本人近来正在学习研读《head first 设计模式》,有读了知名的博文《最牛B的程序员训练方法》,故想写篇博文,总结一下自己学习设计模式的体会和感悟,不好之处,请多多包涵,如诺指出其中的错误,本人不胜感激。
设计模式的本源是java开发中面向对象的各种原则,例如依赖倒置原则(DIP),开闭原则(OCP),依赖接口编程(programming to interface)等。但其根本的目的是信息隐藏,和模块化。然后最终的追求便是程序的效用、坚固、和审美。这是设计模式的滥觞所在。
使用设计模式有什么好处呢?当你在和其他程序员交流时,你使用设计模式的共享语句,其实“不只是”和他人共享“行话”而已。理由如下:
一:共享模式的词汇“威力强大”。当你使用模式名称和其他开发人员或者开发团队交流时,你们之间交流的不只是模式名称,而是整套模式背后所象征的质量、特性、和约束。
二:模式能让你使用更少的词做更充分的交流。这对于“少言”的程序员可是一大幸事啊。
三:设计模式可以让你更专注于“设计圈子”。这样便不会过早的设计底层细节实现的思考。(三条内容摘自《head first 设计模式》)
《head first 设计模式》中以星巴克咖啡店的自动售货系统为例进行情景设计:顾客购买咖啡时,可以按照其要求在咖啡中加入不同的各种调料,例如:摩卡,豆浆或者覆盖奶泡。系统会根据所加入的调料收取不同的费用。所以不同的咖啡和调料间的自由组合便造成了大量的对象,这会给维护带来极大的麻烦。
由此出发,我们使用装饰者模式,即动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。其中的细节是:
一:装饰者和被装饰对象有相同的超类型。
二:可以使用一个或多个装饰者包装一个对象。
三:任何需要原始对象(被包装)的场合,可以使用装饰者对象替代它。
四:装饰者可以在所委托的被装饰者的行为之前或之后,加上自己的行为,已到达特定目的。
五:装饰者可以包装装饰者,这时的被包装的装饰者一定已经包装了一个被装饰者。
总体而言,装饰者是避免在类似情节时使用简单继承时产生的大量类对象的维护噩梦而形成的。
下面是一个例子:
这是装饰者的超类:
public abstract class 装饰者抽象类 extends 咖啡抽象类{ public abstract String 咖啡名称(); }
这是咖啡的超类:
public abstract class 咖啡抽象类 { String cfName = "not Name"; public String 咖啡名称(){ return cfName; } public abstract double 价格(); }
下边是两个具体装饰者:
public class 装饰A extends 装饰者抽象类{ 咖啡抽象类 cf; public 装饰A(咖啡抽象类 cf){ this.cf = cf; } @Override public String 咖啡名称() { return cf.咖啡名称() + " 装饰A"; } @Override public double 价格() { return cf.价格() + 123.01; } }
public class 装饰B extends 装饰者抽象类{ 咖啡抽象类 cf; public 装饰B(咖啡抽象类 cf){ this.cf = cf; } @Override public String 咖啡名称() { return cf.咖啡名称() + " 装饰B"; } @Override public double 价格() { return cf.价格() + 165.01; } }
这是一个咖啡类:
public class 咖啡种类A extends 咖啡抽象类{ public 咖啡种类A(){ cfName = "咖啡种类A"; } @Override public double 价格() { return 10.11; } }
下面是一个demo:
public class 测试 { public static void main(String[] args) { 咖啡抽象类 c = new 装饰A(new 咖啡种类A()); System.out.println(c.咖啡名称()); System.out.println(c.价格()); } }
内容便是那么多了,而且多是书上所得。但我自己写给一个例子,感觉咖啡的超类可以不是抽象类,而且在new出相应对象时可以使用另一个模式--工厂模式来实现根据接口编程的原则。