設計模式之Decorator在餐館中的應用

YaSir發表於2002-11-25
Decorator定義:(動態給一個物件新增一些額外的職責,就象在牆上刷油漆.使用Decorator模式相比用生成子類方式達到功能的擴充顯得更為靈活.
為什麼使用Decorator?
我們通常可以使用繼承來實現功能的擴充,如果這些需要擴充的功能的種類很繁多,那麼勢必生成很多子類,增加系統的複雜性,同時,使用繼承實現功能擴充,我們必須可預見這些擴充功能,這些功能是編譯時就確定了,是靜態的。
使用Decorator的理由是:這些功能需要由使用者動態決定加入的方式和時機.Decorator提供了"即插即用"的方法,在執行期間決定何時增加何種功能。摘自(banq)

以到餐館去吃飯為例:
eatFood()是我們主要做的事,可是在此之前,要點菜askFood(),吃完之後要payMoney(),有時還要給服務員小費giveFee();
因此,除了eatFood之外的方法是"即插即用"的方法,在執行期間可以不給小費等等。
第一步>定義一介面:
public interface EatIF {
public void eatFood();
}
第二步>定義一decoratee(被刷油漆者)
public class EatSupper implements EatIF {
public EatSupper() { }
public String eatFood() {
System.out.println("一般地吃飯,是一個被刷油漆者。。。");
return "";
}
}
第三步>定義油漆工:
public class EatDecorator implements EatIF {
private EatIF eat;
private ArrayList additiveMove=new ArrayList();//吃飯前後的一些動作放在這裡
public EatDecorator(EatIF eatSupper) {
//EatDecorator往eatFood()新增其它方法,“刷油漆”
eat=eatSupper;//吃晚飯
additiveMove.add("用公款訂一桌子,地點在香格里拉。。。");
additiveMove.add("每位女服務員給小費50日元");
}
public void eatFood() {
askFood();
eat.eatFood();
giveFee ();
}
public void askFood (){
System.out.println("吃飯前的第一步"+additiveMove.get(0).toString());
}
public void giveFee (){
System.out.println("吃飯的最後一步"+additiveMove.get(1).toString());
}
}
第四步>呼叫:
public class TestDecorator {
public static void main(String[] args) {
EatIF eatSupper=new EatSupper();
EatIF eatDecorator=new EatDecorator(eatSupper);
eatDecorator.eatFood();
}
}

相關文章