Java设计模式

JAVA设计模式之单例模式

http://blog.csdn.net/jason0539/article/details/23297037


常用设计模式的应用场景

http://blog.sina.com.cn/s/blog_76d0381f0100x5nz.html


JAVA序列化/反序列化与单例(单例被打破)

http://shift-alt-ctrl.iteye.com/blog/1842040




《大话设计模式》读后感

为什么写程序需要学习设计模式,因为设计模式可以使代码具备4个特性:

  可维护性(修改代码)、可复用性()、可扩展性(加代码)、灵活性

这样,客户的需求一改变,这样就不需要改动太多的代码。



UML类图样例是必须要记住的

  弄清类与类之间有哪些关系,能把各个设计模式的结构图画出来才算是真正地理解了。

wKiom1ZHSPewnEyVAAK3jIer_7s429.png


1.简单工厂模式-代码无错就是优?(Factory)

 wKioL1ZHSveAC-baAADWeWCVwoM848.png

 **简单工厂模式只是简简单单地创建对象**

 需求:写一个计算器程序

 1-1:业务的封装

    让业务逻辑与界面逻辑分离开,让它们的耦合度下降。只有分离开,才易于维护和扩展。

  利用“万物皆对象”的思想,来构建类。

  》》运算类

//运算类
public abstract class Operation {
	//运算类会哪些属性,操作的两个数。
	private double a,b;

	public double getA() {
		return a;
	}

	public void setA(double a) {
		this.a = a;
	}

	public double getB() {
		return b;
	}

	public void setB(double b) {
		this.b = b;
	}
	
	//得到运算结果,由于不确定运算到底是加、减、乘、除中的哪一个,所以要抽象方法。
	//既然有抽象方法,那么类也必须是抽象的。
	public abstract double getResult();
}

 》》然后分别定义加、减、乘、除4个子类

//加法运算类
public class AddOperation extends Operation {
	public double getResult() {
		return a + b;
	}
}
//减法运算类
public class SubOperation extends Operation {
	public double getResult() {
		return a - b;
	}
}
//乘法运算类
public class MulOperation extends Operation {
	public double getResult() {
		return a * b;
	}
}
//除法运算类
public class DivOperation extends Operation {
	public double getResult() {
		if(b == 0){
			throw new RuntimeException("除数不能为0");
		}
		return a / b;
	}
}

  》》利用简单工厂实例化类

//利用工厂设计模式来实例化类
public class OperationFactory {
	public static Operation create(String operate){
		Operation oper = null;
		switch(operate)
		{
		case "+":
		  oper = new AddOperation();
		  break;
		case "-":
		  oper = new SubOperation();
		  break;
		case "*":
		  oper = new MulOperation();
		  break;
		case "/":
		  oper = new DivOperation();
		  break;
		}
		return oper;
	}
}

  测试:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		Operation oper = OperationFactory.create("/");
		oper.setA(8);
		oper.setB(0);
		System.out.println(oper.getResult());
}

 UML类图:

 》》聚合、合成、依赖关系,基数

 

 作者说了这样几句话:编程是一门技术,更是一门艺术,不能只满足于写完代码运行结果正确就完

 事,时常考虑如何让代码更加简练,更加容易维护,更加容易扩展和复用,这样才能写出优雅的代 

 码。


2.策略模式-商场促销(Strategy)

 wKiom1ZHShKgA9coAAH497biwpk176.png

 **面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相

   同的属性和功能的对象的抽象集合才是类**  

 需求:正常情况下,买多少钱的商品付多少钱;搞活动,可能会打折,也有可能满多少钱返回

    一定数目的钱。

 构建类

  》》现金收费抽象父类

//现金收费抽象父类
public abstract class Cash {
	//怎么收费不确定,抽象化。
	public abstract double acceptCash(double money);
}

  》》正常收费子类

//正常收费子类
public class NormalCash extends Cash{
	//买多少钱收多少钱
	public double acceptCash(double money) {
		return 0;
	}
}

  》》打折收费子类

