我发现装饰模式最令人困惑。请考虑“Head first design patterns book”中提供的示例。
所以要用双摩卡和鞭子来获得 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,两者都是一样的。如果是,那么在这里使用装饰模式有什么好处?
有什么想法吗?
答案 0 :(得分:16)
不,他们不一样。
头部第一个例子有1杯饮料,摩卡,鞭子,烤肉添加。你的例子有3种饮料 请参阅头首代码。它适用于饮料的同一个实例
beverage2 = new Mocha(beverage2);
beverage2 = new DarkRoast(beverage2);
beverage2 = new Whip(beverage2);
您的代码会创建3种饮料(这意味着有人分别订购了3种饮料) 在现实生活中,我想这不是饮料。饮料是一个&amp;在它上面添加了味道。
装饰者的目的是 - 装饰。 .Net有TextWriter和IndentedTextWriter(我猜),它基本上采用你的普通文本并对其应用缩进。如果你想到它,它在某种程度上类似于unix管道。
输入 - &gt;调整 - &gt;调整输入 - &gt;进一步调整 - &gt;进一步调整输入。
当前操作的输出变为下一操作的输入。
我不知道我是否解释得很好。
答案 1 :(得分:8)
Decorator模式的重点是通过对象组合而不是继承来添加职责。 obj,继承是静态的。构图是动态的,更灵活。装饰的可能性是无穷无尽的。也可以在运行时解除对象的装饰。
答案 2 :(得分:1)
我认为你实际上代表的是完全不同的东西。
在您的示例中,您有一个接收饮料的对象呼叫订单,而在头部的第一个示例中,他们只是用浇头装饰饮料,这会导致以下主要问题。
在您的订购代码中,您可以放置多种饮料,如果是这样,并且您放置了多个顶部,每种饮料的打顶量是多少?