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

新奇的IPad

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

 

[cpp] view plain copy print?

  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弄个保护套,要不容易摔,摔坏了去维修可是很贵的,我嘻嘻一笑,容易直接上苹果店买了一个,走上路上美滋滋的。

 

[cpp] view plain copy print?

  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,

[cpp] view plain copy print?

  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;
    }
};

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

[cpp] view plain copy print?

  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 <<"贴了个的贴膜,";
    }

};

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

[cpp] view plain copy print?

  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( );
}

模式总结

概述

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

特点

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

② 装饰对象包含一个真实对象的引用(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

时间: 2024-09-16 13:41:17

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

乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)

原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)[索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:webabcd 介绍 动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活. 示例 有一个Message实体类,某个对象对它的操作有Insert()和Get()方法,现在扩展这个对象的功能. MessageModel using System;using System.Collecti

【设计模式】—— 装饰模式Decorator

模式意图 在不改变原来类的情况下,进行扩展. 动态的给对象增加一个业务功能,就功能来说,比生成子类更方便. 应用场景 1 在不生成子类的情况下,为对象动态的添加某些操作. 2 处理一些可以撤销的职责. 3 当不能使用生成子类来扩充时. 模式结构 Component 外部接口,用于定义外部调用的形式.提供默认的处理方法. interface Component{ public void operation(); }   ConcreteComponent  具体的处理类,用于实现operation

温故而知新:设计模式之装饰模式(Decorator)

小时候对日本的动画片十分着迷,"圣斗士"是我的最爱:长大后也曾经一度对"海贼王"十分痴迷:大学看武侠小说时,也特别喜欢那种主人公有奇遇的情况:吃到一颗千年异果,然后功夫大增60年... 这些个场景都有一个共同点:对象(或系统)会因为一些需求(通常这些需求之间没有任何关联),而扩展自己的功能.具体来说:青铜战士如果有幸能穿上黄金圣衣,不管你是不是黄金圣斗士,在穿上黄金圣衣的那一刻,你就具有黄金圣斗士的能力:海赋王中的人物,如果能吃到一颗奇异果,就能获得特别的能力(比如

设计模式重构应用---Decorator模式

先简单介绍Decorator 模式(装饰模式)的内容和应用场景. 装饰模式可以动态地给一个对象添加额外的职责.虽然,利用子类继承也可以实现这样的功能,但是 装饰模式提供了一个更灵活的方式. 因为继承会为类型引入的静态特质,使得这种扩展方式缺乏灵活性: 并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨 胀. 下面是标准Decorator 模式的UML结构图: [此图来自GOF <设计模式>一书] 现在结合我实际开发的一个例子谈谈这个模式的重构应用. 还是那

设计模式之六(装饰模式)

原文:设计模式之六(装饰模式) 前言 装饰模式:动态の给一个对象添加有些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 装饰模式结构图   Component是定义一个对象接口,可以给这些对象动态添加职责 ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责 Decorator装饰抽象类,继承了Component,从外类来扩展Componnt类的功能,但对于Component来说,是无需知道Decorator的存在的 代码实现 Component类 p

大话设计模式之装饰模式

          装饰,字面意思是对生活用品或生活环境进行艺术加工的手法.它必须与所装饰的客体有机地结合,成为统一.和谐的整体,以便丰富艺术形象,扩大艺术表现力,加强审美效果,并提高其功能.经济价值和社会效益.我们编程世界中的装饰又有着怎样与众不同的解释呢?原来装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象.         我们来看一个具体的例子,经过一个上午的消耗,加上昨天晚上熬夜看<出彩中国人>,早上赖床,

设计模式之装饰模式

          装饰模式,动态的给一个对象添加一些额外的职责,就增加功能而言,装饰模式比生成子类更为灵活.这种模式可以有效的将类的核心职责和装饰功能区分开来.         设计原则:          1.多用组合,少用继承             利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为.然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展.            2.类的设计应对扩展开放,对修改关闭.          要点

java设计模式之装饰模式详细介绍_java

1.    装饰模式(Decorator)的定义:又名包装(Wrapper)模式,装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 2.    装饰模式以对客户端透明的方式动态的给一个对象附加上更多的责任.换言之客户端并不会觉的对象在装饰前和装饰后有什么区别. 3.    装饰模式可以在不创造更多的子类的模式下,将对象的功能加以扩展. 4.    装饰模式与类继承的区别: 1)    装饰模式是一种动态行为,对已经存在类进行随意组合,而类的继承是一种静态的行为,一个类定义成

java后台接口-如何实现类似qq空间的“与我相关”动态即时提示功能?

问题描述 如何实现类似qq空间的"与我相关"动态即时提示功能? 项目要实现类似功能,目前我有三种实现方案,但总觉得并非上上之策,希望有过类似经验的朋友参与讨论? 方案1:APP用户点击后调用后台统计接口,传值至前台展示. 优点:实现简单,服务器性能消耗低.缺点:不能真正意义上实现即时通知. 方案二:服务器定时任务,根据情况推送动态. 优点:半即时推送,实现不难,缺点:消耗一定服务器性能 方案三:把活跃客户看成是一个活跃客户池, 由服务器主动去推送信息到客户端, 客户端接收到指令+数据后