设计模式之装饰模式

本文详细介绍了装饰模式的概念及其在C++中的应用。通过实例演示了如何动态地给对象添加职责,对比了装饰模式与子类扩展功能的区别。同时,强调了装饰模式在保持核心职责与装饰功能分离方面的优势。

1、动态地给一个对象添加一些额外的职责,就增加工能来说,装饰模式比生成子类更为灵活。

Component是定义一个对象接口,可以这些对象动态添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。

Decorator装饰抽象类,继承了Component,从外类来扩展Component类的功能,但对于Component来说,是无需知道Decorator存在的。至于ConcreteDecorator就是具体的装饰对象起到给Component添加职责的功能。

UML图如下:



2、装饰模式是利用SetComponent来对对象进行包装的,这样每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。

如果只有一个ConcreteComponent类而没有抽象的Compnent类,那么Decorator类可以是ConcreteComponent的一个子类。同样道理,如果只有一个ConcreteDecorator类那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConreteDecorator的责任合并成为一个类。


3、装饰模式是为已有功能动态地添加更多功能的一种方式,当系统需要新的功能的时候,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责或主要行为。

在主类中加入新的字段,新的方法和新的逻辑从而增加了主要类的复杂度,而这些新加入的东西仅仅是为了满足一些只存在某种特定情况下才会执行的特殊行为的需要。

而装饰模式却提供了一个非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它要装饰的对象,因此,当需要执行特殊的行为时,客户代码就可以在运行时根据需要有选择地,按顺序地使用装饰功能包装对象。


4、装饰模式的优点:

把类中的装饰功能从类中搬移去除,这样就可以简化原有的类。更大的好处是有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。有一点要注意就是装饰模式的装饰顺序很重要,比如加密数据和过滤词汇都可以是数据持久化前的装饰功能,但若是先加密了数据再过滤功能就会出问题了。最理想的情况,是保证装饰类之间的彼此独立,这样它们就可以以任何的顺序进行结合了。


5、C++代码实现

[cpp] view plaincopy
 
  1. #include <iostream>  
  2. #include <string>  
  3. using namespace std;  
  4.   
  5. //抽象组件类,定义了接口  
  6. class Component  
  7. {  
  8. public:  
  9.     virtual void Operation() = 0;  
  10. };  
  11.   
  12. //具体组件类  
  13. class ConcreteComponent: public Component   
  14. {  
  15. public:  
  16.     void Operation() {  
  17.         cout << "具体对象的操作" << endl;  
  18.     }  
  19. };  
  20.   
  21. //装饰类,从这里开始了对象链。  
  22. class Decorator: public Component   
  23. {  
  24. protected:  
  25.     Component * p_component;  
  26. public:  
  27.     Decorator() {  
  28.         p_component = NULL;  
  29.     }  
  30.     void SetComponent(Component * p_component) {  
  31.         Decorator::p_component = p_component;  
  32.     }  
  33.     void Operation() {  
  34.         if (p_component != NULL) {  
  35.             p_component->Operation();  
  36.         }  
  37.     }  
  38. };  
  39.   
  40. //具体装饰类A  
  41. class ConcreteDecoratorA : public Decorator   
  42. {  
  43. private:  
  44.     string addState;  
  45. public:  
  46.     void Operation()   
  47.     {  
  48.         Decorator::Operation();  
  49.         addState = "New State";  
  50.         cout << "具体装饰对象A的操作" << endl;  
  51.     }  
  52. };  
  53.   
  54. //具体装饰类B  
  55. class ConcreteDecoratorB : public Decorator  
  56. {  
  57. private:  
  58.     void AddBehavior() {  
  59.         cout << "added behavior" << endl;  
  60.     }  
  61. public:  
  62.     void Operation() {  
  63.         Decorator::Operation();  
  64.         AddBehavior();  
  65.         cout << "具体装饰对象B的操作" << endl;  
  66.     }  
  67. };  
  68.   
  69. int main()   
  70. {  
  71.     ConcreteComponent c;  
  72.     ConcreteDecoratorA a;  
  73.     ConcreteDecoratorB b;  
  74.     a.SetComponent(&c);  
  75.     b.SetComponent(&a);  
  76.     b.Operation();  
  77.     return 0;  
  78. }  


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值