讀《Head First Design Patterns》(第三章 裝飾者模式)
第3章講了裝飾者模式,書中列舉了一個星巴克咖啡的例子,比較淺顯的闡述了這種模式。我將力求提取其中實際的部分,并消化之,作此記錄,以供日后參考。 先從一條金科玉律(Open-Closed Principle)開始吧:
Classes should be open for extension,but closed for modification
我的理解是類的設計應該做到有新的變化易于擴展但對原有的代碼不能有修改。
這當然好啦,只是聽起來似乎挺矛盾的,也不知道該怎么實現。但的確有相應的OO技巧,等著瞧吧。先看一下書里有段話值得我們注意,特別象我這種不懂OO的OO崇拜者:
applying the Open-Closed Principle EVERYWHERE is wasteful, unnecessary, and can lead to complex, hard to understand code.
Following the Open-Closed Principle usually introduces new levels of abstraction,which adds complexity to our code.You want to concentrate on those areas that are most likely to change in your designs and apply the principles there.
好了,現在我們來正視觀察者模式是如何實現這個原則的:
裝飾者模式定義:The Decorator Pattern attaches additional
responsibilities to an object dynamically.Decorators provide a flexible alternative to subclassing for extending functionality.
看看書中的例子:
![]()
代碼如下:
Beverage.java
package com.Decorator.www;
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
public abstract String getDescription();
}
DarkRoast.java
package com.Decorator.www;
public class DarkRoast extends Beverage {
public DarkRoast(){
super.description = "description";
}
public double cost() {
// TODO 自動生成方法存根
return .78;
}
}
Mocha.java
package com.Decorator.www;
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
// TODO 自動生成方法存根
return beverage.getDescription() + ", Mocha";
}
public double cost() {
// TODO 自動生成方法存根
return .20 + beverage.cost();
}
}
StarbuzzCoffee.java
package com.Decorator.www;
public class StarbuzzCoffee {
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自動生成方法存根
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription()
+ "$" + beverage.cost());
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription()
+ "$" + beverage2.cost());
Beverage beverage3 = new HouseBlend();
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
System.out.println(beverage3.getDescription()
+ "$" + beverage3.cost());
}
}
其他略
沒錯,就是包裝者模式,需要添加一個新功能就包一層,同時需要另外一個新功能就再包一層。基本的原理是這樣的:如果需要對A類裝飾,就從A類的父類繼承一個裝飾者虛擬類(當然也可以用接口,可能接口更理想),然后從這個虛擬類(接口)實現具體的裝飾者類,在具體裝飾者類中從構造函數引入被包裝者對象,然后對該對象添加額外的功能。(The decorator adds its own behavior either before and/or after delegating to the object itdecorates to do the rest of the job.)這樣很容易就擴展了被包裝類的功能,也沒有修改被包裝類和他的父類。
裝飾者模式很好的彌補了繼承的不足之處,可以真正的做到Open-Closed Principle原則,不過也有不足的一面:
1.sometimes add a lot of small classes to a design and this occasionally results in a design that’s less than straightforward for others to understand.
2.you can usually insert decorators transparently and the client never has to knowit’s dealing with a decorator
關于這些我也只是字面理解,在以后的實際應用中慢慢體會吧!![]()

浙公網安備 33010602011771號