//打折抽象类
public class DiscountCash extends Cash {
	private double discount = 1;

	// 在初始化的时候传入打折率
	public DiscountCash(double discount) {
		this.discount = discount;
	}

	public double acceptCash(double money) {
		return money * discount;
	}
	
	public double getDiscount() {
		return discount;
	}

	public void setDiscount(double discount) {
		this.discount = discount;
	}
}

  》》返利费子类 

//返利收费子类
public class ReturnCash extends Cash {
	private double base; // 满多少钱就返利的基数
	private double ret; // 返多少钱

	// 通过构造方法传递base和ret
	public ReturnCash(double base, double ret) {
		this.base = base;
		this.ret = ret;
	}

	public double acceptCash(double money) {
		double result = money;
		if(result > base){
			result -= Math.floor(result / base)* ret;
		}		
		return result;
	}
	
	public double getBase() {
		return base;
	}

	public void setBase(double base) {
		this.base = base;
	}

	public double getRet() {
		return ret;
	}

	public void setRet(double ret) {
		this.ret = ret;
	}

}

  》》简单工厂实例化类及调用

   实例化 

public class CashFactory {
	public static Cash create(int position){
		Cash cash = null;
		switch(position){
		case 0:
			cash = new NormalCash();
			break;
		case 1:
			cash  = new DiscountCash(0.5);
			break;
		case 2:
			cash = new ReturnCash(300,50);
			break;
		}
		return cash;
	}
}

    调用

double cash = CashFactory.create(2).acceptCash(600);
System.out.println(cash);

   》》策略模式实例化类及调用 

//策略模式
public class CashContext {
	//维护对Cash基类的一个引用
	private Cash cash;
	
	//在外部switch条件
	public CashContext(Cash cash){
		this.cash = cash;
	}
	
	public double getResult(double money){
		return cash.acceptCash(money);
	}
}
double cash = new CashContext(new DiscountCash(0.5)).getResult(100);
System.out.println(cash);

   》》策略模式与简单工厂模式相结合

//策略模式与简单工厂模式结合
public class CashContextF {
	private Cash cash = null;
	
	//在内部switch
	public CashContextF(int position){
		switch(position){
		case 0:
			cash = new NormalCash();
			break;
		case 1:
			cash = new DiscountCash(0.5);
			break;
		case 2:
			cash = new ReturnCash(300,50);
			break;
		}
	}
	
	public double getResult(double money){
		return cash.acceptCash(money);
	}
}

   简单工厂模式与策略模式的区别:虽然代码上能分清两者的区别,但是它们的本质区别目前不太

   想得明白,求路人指点。。。

   封装系列的算法


3.单一职责原则

   分离类的职责  

   就一个类而言,应该仅有一个引起它变化的原因。

    如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会消弱

      或者抑制这个类完成其它职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设

      计遭受到意想不到的破坏。

   

   比如俄罗斯方块游戏,设计的时候应该将界面逻辑与游戏逻辑相分离,游戏逻辑实则是数组的

    变化,而界面逻辑则是根据数组来进行绘制。


    软件设计真正要做的许多内容,就是发现职责并把那些职责相分离。  

    

4.开发封闭原则(OCP) 

  软件实体(类、模块、方法等等)应该可以扩展,但是不可修改。

  对于扩展是开放的,对于更改是封闭的。

  面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。wKiom1ZHIdbT3neuAAFGEdW1Hnw427.png  例1:比如弹性工作制度,业绩(任务目标量)是必须要完成的,是不可修改的,而时间是可以扩展

     的。因为有的人可能会有特殊原因。

  wKiom1ZHJjiCwnKkAADkwSmY2Ss452.png 

  wKiom1ZHKEvjF5ZCAAESrWJAu-8581.png   

    wKiom1ZHKVzStKIHAAIky5wgkYA631.png

