大多数人都知道装饰器模式的披萨/咖啡例子。
Pizza* pizza1 = BigPizzaDecorator(MushromDecorator(SimplePizza()));
Pizza* pizza2 = MushromDecorator(BigPizzaDecorator(SimplePizza()));
这两个对象表现方式相似,但并非完全相同,特别是在存在非交换操作的情况下,例如:
BigPizzaDecorator::price() { return 10 + PizzaDecorator::price(); } // this is commutative
BigPizzaDecorator::name() { return "big " + PizzaDecorator::name(); } // this is not commutative
因此,pizza1
和pizza2
的价格相同,但名称不同,例如第一个应该是"大蘑菇披萨"
,第二个应该是"蘑菇大披萨"
。第一个英文正确(可能更好的说法是"带蘑菇的大披萨",但这并不是很重要)。
书籍“Head First”以Cofee示例指出了这个问题:
当您需要查看装饰器链中的多个层次时,您开始将装饰器推向其真正意图之外。
尽管如此,这种事情是可能的。想象一个CondimentPrettyPrint装饰器,可以解析最终描述,并将“Mocha,Whip,Mocha”打印为“Whip,Double Mocha”。
怎么做才是最好的方法? (operator<
?)