装饰模式

装饰模式:一个类有一些核心功能;但随着业务改变,需要能够在核心功能之外加一些功能。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性。

给某个对象,而不是整个类,添加一些功能。就增加功能来说,装饰器模式比相比生成子类更加灵活。

适用性:

       1、在不影响其它对象的情况下,以动态、透明的方式给单个对象添加职责。

       2、处理那些可以撤销的职责。

       3、希望为某个对象而不是一整个类添加一些功能时。

       4、当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

装饰模式的UML图:

Component

——定义一个对象接口,可以给这些对象动态的添加职责。

ConcreteComponent

——定义一个对象,可以给这个对象添加一些职责。

Decorator

——维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。

ConcreteDecorator

——向组件添加职责。

注意:

       1、接口的一致性。装饰对象的接口必须与它所装饰的Component的接口是一致的。

       2、省略抽象的Docorator类。当你仅需要添加一个职责的时,没有必要定义抽象Decorator类。你常常需要处理显存的类层次结构而不是设计一个新系统,这时你可以把Decorator向Component转发请求的职责合并到ConcreteDecorator中。

       3、保持Component类的简单性。为了保证接口的一致性,组件和装饰必须有一个共同的Component父类。因此保持这个类的简单些是很重要的。

具体例子:

 在这种设计中,手机的装饰功能被独立出来,可以单独发展,进而简化了具体手机类的设计。下面给出Phone类的实现:

[cpp]  view plain  copy
  1. //公共抽象类  
  2. class Phone  
  3. {  
  4. public:  
  5.     Phone() {}  
  6.     virtual ~Phone() {}  
  7.     virtual void ShowDecorate() {}  
  8. };  

        具体的手机类的定义:

[cpp]  view plain  copy
  1. //具体的手机类  
  2. class iPhone : public Phone  
  3. {  
  4. private:  
  5.     string m_name; //手机名称  
  6. public:  
  7.     iPhone(string name): m_name(name){}  
  8.     ~iPhone() {}  
  9.     void ShowDecorate() { cout<<m_name<<"的装饰"<<endl;}  
  10. };  
  11. //具体的手机类  
  12. class NokiaPhone : public Phone  
  13. {  
  14. private:  
  15.     string m_name;  
  16. public:  
  17.     NokiaPhone(string name): m_name(name){}  
  18.     ~NokiaPhone() {}  
  19.     void ShowDecorate() { cout<<m_name<<"的装饰"<<endl;}  
  20. };  

        装饰类的实现:

[cpp]  view plain  copy
  1. //装饰类  
  2. class DecoratorPhone : public Phone  
  3. {  
  4. private:  
  5.     Phone *m_phone;  //要装饰的手机  
  6. public:  
  7.     DecoratorPhone(Phone *phone): m_phone(phone) {}  
  8.     virtual void ShowDecorate() { m_phone->ShowDecorate(); }  
  9. };  
  10. //具体的装饰类  
  11. class DecoratorPhoneA : public DecoratorPhone  
  12. {  
  13. public:  
  14.     DecoratorPhoneA(Phone *phone) : DecoratorPhone(phone) {}  
  15.     void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }  
  16. private:  
  17.     void AddDecorate() { cout<<"增加挂件"<<endl; } //增加的装饰  
  18. };  
  19. //具体的装饰类  
  20. class DecoratorPhoneB : public DecoratorPhone  
  21. {  
  22. public:  
  23.     DecoratorPhoneB(Phone *phone) : DecoratorPhone(phone) {}  
  24.     void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }  
  25. private:  
  26.     void AddDecorate() { cout<<"屏幕贴膜"<<endl; } //增加的装饰  
  27. };  

         客户使用方式:

[cpp]  view plain  copy
  1. int main()  
  2. {  
  3.     Phone *iphone = new NokiaPhone("6300");  
  4.     Phone *dpa = new DecoratorPhoneA(iphone); //装饰,增加挂件  
  5.     Phone *dpb = new DecoratorPhoneB(dpa);    //装饰,屏幕贴膜  
  6.     dpb->ShowDecorate();  
  7.     delete dpa;  
  8.     delete dpb;  
  9.     delete iphone;  
  10.     return 0;  
  11. }  
装饰模式提供了更加灵活的向对象添加职责的方式。可以用添加和分离的方法,用装饰在运行时刻增加和删除职责。装饰模式提供了一种“即用即付”的方
法来添加职责。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值