2009-08-08 81 views
4

我覺得裝飾圖案最令人困惑。請考慮「首先設計模式書」中提供的示例。裝飾圖案的替代品

alt text

因此,要獲得一個在DarkRoast雙摩卡和鞭子,你必須寫

Beverage beverage2 = new DarkRoast(); 
beverage2 = new Mocha(beverage2);          
beverage2 = new Mocha(beverage2);          
beverage2 = new Whip(beverage2); 

我覺得這是不必要的。這裏是我的實現,

interface Beverage 
{ 
    int Cost(); 
} 

class DarkRoast : Beverage 
{ 
    /* .... */ 
} 

class Mocha : Beverage 
{ 
    /* .... */ 
} 

class Whip : Beverage 
{ 
    /* .... */ 
} 

// here is the changed part 
class Order 
{ 
    List<Beverage> beverages = new List<Beverage> beverages(); 
    public void AddItem(Beverage b) 
    { 
     beverages.Add(b); 
    } 

    public int Cost() 
    { 
     int cost; 
     foreach(Beverage b in beverages) 
      cost += b.Cost(); 
    } 
} 

// use it like 
Order order = new Order(); 
order.AddItem(new DarkRoast()); 
order.AddItem(new Mocha()); 
order.AddItem(new Mocha()); 
order.AddItem(new Whip()); 
int cost = order.Cost(); 

IMO,兩者都是相同的。如果是的話,這裏使用裝飾器模式的優點是什麼?

有什麼想法?

回答

16

不,它們不一樣。

頭第一個例子具有1種飲料與摩卡,鞭,烤加入。你的例子有3種飲料。
看到這個頭第一個代碼。它適用於飲料的同一實例

beverage2 = new Mocha(beverage2);          
beverage2 = new DarkRoast(beverage2);          
beverage2 = new Whip(beverage2); 

你的代碼創建3種飲料(這意味着有人單獨訂購3樣東西)。
在現實生活中,我想這不是飲料。該飲料是在其上添加一種&香料。

裝飾的目的是 - 裝飾。 .Net有TextWriter和IndentedTextWriter(我猜),它基本上採用了你的正常文本並對其應用縮進。如果你想到它,它與unix管道類似。

輸入 - >調整 - >調整了輸入 - >進一步的調整 - >進一步微調的輸入。
當前操作的輸出成爲下一個操作的輸入。

我不知道我是否解釋得好。

+0

謝謝。這解釋得很好。 – 2009-08-08 18:37:57

+0

你解釋得很好。 – 2010-09-28 20:44:28

8

裝飾模式的整點是經由對象組合物,而不是繼承來添加的責任。繼承是靜態的,obj。構圖動態更靈活。裝飾的可能性是無止境的。在運行時也可以取消裝飾對象。

+0

你能否提供更多有關未裝飾的想法? – 2009-08-08 18:41:38

1

我想你實際上是代表完全不同的東西。

在你的榜樣,你有收到飲料對象調用順序,並在頭第一個例子它們只是裝飾用的配料的飲料,這將導致以下主要問題。

在您的訂單代碼中,您可以放置​​多種飲料,如果是這樣,並且您放置了多個頂部,每種飲料都配什麼?