5.依赖倒转原则

  抽象不依赖细节,但细节依赖抽象。

  针对接口编程,不要针对实现编程。

  wKioL1ZHMmmCeNsrAACkpHpsZwY268.png  

  wKiom1ZHMzCxoXFTAAERSBfNmNQ157.png  

  依赖倒转原则其实就是谁也不要依靠谁,除了约定的接口,大家都可以灵活自如。


  里氏代换原则(好像是多态的意思?)

  wKioL1ZHNZCTpbPGAADPPJf9EPA890.png 

  

  wKiom1ZHSAuy5yejAACAQSzdOlg625.png

  

6.装饰模式(Decorator)

 wKioL1ZHOQyACYmeAACLUgdvw-s722.png

  注意装饰与继承的区别

  关于装饰设计模式,我有几点疑问:

  1)为什么Decorator类一定要继承Component呢,通过set就已经获得了Component对象,又何必再

    继承它呢?

    我的想法:所谓的装饰,就是增强接口或抽象类的方法职责,所以要实现接口或抽象里的方

        法。 

  wKiom1ZHTA3T2I2VAAK_mxjZjdk698.png 

  用代码来说明问题:

 

//接口,为对象动态地添加职责。
public abstract interface Component {
	public abstract void operate();
}
//定义了一个具体的对象,实现接口的职责
public class ConcreteComponent implements Component {
	public void operate() {
		System.out.println("具体对象的操作");
	}
}
//包装类
public  class Decorator implements Component {
	protected Component component;
	
	public void setComponent(Component component) {
		this.component = component;
	}

	public void operate() {
		if (component != null) {
			component.operate();
		}
	}
}
//二级包装类A
public class DecoratorA extends Decorator {
	// 本类独有的属性
	private String addedState;

	public void operate() {
		super.operate();
		addedState = "New State";
		System.out.println("具体装饰对象A的操作");
	}
}
//二级包装类B
public class DecoratorB extends Decorator {

	public void operate() {
		super.operate();
		addBehavior();
		System.out.println("具体装饰对象B的操作");
	}

	// 本类独有的方法
	public void addBehavior() {
		
	}
}

客户端调用:

public static void main(String[] args) {
		ConcreteComponent component = new ConcreteComponent();
		DecoratorA decoratorA = new DecoratorA();
		DecoratorB decoratorB = new DecoratorB();
		decoratorA.setComponent(component);
		decoratorB.setComponent(decoratorA);
		decoratorB.operate();
}

输出:

wKioL1ZHT0HysOXNAAAZ6Tzr9tk884.png 

wKioL1ZHVHbwOGSJAAZHthLp6dU209.png

 wKiom1ZIII-SPc90AAEv_aV3sac130.png


7.代理模式(Proxy)  

  Proxy代理模式之应用 http://blog.csdn.net/liujiahan629629/article/details/19428485     

  Realm数据库就用到了这种设计模式 

 wKioL1ZIJzGgDyHpAADzI-5AG8Y198.png    

  wKiom1ZIJ2-ypWDvAAByCPtvpws820.png

  wKiom1ZIKO2gzPRBAAIkDdm5At8209.png 

  代码实现

 

//Subject类,定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以
  使用Proxy。
public interface Subject {
	public void request();
}
//实体类RealSubject,定义Proxy所代表的真实实体。
public class RealSubject implements Subject {
	public void request() {
		System.out.println("真实的请求");
	}
}
//代理类Proxy,保存一个引用使得代理可以访问实体。
public class Proxy implements Subject {
	RealSubject realSubject;
	public void request() {
		if(realSubject == null){
			realSubject = new RealSubject();
		}
		realSubject.request();
	}
}

客户端调用:

public static void main(String[] args) {
		Proxy proxy = new Proxy();
		proxy.request();
}

   代理模式的代码很简单,但是应用场景是什么??

8.工厂方法模式

  wKiom1ZUa12R7CYWAAJjD8Y1uQs356.png


  wKioL1ZUbOmyMUfgAADCvrSdGdw749.png  



。。。

15.抽象工厂模式

  wKioL1ZUY7igpVuOAADlfwlLTs4172.png    

   

   wKiom1ZUY4DTmYzlAAI9oitMa0c093.png


    

你可能感兴趣的:(android经验)