JAVA设计模式之单例模式
http://blog.csdn.net/jason0539/article/details/23297037
常用设计模式的应用场景
http://blog.sina.com.cn/s/blog_76d0381f0100x5nz.html
http://shift-alt-ctrl.iteye.com/blog/1842040
《大话设计模式》读后感
为什么写程序需要学习设计模式,因为设计模式可以使代码具备4个特性:
可维护性(修改代码)、可复用性()、可扩展性(加代码)、灵活性
这样,客户的需求一改变,这样就不需要改动太多的代码。
UML类图样例是必须要记住的
弄清类与类之间有哪些关系,能把各个设计模式的结构图画出来才算是真正地理解了。
1.简单工厂模式-代码无错就是优?(Factory)
**简单工厂模式只是简简单单地创建对象**
需求:写一个计算器程序
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)
**面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相
同的属性和功能的对象的抽象集合才是类**
需求:正常情况下,买多少钱的商品付多少钱;搞活动,可能会打折,也有可能满多少钱返回
一定数目的钱。
构建类
》》现金收费抽象父类
//现金收费抽象父类 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)
软件实体(类、模块、方法等等)应该可以扩展,但是不可修改。
对于扩展是开放的,对于更改是封闭的。
面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。 例1:比如弹性工作制度,业绩(任务目标量)是必须要完成的,是不可修改的,而时间是可以扩展
的。因为有的人可能会有特殊原因。
5.依赖倒转原则
抽象不依赖细节,但细节依赖抽象。
针对接口编程,不要针对实现编程。
依赖倒转原则其实就是谁也不要依靠谁,除了约定的接口,大家都可以灵活自如。
里氏代换原则(好像是多态的意思?)
6.装饰模式(Decorator)
注意装饰与继承的区别
关于装饰设计模式,我有几点疑问:
1)为什么Decorator类一定要继承Component呢,通过set就已经获得了Component对象,又何必再
继承它呢?
我的想法:所谓的装饰,就是增强接口或抽象类的方法职责,所以要实现接口或抽象里的方
法。
用代码来说明问题:
//接口,为对象动态地添加职责。 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(); }
输出:
7.代理模式(Proxy)
Proxy代理模式之应用 http://blog.csdn.net/liujiahan629629/article/details/19428485
Realm数据库就用到了这种设计模式
代码实现
//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.工厂方法模式
。。。
15.抽象工厂模式