对于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中提到的。
发布于 2017-01-27 09:48:34
移除最后包装的责任可以很容易地完成。
不需要有单独的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)来附加和分离职责。这就是装饰模式背后的想法。
也就是说,使用HashMap (其中键是顶部名称)实现的复合模式是一个更好的选择,在这样的场景中,您希望能够任意地从现有实例中添加或删除责任。
额外提示:理想情况下,装饰器模式中的装饰器不应该是可实例化的(在您的例子中是Toppings)。将Toppings重命名为ToppingsDecorator也会有所帮助。(我知道这不是你要问的直接问题。这纯粹是为了其他读者的利益)
https://stackoverflow.com/questions/41873464
复制相似问题