设计模式——装饰模式

       设计模式是人们从长期的软件开发实战中总结出来的一些经验之谈,为软件领域中的开发人员提供了一种使用专家设计经验的有效途径,通常是多个设计模式结合使用。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,只有通过大量的编程实践才能真正领悟设计模式的精髓。在参加校招前我翻看了部分设计模式相关的书,对于每个设计模式模式,用C++写了个小例子,加深一下理解。主要参考《大话设计模式》和《设计模式》两本书以及借鉴其他博客园博文的优秀部分。本文介绍享元模式的实现和一些使用场景。希望对大家加深对设计模式的理解有一点帮助。

 

一、举例

        之前做过一个文件系统就叫MyFileSys 吧,后来的话,客户想加入一些附加功能,比如压缩、加密、杀毒之类的功能,这些附加功能没有先后顺序,比如你可以先压缩再加密,也可以先杀毒再压缩,等等

 

        这些附加功能是可选的,有的客户要这些功能,有的客户则不要,有的客户则要其中的几种附加功能等等。怎么设计呢?

 

第一种方案

        直接修改这个独立的文件系统 MyFileSys,对于不同的客户实现不同的文件系统。


       后来随着客户的增多,发现维护和修改的工作量越来越大。因为每增加一个客户就要重新生成一个类,然后把客户想要的附加功能加入,更加郁闷的是,只针对一个客户有时也是要修改很多次,客户今天要这些附加功能,明天又想加入另外一些功能,这样改来改去,维护工作量也是很大的。

第二种方案

       后来改用第二种方案,实现一个单独的附加功能类,保持原文件系统不变,这样在客户端就可以轻松的加入一些附加功能。

 

代码如下

#include
    
    
     
     
usingnamespacestd;
 
//定义一个对象接口,可以给这些对象动态地添加职责 
classFileSys 
{ 
public: 
    virtual~FileSys() 
    { 
    } 
       
    virtualvoidOperation() 
    { 
    } 
protected: 
    FileSys() 
    { 
    } 
}; 
 
//定义一个具体的对象 
classMyFileSys:publicFileSys 
{ 
public: 
    MyFileSys() 
    { 
    } 
       
    ~MyFileSys() 
    { 
    } 
       
    voidOperation() 
    { 
       cout<<"MyFileSysoperation..."<
     
     
      
      _fileSys=fileSys; 
    } 
       
    virtual~Decorator() 
    { 
       delete_fileSys; 
    } 
       
    voidOperation() 
    { 
    } 
protected: 
    FileSys*_fileSys; 
}; 
 
//压缩装饰类 
classZipDecorator:publicDecorator 
{ 
public: 
    ZipDecorator(FileSys*fileSys):Decorator(fileSys) 
    { 
    } 
       
    ~ZipDecorator() 
    { 
    } 
       
    voidOperation() 
    { 
       _fileSys->Operation();//首先运行以前的功能 
              
       this->AddedZipBehavior();//附加功能 
    } 
       
    voidAddedZipBehavior() 
    { 
       cout<<"AddedZipBehavior...."<
      
      
       
       Operation(); 
              
               this->AddedKillVirBehavior(); 
        } 
       
    voidAddedKillVirBehavior() 
    { 
       cout<<"AddedKillVirusBehavior...."<
       
       
        
        Operation(); 
              
       this->AddedEncrypeBehavior(); 
    } 
       
    voidAddedEncrypeBehavior() 
    { 
       cout<<"AddedEncryptBehavior...."<
        
        
          Operation(); return0; } 
        
       
       
      
      
     
     
    
    

 

这样之后,如果要添加附加功能,实现起来就很方便了。这种模式就是装饰模式。

 

二、装饰模式

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


说明:

Componet,主要是定义一个接口,通过这个接口可以给这些对象(ConcreteComponent)添加职责。

Dectorator,装饰类,通过外类(ConcreteDecorator)来扩展Component类的功能,对于Component来说,是无需知道这个抽象类的存在的。

ConcreteDecorator,具体装饰类,添加具体的附加功能。

优点:

1. 装饰类是为已有功能动态地添加更多功能的一种方式。

2. 有效地把类的核心职责和装饰功能区分开,而且可以去除相关类中重复的装饰逻辑。

 

三、 问题讨论

       从上图可以看到 Decorator 是继承于 Component 的,也就和 ConcreteComponent 成了兄弟了,但是 Decorator 的作用却是修饰 ConcreteComponent 的,这点好像是很怪怪的!!最说不通的是Decorator 与 Component 是没有is-a关系的!!

 

我个人觉得:

1. 这个继承关系,不应该是我们要重点关注的。这里使用继承主要是为了要重用 Operation() 这个接口,以达修饰的目的。

2. 重点是 Decorator 与 Component 这个组合关系。装饰类里有一个Component 指针,正是由于它的存在才能修饰到具体的 Component 对象。

 

        好啦,关于装饰模式就介绍到这里了,希望你已经掌握了这个模式并且可以熟练的使用它,那么本博文的效果就达到了。如果你还觉得意犹未尽,那么可以去看看博主的其他设计模式的介绍哦。

 

          关于设计模式,我推荐大家看看以下博客写的博文,关于设计模式的讲解将的特别好,我从中学习了很多,我的设计模式中的部分博文就是从这里借鉴过来的。

    博客链接:http://blog.csdn.net/wuzhekai1985

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值