且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C++设计模式8--装饰模式(Decorator)--动态的增减功能

更新时间:2022-08-14 10:51:17

新奇的IPad

快到媳妇生日了,这几天加班加点的干活,给媳妇买了个IPadMini,可把媳妇乐坏了,媳妇拿到手第一天,就跑出去跟姐妹们得瑟了一把。

 

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class Pad  
  5. {  
  6. public:  
  7.     Pad(){ }  
  8.     virtual ~Pad(){ }  
  9.     virtual void Show( ) = 0;  
  10. };  
  11.   
  12. class IPad : public Pad  
  13. {  
  14. public :  
  15.     IPad( ){ }  
  16.     virtual ~IPad( ){  };  
  17.   
  18.     void Show( )  
  19.     {  
  20.         std::cout <<"新的Ipad Mini..." <<endl;  
  21.     }  
  22. };  
  23.   
  24. int main( )  
  25. {  
  26.     // 给媳妇买了一个IpadMini  
  27.     Pad *pad = new IPad( );  
  28.     pad->Show( );               // 跑出去得瑟一下  
  29.   
  30.     return 0;  
  31. }  
#include <iostream>
using namespace std;

class Pad
{
public:
	Pad(){ }
	virtual ~Pad(){ }
	virtual void Show( ) = 0;
};

class IPad : public Pad
{
public :
    IPad( ){ }
    virtual ~IPad( ){  };

    void Show( )
    {
        std::cout <<"新的Ipad Mini..." <<endl;
    }
};

int main( )
{
    // 给媳妇买了一个IpadMini
    Pad *pad = new IPad( );
    pad->Show( );               // 跑出去得瑟一下

	return 0;
}

 弄个保护套

晚上回来,我问她,开心不,她说,开心是开心,但是朋友们都说怎么没给Pad弄个保护套,要不容易摔,摔坏了去维修可是很贵的,我嘻嘻一笑,容易直接上苹果店买了一个,走上路上美滋滋的。

 

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. // pad类的抽象接口  
  5. class Pad  
  6. {  
  7. public:  
  8.     Pad(){ }  
  9.     virtual ~Pad(){ }  
  10.     virtual void Show( ) = 0;  
  11. };  
  12.   
  13. // 新的IPadMini  
  14. class IPad : public Pad  
  15. {  
  16. public :  
  17.     IPad( ){ }  
  18.     virtual ~IPad( ){  };  
  19.   
  20.     void Show( )  
  21.     {  
  22.         std::cout <<"新的Ipad Mini..." <<endl;  
  23.     }  
  24. };  
  25.   
  26. // 加了保护套的IPadMini  
  27. class CoverIPad : public IPad  
  28. {  
  29. public :  
  30.     CoverIPad( ){ }  
  31.     virtual ~CoverIPad( ){  };  
  32.   
  33.     void Show( )  
  34.     {  
  35.         std::cout <<"加了保护套的,新的Ipad Mini..." <<endl;  
  36.     }  
  37. };  
  38.   
  39.   
  40. int main( )  
  41. {  
  42.     // 现在我买了一个IpadMini  
  43.     Pad *pad = new CoverIPad( );  
  44.     pad->Show( );               // 跑出去得瑟一下  
  45.   
  46.   
  47. }  
#include <iostream>
using namespace std;

// pad类的抽象接口
class Pad
{
public:
	Pad(){ }
	virtual ~Pad(){ }
	virtual void Show( ) = 0;
};

// 新的IPadMini
class IPad : public Pad
{
public :
    IPad( ){ }
    virtual ~IPad( ){  };

    void Show( )
    {
        std::cout <<"新的Ipad Mini..." <<endl;
    }
};

// 加了保护套的IPadMini
class CoverIPad : public IPad
{
public :
    CoverIPad( ){ }
    virtual ~CoverIPad( ){  };

    void Show( )
    {
        std::cout <<"加了保护套的,新的Ipad Mini..." <<endl;
    }
};


int main( )
{
    // 现在我买了一个IpadMini
    Pad *pad = new CoverIPad( );
    pad->Show( );               // 跑出去得瑟一下


}

还要个贴膜???

回家拿给媳妇看,媳妇说,老公能不能再给贴个膜啊 ,人家指甲长,万一把屏划花了怎么办呢呢,还有....(此处省略一万字),好吧再次出发,等等,难道要我在派生出一个CoverFoilIPad,天天这样子一天一个新的花样,这框架得多复杂,不行得换个方式。

我想想,直接弄装饰得了,那些保护套,贴膜什么的不都是装饰么。。

好了装饰模式出现了。

基础还是我们的Ipad,

  1. //公共抽象类  
  2. // 对应于 -=> 抽象构件(Component)角色  
  3. class Pad  
  4. {  
  5. public:  
  6.     Pad(){ }  
  7.     virtual ~Pad(){ }  
  8.     virtual void Show( ) = 0;  
  9. };  
  10.   
  11.   
  12. // 具体构件(Concrete Component)角色  
  13. class IPad : public Pad  
  14. {  
  15. public :  
  16.     IPad( ){ }  
  17.     virtual ~IPad( ){  };  
  18.   
  19.     void Show( )  
  20.     {  
  21.         std::cout <<"新的Ipad Mini..." <<endl;  
  22.     }  
  23. };  
//公共抽象类
// 对应于 -=> 抽象构件(Component)角色
class Pad
{
public:
	Pad(){ }
	virtual ~Pad(){ }
	virtual void Show( ) = 0;
};


