设计模式 --> (12)装饰模式

装饰模式

  时常会遇到这样一种情况,我已经设计好了一个接口,并且也有几个实现类,但是这时我发现我设计的时候疏忽了,忘记了一些功能,或者后来需求变动要求加入一 些功能,最简单的做法就是修改接口,添加函数,然后继承类中都相应的添加实现,这样做倒也没什么问题,但是如果这种变化来个好几次或者继承类非常多,那工 作量可就大了。

  装饰者模式,在不修改现在有接口和实现类的基础上实现功能或者状态的添加。

适用性:

  如果需要添加新功能,但又不想修改定义好的接口或者抽象类,那么这时候就比较适合装饰模式,例如很多图形系统中的组件,就可以使用装饰模式,来让新的组件在继承现在功能的基础上添加新的功能。

  装饰模式一般是针对接口或者抽象类的变化,如果是具体实现类的变化,则要考虑适用哪种模式。

优点

  1.可以不用修改原有的接口,就可以实现新功能的添加。

  2.装饰者可以很方便的转换原有接口中的实现,可以给装饰者指定不同的ConcreteComponent实现不同的功能。

缺点

  1.复杂性增加,装饰者模式会导致许多小类的产生。

示例

  比如有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。一种灵活的设计方式是,将手机嵌入到另 一对象中,由这个对象完成特性的添加,我们称这个嵌入的对象为装饰。

#include <iostream>
using namespace std;

//公共抽象类  
class Phone  
{  
    public:  
    Phone() {}  
    virtual ~Phone() {}  
    virtual void ShowDecorate() {}  
};

//具体的手机类  
class iPhone : public Phone  
{  
private:  
    string m_name; //手机名称  
public:  
    iPhone(string name): m_name(name){}  
    ~iPhone() {}  
    void ShowDecorate() { cout<<m_name<<"的装饰"<<endl;}  
};  

//具体的手机类  
class NokiaPhone : public Phone  
{  
private:  
    string m_name;  
public:  
    NokiaPhone(string name): m_name(name){}  
    ~NokiaPhone() {}  
    void ShowDecorate() { cout<<m_name<<"的装饰"<<endl;}  
};  


//装饰类  
class DecoratorPhone : public Phone  
{  
private:  
    Phone *m_phone;  //要装饰的手机  
public:  
    DecoratorPhone(Phone *phone): m_phone(phone) {}  
    virtual void ShowDecorate() { m_phone->ShowDecorate(); }  
};  

//具体的装饰类  
class DecoratorPhoneA : public DecoratorPhone  
{  
public:  
    DecoratorPhoneA(Phone *phone) : DecoratorPhone(phone) {}  
    void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }  
private:  
    void AddDecorate() { cout<<"增加挂件"<<endl; } //增加的装饰  
}; 
 
//具体的装饰类  
class DecoratorPhoneB : public DecoratorPhone  
{  
public:  
    DecoratorPhoneB(Phone *phone) : DecoratorPhone(phone) {}  
    void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }  
private:  
    void AddDecorate() { cout<<"屏幕贴膜"<<endl; } //增加的装饰  
}; 

int main()  
{  
    Phone *iphone = new NokiaPhone("6300");  
    Phone *dpa = new DecoratorPhoneA(iphone); //装饰,增加挂件  
    Phone *dpb = new DecoratorPhoneB(dpa);    //装饰,屏幕贴膜  
    dpb->ShowDecorate();  
    delete dpa;  
    delete dpb;  
    delete iphone;  
    return 0;  
}  

参考: http://blog.csdn.net/wuzhekai1985

原文地址:https://www.cnblogs.com/jeakeven/p/4967080.html