上一篇说了适配器模式,这一篇接着学习装饰者模式。
想要扩展功能,装饰者提供了有别于继承的另外一种选择。
装饰者模式主要实现的功能是动态的给某一个类添加一些额外的功能,它是一个锦上添花者。想要扩展功能,装饰者提供了有别于继承的另外一种选择。设计模式的原则是多用组合少用继承。
uml 图:
特点:
1. 装饰者和被装饰者拥有相同的超类型(可能是抽象类也可能是接口)
2. 可以用多个装饰类来包装一个对象,装饰类可以包装装饰类或被装饰对象
3. 因为装饰者和被装饰者拥有相同的抽象类型,因此在任何需要原始对象(被包装)的场合,都可以用装饰过的对象来替代它。
4. 装饰者可以在被装饰者的行为之前或之后,加上自己的附加行为,以达到特殊目的
5. 因为对象可以在任何的时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象
案例分析
假如你老婆喜欢化妆,她每天早上照镜子着镜子都化妆,化妆的时候要涂口红,画睫毛,抹香水。老婆化妆的这个过程便是一个典型的装饰者模式,而口红,眼线笔,香水,显然就是装饰品。
首先是爱照镜子的女人:
- class IWomen
- {
- public:
- virtual void lookIntoTheMirror() = 0;
- };
然后老婆是个爱照镜子的喜欢打扮的女人(具体需要装饰对象)
- class Wife : public IWomen
- {
- public:
- void lookIntoTheMirror()
- {
- cout<<"镜子中的老婆 "<<endl;
- }
- };
需要一个化妆的女人(装饰品的抽象基类)
- class DecoratorWomen : public IWomen
- {
- public:
- DecoratorWomen(IWomen* woman)
- :m_women(woman)
- {
- }
- void lookIntoTheMirror()
- {
- m_women->lookIntoTheMirror();
- makeUp();
- }
- virtual void makeUp() = 0; //化妆
- protected:
- IWomen* m_women;
- };
下面是具体3种用于化妆的化妆品: 口红,睫毛膏,香水
- class Lipstick : public DecoratorWomen
- {
- public:
- Lipstick(IWomen* woman):DecoratorWomen(woman){};
- void makeUp()
- {
- cout<<" 有火红的嘴唇!";
- }
- };
- class Mascara : public DecoratorWomen
- {
- public:
- Mascara(IWomen* woman):DecoratorWomen(woman){};
- void makeUp()
- {
- cout<<" 有黑黑的睫毛!";
- }
- };
- class Perfume : public DecoratorWomen
- {
- public:
- Perfume(IWomen* woman):DecoratorWomen(woman){};
- void makeUp()
- {
- cout<<" 有香奈儿的味道!";
- }
- };
- IWomen* myWife = new Wife();
- Lipstick* lips = new Lipstick(myWife);
- Mascara* mas = new Mascara(lips);
- Perfume* per = new Perfume(mas);
- myWife = per;
- myWife->lookIntoTheMirror();
- //释放各种资源...
适配器模式和装饰者模式的区别:
适配器将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增强新的行为和责任;而外观将一群对象包装起来以简化其接口。要注意装饰着模式的两个抽象类,一个是Compent, 还有一个是Decorator。