Posted on 2007-11-28 20:31
flustar 閱讀(1188)
評論(0) 編輯 收藏 所屬分類:
Design Patterns
《設計模式》一書對Decorator是這樣描述的:
動態地給一個對象添加一些額外的職責。就增加功能來說,Decorator模式比生成子類更為靈活。
也就是說:動態地給對象添加一些額外的功能。它的工作原理是:創建一個始于Decorator對象(負責新功能的對象)終止于原對象的一個對象的“鏈”。例如,我們要為超市的收銀臺設計一個打印票據的程序,有的需要打印票據的頭信息,有的需要打印票據的頁腳信息,有的只需要打印票據的內容。如果針對每一種情況都修改一次程序,勢必會很麻煩。這時我們可以考慮使用Decorator模式。其結構類圖如下:

代碼如下:
abstract class Component{
abstract public void printTicket();
}
class SalesTicket extends Component{
public void printTicket() {
System.out.println("打印出salesTicket的內容");
}
}
abstract class TicketDecorator extends Component{
private Component myTrailer;
public TicketDecorator(Component myComponent){
myTrailer=myComponent;
}
public void callTrailer(){
if(myTrailer!=null)
myTrailer.printTicket();
}
}
class Header extends TicketDecorator{
public Header(Component myComponent){
super(myComponent);
}
public void printTicket(){
System.out.println("打印salesTicket的頭信息");
super.callTrailer();
}
}
class Footer extends TicketDecorator{
public Footer(Component myComponent){
super(myComponent);
}
public void printTicket(){
super.callTrailer();
System.out.println("打印salesTicket的頁腳信息");
}
}
public class Client {
public static void main(String[] args) {
System.out.println("====================================");
new Header(new Footer(new SalesTicket())).printTicket();
System.out.println("====================================");
new Footer(new Header(new SalesTicket())).printTicket();
System.out.println("====================================");
}
}
輸出結果如下:
====================================
打印salesTicket的頭信息
打印出salesTicket的內容
打印salesTicket的頁腳信息
====================================
打印salesTicket的頭信息
打印出salesTicket的內容
打印salesTicket的頁腳信息
====================================
從這個例子我們可以看出,Decorator模式把問題分為兩部分:
1) 如何實現提供新功能的對象。
2) 如何為每種特殊情況組織對象。
這樣能夠將Decorator對象的實現與決定如何使用Decorator的對象分離開來,從而提高了內聚性,因為每個Decorator對象只用關心自己添加的功能,無需關心自己是如何被加入到對象鏈中。還可以任意地重排Decorator的順序,無需改變其任何代碼。
小結:Decorator模式的適用場合是,各種可選的功能在另一個肯定要執行的功能之前或之后執行。