2009-08-08 46 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

我想你实际上是代表完全不同的东西。

在你的榜样,你有收到饮料对象调用顺序,并在头第一个例子它们只是装饰用的配料的饮料,这将导致以下主要问题。

在您的订单代码中,您可以放置​​多种饮料,如果是这样,并且您放置了多个顶部,每种饮料都配什么?