对于Decorator设计模式,GoF明确指出:
使用装饰器,可以在运行时添加和删除职责 只需将它们连接和拆卸即可。
我正在尝试用C ++构建一个框架代码,我可以很容易地看到这个模式如何为未修饰的对象添加职责。
我的问题是如何删除特定的责任。删除最后包装的责任可以轻松完成。但我是否也可以删除之间添加的责任。
以下是我的示例代码:
class Icecream { //Component
public :
virtual void addToppings() = 0 ;
virtual Icecream *getUndecorated() = 0 ;
} ;
class PlainIcecream : public Icecream { //Concrete Component
public :
void addToppings() { cout<<"I am just plain icecream, you may add more flavors\n" ; }
Icecream * getUndecorated() {return this ; }
} ;
class Topping : public Icecream { //Decorator
protected :
Icecream *icecream ;
public :
Topping(Icecream *i) : icecream(i) {}
void addToppings() { icecream->addToppings() ; }
} ;
class PeanutToppings : public Topping { //Concrete Component A
public :
PeanutToppings(Icecream *i) : Topping(i) {}
void addToppings() {
Topping::addToppings() ;
cout<<"Adding peanut toppings for great taste\n" ;
}
Icecream * getUndecorated() {return icecream ; }
} ;
class CandyToppings : public Topping { //Concrete Component A
public :
CandyToppings(Icecream *i) : Topping(i) {}
void addToppings() {
Topping::addToppings() ;
cout<<"Adding candy toppings for yummy flavour\n" ;
}
Icecream * getUndecorated() {return icecream ; }
} ;
main() {
Icecream *icecream_with_candy_and_peanuts = new CandyToppings(new PeanutToppings(new PlainIcecream)) ;
icecream_with_candy_and_peanuts->addToppings() ;
cout<<"_________________________________________________\n" ;
Icecream *icecream_with_only_peanuts = icecream_with_candy_and_peanuts->getUndecorated() ;
icecream_with_only_peanuts->addToppings() ;
cout<<"_________________________________________________\n" ;
Icecream *icecream_plain = icecream_with_only_peanuts->getUndecorated() ;
icecream_plain->addToppings() ;
}
现在我想知道是否有可能只有来自icecream_with_candy_and_peanuts
的糖果的冰淇淋。请不要考虑我为什么要这样做。我只是想了解这个词
分离职责
如GoF所述。
答案 0 :(得分:2)
可以轻松删除最后包装的责任
无需单独的getUndecorated
方法。这不是标准 Decorator 模式定义的一部分。
现在我想知道是否可以制作一个冰淇淋,只有来自icecream_with_candy_and_peanuts的糖果顶部
是的,你可以。当涉及到装饰器模式时,附加或分离职责之间没有太大区别。要分离责任,您只需要重新创建组件:
//attaching responsibilities
Icecream *icecream = new new PlainIcecream();
*icecream = new PeanutToppings(icecream);//wrap around with new respnsibility
*icecream = new CandyToppings(icecream);//wrap around with new responsiblity
//detaching responsibilities
*icecream = new CandyToppings(new PlainIcecream());
注意我在两种情况下如何使用*icecream
。您可以通过限制到单个界面(即IceCream
)来附加和分离职责。这就是 Decorator 模式背后的想法。
也就是说,使用HashMap
(其中键是顶部名称)实现的 Composite 模式在您希望能够任意添加或者任意添加的情况下是更好的选择。从现有实例中删除职责。
额外提示:装饰器模式中的装饰器理想情况下不应该是可实例化的(在您的情况下为Toppings
)。将Toppings
重命名为ToppingsDecorator
也会有所帮助。 (我知道这不是你要问的直接问题。这纯粹是为了其他读者的利益)