装饰器模式的替代方案

6
我发现装饰器模式最令人困惑。请参考《Head First设计模式》中提供的示例。
要获得一杯加入双倍摩卡和奶泡的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();

在我看来,它们两者是相同的。如果是这样的话,使用装饰器模式有什么优点呢?

有什么想法吗?

3个回答

15

不,它们不一样。

《Head First》的示例中添加了摩卡、奶油和烘焙的一种饮料。您的示例有三种饮料。
请参阅此《Head First》代码。它在相同的饮料实例上工作。

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

你的代码创建了三种饮料(这意味着有人单独点了三种东西)。 在现实生活中,我想不是饮料。饮料本身只有一种,上面加上各种口味。

装饰器的目的是为了装饰。 .NET有TextWriter和IndentedTextWriter(我想),它们基本上接收您的普通文本并对其进行缩进。从某种意义上讲,这类似于Unix管道。

输入->微调->微调后的输入->进一步微调->进一步微调后的输入。 当前操作的输出成为下一个操作的输入。

我不知道我是否解释清楚了。


看一下这个《Head First》代码。它在相同的饮料实例上运行。但它并不是相同的实例。每个后续的装饰器都采用前一个装饰器的实例。它是同一个变量,但被分配了不同的实例。 - CodingYoshi
@CodingYoshi:是的,我的意思是使用了同一变量,并且新实例包装了现有实例以创建新的饮料。谢谢 :) - shahkalpesh
@EdwardOlamisan:OP展示了一种可能的替代装饰器的方法,而不是寻求其他选择。 - shahkalpesh

10

装饰器模式的整个意义在于通过对象组合而非继承来增加职责。继承是静态的,对象组合是动态的和更为灵活的。修饰的可能性是无限的。同时,在运行时取消装饰也是可能的。


1
能否给出更多关于“去装饰化”(un-decorating)的想法? - Navaneeth K N

1

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

在你的例子中,你有一个名为order的对象,它接收饮料,在Head First的例子中,他们只是用配料装饰饮料,这导致了以下主要问题。

在你的订单代码中,你可以放置多个饮料,如果是这样,并且你放置了多个配料,那么每个饮料应该搭配哪个配料呢?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接