• 装饰模式(Decorator)C++实现


    装饰模式

           层层包装,增强功能。这就是装饰模式的要旨!装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能。它把需要装饰的功能放在单独的类中,并让这个类包装它所要装饰的对象。

     

    意图:

           动态的给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类模式更为灵活。

     

    适用性:

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

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

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

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

     

    效果:

           1、比静态继承更为灵活。继承机制会产生许多新类,增加了系统的复杂度。而装饰可以使你对一些职责进行混合和匹配。

           2、避免在层次结构高层的类有太多的特征。扩展一个复杂类的时候,很可能会暴露出与添加职责无关的细节。你可以定义一个简单的类,并且用装饰逐渐的添加功能。

           3、会产生许多小对象。

           4、Decorator与Component不一样,Decorator是一个透明的包装。如果我们从对象标识的观点出发,一个被装饰了的组件与这个组件是有差别的,因此,使用装饰时不应该依赖对象标识。

     

    注意:

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

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

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

          

    参与者:

    Component

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

    ConcreteComponent

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

    Decorator

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

    ConcreteDecorator

    ——向组件添加职责。

     

    UML:

     

     

    代码实现:在控制台打印如下表格,基本的姓名、年龄、学历、性别必须拥有,其它如英语等级等属性自由添加。

     

    打印一行表格代码:

    1 void print(char* str)
    2 {
    3     cout<<"├───────────────────────────────"<<endl
    4         <<""<<str<<":"<<endl;
    5 }

    定义一个抽象基类absTable(Component)

    1 class absTable
    2 {
    3 public:
    4 virtual void putTable() = 0;
    5 };

    定义具体的表格absTable(ConcreteComponent)

     1 class BaseTable:public absTable
     2 {
     3 public:
     4     virtual void putTable()
     5     {
     6         print("姓名");
     7         print("性别");
     8         print("学历");
     9         print("年龄");
    10         cout<<"└───────────────────────────────"<<endl;
    11     }
    12 };

    定义抽象Decorator

     1 class Decorator:public absTable
     2 {
     3 public:
     4     Decorator(absTable* concrateTb):mpAbsTable(concrateTb){}
     5 
     6     virtual void putTable()
     7     {
     8         mpAbsTable->putTable();
     9     }
    10 private:
    11     absTable* mpAbsTable;
    12 };

    定义具体的装饰EnglishDcrt、CurWage、Experience(ConcreteDecoratorA、B、C)

     1 class EnglishDcrt:public Decorator
     2 {
     3 public:
     4     EnglishDcrt(absTable* pTb):Decorator(pTb){}
     5 
     6     virtual void putTable()
     7     {
     8         print("英语等级");
     9         Decorator::putTable();
    10     }
    11 };
     1 class CurWage:public Decorator
     2 {
     3 public:
     4     CurWage(absTable* pTb):Decorator(pTb){}
     5 
     6     virtual void putTable()
     7     {
     8         print("当前薪水");
     9         Decorator::putTable();
    10     }
    11 };
     1 class Experience:public Decorator
     2 {
     3 public:
     4     Experience(absTable* pTb):Decorator(pTb){}
     5 
     6     virtual void putTable()
     7     {
     8         print("项目经验");
     9         Decorator::putTable();
    10     }
    11 };

    客户端代码:

     1 #include <iostream>
     2 #include "Decorator.h"
     3 
     4 using namespace std;
     5 
     6 //动态的给一个对象添加一些额外的职责!
     7 //层层包装,增强功能。这就是装饰模式的要旨!
     8 //接口稳定不变!
     9 
    10 void main()
    11 {
    12     BaseTable pro1;
    13     cout<<"初始表格:"<<endl<<endl;
    14     pro1.putTable();
    15 
    16     cout<<"新表格1:"<<endl<<endl;
    17     EnglishDcrt eng(&pro1);
    18     eng.putTable();
    19 
    20     cout<<"新表格2:"<<endl<<endl;
    21     CurWage wg(&eng);
    22     wg.putTable();
    23 
    24     cout<<"新表格3:"<<endl<<endl;
    25     Experience ex(&wg);
    26     ex.putTable();
    27 }

    部分结果:

    这样我们实现了项目经验、当前薪水、英语等级的自由组合,当然还可以添加更多的属性。

  • 相关阅读:
    freemarker报错之五
    freemarker处理空值
    freemarker报错之四
    freemarker之include指令
    freemarker之list
    freemarker报错之三
    freemarker中的if...elseif...else语句
    freemarker获取封装类中对象的属性
    单块读和多块读操作汇总
    freemarker报错之二
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13885016.html
Copyright © 2020-2023  润新知