Decorator装饰设计模式(结构型)

第八个设计模式

意图
动态地给一个对象添加一些额外的职责。有时候我们需要给某个对象而不是整个类添加一些功能。

适用性

  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤消的职责。
  • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,
  • 为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

结构
这里写图片描述

参与者
Component:定义一个对象接口,可以给这些对象动态地添加职责。

ConcreteComponent: 定义一个对象,可以给这个类的对象添加一些职责

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

ConcreteDecorator:向组件添加职责。

实现

#include <string>  
#include <iostream>  
#include <memory>  
using namespace std;  

//抽象类Tank  
class Tank  
{  
public:  
    virtual void shot()=0;  
    virtual void run()=0;  

public:  
    virtual ~Tank()  
    {  
        cout<<"in the destructor of Tank"<<endl;  
    }     
};  
//具体类 T50  
class T50:public Tank  
{  
public:  
    void shot()  
    {  
        cout<<"Tank T50 shot()"<<endl;  
    }  
    void run()  
    {  
        cout<<"Tank T50 run()"<<endl;  
    }  
public:  
    virtual ~T50()  
    {  
        cout<<"In the destructor of T50"<<endl;  
    }  
};  
//具体类T75  
class T75:public Tank  
{  
public:  
    void shot()  
    {  
        cout<<"Tank T75 shot()"<<endl;  
    }  
    void run()  
    {  
        cout<<"Tank T75 run()"<<endl;  
    }  
public:  
    virtual ~T75()  
    {  
        cout<<"In the destructor of T75"<<endl;  
    }  
};  

//抽象类,Decorator  
class Decorator:public Tank  
{  
protected:  
    Tank* tank;  
public:  
    Decorator(Tank* tank):tank(tank) {}  //具体的坦克的装饰类  
    virtual ~Decorator()  
    {  
        cout<<"In the destructor of Decorator"<<endl;  
    }  
public:  
    void shot()  
    {  
        tank->shot();  
    }  
    void run()  
    {  
        tank->run();  
    }  
};  

class InfraredDecorator: public Decorator  
{  
private:  
    string infrared;//这就是所谓的addAtrribute  
public:  
    InfraredDecorator(Tank* tank):Decorator(tank) {}  
    virtual ~InfraredDecorator()  
    {  
        cout<<"in the destructor of InfraredDecorator"<<endl;  
    }  
public:  
    void set_Infrared(const string &infrared)  
    {  
        this->infrared=infrared;  
    }  
    string get_infrared() const  
    {  
        return infrared;  
    }  
    void run()  
    {  
        tank->run();  
        set_Infrared("+Infrared");  
        cout<<get_infrared()<<endl;  
    }  
    void shot()  
    {  
        tank->shot();  
    }  
};  

class AmphibianDecorator:public Decorator  
{  
private:  
    string amphibian;  
public:  
    AmphibianDecorator(Tank* tank):Decorator(tank) {}  
    ~AmphibianDecorator()  
    {  
        cout<<"in the destructor of AmphibianDecorator"<<endl;  
    }  
public:  
    void set_amphibian(const string &hibian)  
    {  
        this->amphibian=hibian;  
    }  
    string get_amphibian() const  
    {  
        return amphibian;  
    }  
public:  
    void run()  
    {  
        tank->run();  
        set_amphibian("+amphibian");  
        cout<<get_amphibian()<<endl;  
    }  
    void shot()  
    {  
        tank->shot();  
    }  
};  

int main(int argc, char **argv)  
{  
    //给T50增加红外功能  
    Tank* tank1(new T50);  
    Tank* pid1(new InfraredDecorator(tank1));  
    pid1->shot();  
    cout<<endl;  
    pid1->run();  
    cout<<endl;  
    cout<<endl<<"---------------"<<endl;  
    //给t75增加红外、两栖功能  
    Tank* tank2(new T75);  
    tank2->run();  
    Tank* pid2(new InfraredDecorator(tank2));  
    Tank* pad2(new AmphibianDecorator(pid2));  
    pad2->shot();  
    cout<<endl;  
    pad2->run();  
    cout<<endl;  
    cout<<endl<<"--------------"<<endl;  

    //动态撤销其他装饰 ?  
    tank2->run();  

    Tank * tank3(tank2);  
    tank3->run();  
    return 0;  
}  

适用场景与优缺点:

在以下情况下应当使用装饰模式:
1.需要扩展一个类的功能,或给一个类增加附加责任。
2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

优点:
1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:
1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。

参考于:
http://blog.youkuaiyun.com/lcl_data/article/details/8830455

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值