// 具体构件(Concrete Component)角色
class IPad : public Pad
{
public :
    IPad( ){ }
    virtual ~IPad( ){  };

    void Show( )
    {
        std::cout <<"新的Ipad Mini..." <<endl;
    }
};

下面是那些装饰,保护套,贴膜,管你是什么,爱来多少来多少,咱不怕

  1. // 装饰(Decorator)角色:  
  2. class Decorator : public Pad  
  3. {  
  4. public :  
  5.     Decorator(Pad *pad)  
  6.     {  
  7.         m_pad = pad;  
  8.     }  
  9.     virtual ~Decorator( ){ };  
  10.   
  11.     void Show( )  
  12.     {  
  13.         this->m_pad->Show( );       // 展示一下自己的手机  
  14.     }  
  15.   
  16. protected:  
  17.     Pad *m_pad;  
  18.   
  19.     virtual void AddDecorator( ) = 0;  
  20.   
  21. };  
  22.   
  23. // 具体装饰(Concrete Decorator)角色  
  24. class CoverDecorator : public Decorator  
  25. {  
  26. public :  
  27.     CoverDecorator(Pad *pad)  
  28.     :Decorator(pad)  
  29.     {  
  30.     }  
  31.   
  32.     virtual ~CoverDecorator( ){ }  
  33.   
  34.     void Show( )  
  35.     {  
  36.         this->AddDecorator( );  
  37.         Decorator::Show( );  
  38.     }  
  39.   
  40. protected:  
  41.     void AddDecorator( )  
  42.     {  
  43.         std::cout <<"弄了个保护套";  
  44.     }  
  45.   
  46. };  
  47.   
  48. // 具体装饰(Concrete Decorator)角色  
  49. class FoilDecorator : public Decorator  
  50. {  
  51. public :  
  52.     FoilDecorator(Pad *pad)  
  53.     :Decorator(pad)  
  54.     {  
  55.     }  
  56.     virtual ~FoilDecorator( ){ }  
  57.   
  58.     void Show( )  
  59.     {  
  60.         this->AddDecorator( );  
  61.         Decorator::Show( );  
  62.     }  
  63.   
  64. protected:  
  65.     void AddDecorator( )  
  66.     {  
  67.         std::cout <<"贴了个的贴膜,";  
  68.     }  
  69.   
  70. };  
// 装饰(Decorator)角色:
class Decorator : public Pad
{
public :
    Decorator(Pad *pad)
    {
        m_pad = pad;
    }
    virtual ~Decorator( ){ };

    void Show( )
    {
        this->m_pad->Show( );       // 展示一下自己的手机
    }

protected:
    Pad *m_pad;

    virtual void AddDecorator( ) = 0;

};

// 具体装饰(Concrete Decorator)角色
class CoverDecorator : public Decorator
{
public :
    CoverDecorator(Pad *pad)
    :Decorator(pad)
    {
    }

    virtual ~CoverDecorator( ){ }

    void Show( )
    {
        this->AddDecorator( );
        Decorator::Show( );
    }

protected:
    void AddDecorator( )
    {
        std::cout <<"弄了个保护套";
    }

};

// 具体装饰(Concrete Decorator)角色
class FoilDecorator : public Decorator
{
public :
    FoilDecorator(Pad *pad)
    :Decorator(pad)
    {
    }
    virtual ~FoilDecorator( ){ }

    void Show( )
    {
        this->AddDecorator( );
        Decorator::Show( );
    }

protected:
    void AddDecorator( )
    {
        std::cout <<"贴了个的贴膜,";
    }

};

下面看看媳妇怎么去得瑟的

  1. int main( )  
  2. {  
  3.     // 现在我买了一个IpadMini  
  4.     Pad *pad = new IPad( );  
  5.     pad->Show( );               // 跑出去得瑟一下  
  6.   
  7.     // 不行,还需要加个保护套  
  8.     Pad *coveDeco = new CoverDecorator(pad);  
  9.     coveDeco->Show( );               // 现在可以了吧,再出去得色一下  
  10.   
  11.     // 好吧,再来个贴膜  
  12.     Pad *foilDeco = new FoilDecorator(coveDeco);  
  13.     foilDeco->Show( );  
  14. }  
int main( )
{
    // 现在我买了一个IpadMini
    Pad *pad = new IPad( );
    pad->Show( );               // 跑出去得瑟一下

    // 不行,还需要加个保护套
    Pad *coveDeco = new CoverDecorator(pad);
    coveDeco->Show( );               // 现在可以了吧,再出去得色一下

    // 好吧,再来个贴膜
    Pad *foilDeco = new FoilDecorator(coveDeco);
    foilDeco->Show( );
}

模式总结


概述

又叫装饰者模式。装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象

C++设计模式8--装饰模式(Decorator)--动态的增减功能

特点

①装饰对象和真实对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。

② 装饰对象包含一个真实对象的引用(reference)

③ 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。

④装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

要点:

1. 装饰者和被装饰对象有相同的超类型。

2. 可以用一个或多个装饰者包装一个对象。

3. 装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。

4. 对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。

5. 装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。

6. 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。在实际项目中可以根据需要为装饰者添加新的行为,做到“半透明”装饰者。

适用场景与优缺点:

在以下情况下应当使用装饰模式:

1.需要扩展一个类的功能,或给一个类增加附加责任。 

2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销。 

3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

优点:

1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。

2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。

2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出***选择。


转载:http://blog.csdn.net/gatieme/article/details/18034425