zoukankan      html  css  js  c++  java
  • 设计模式读书笔记-decorator 模式

    转自http://blog.csdn.net/qq276592716/article/details/6679695

    0 引言

    0.1 目的

           本文档给出设计模式之——Decorator模式的简化诠释,并给出其C++实现。

    0.2 说明

    Project

    Design Pattern Explanation(By K_Eckel)

    Authorization

    Free Distributed but Ownership Reserved

    Date

    2005-04-05(Cherry blossom is Beautiful)

    Test Bed

    MS Visual C++ 6.0

    0.3 参考

           在本文档的写作中,参考了以下的资源,在此列出表示感谢:

    u       书籍

    [GoF 2000]:GoF,Design Patterns-Elements of Reusable Object-Oriented Software

    Addison-Wesley 2000/9.

            [Martine 2003]:Robert C.Martine, Agile Software Development Principles, Patterns, and Practices, Pearson Education, 2003.

    0.4 联系作者

    Author

    K_Eckel

    State

    Candidate for Master’s Degree School of Computer Wuhan University

    E_mail

    frwei@whu.edu.cn  

    2 Decorator模式

    2.1 问题

           在OO设计和开发过程,可能会经常遇到以下的情况:我们需要为一个已经定义好的类添加新的职责(操作),通常的情况我们会给定义一个新类继承自定义好的类,这样会带来一个问题(将在本模式的讨论中给出)。通过继承的方式解决这样的情况还带来了系统的复杂性,因为继承的深度会变得很深。

           而Decorator提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合。有关这些内容在讨论中进一步阐述。

    2.2 模式选择

           Decorator模式典型的结构图为:


    2-1Decorator Pattern结构图

          在结构图中,ConcreteComponentDecorator需要有同样的接口,因此ConcreteComponentDecorator有着一个共同的父类。这里有人会问,让Decorator直接维护一个指向ConcreteComponent引用(指针)不就可以达到同样的效果,答案是肯定并且是否定的。肯定的是你可以通过这种方式实现,否定的是你不要用这种方式实现,因为通过这种方式你就只能为这个特定的ConcreteComponent提供修饰操作了,当有了一个新的ConcreteComponent你又要去新建一个Decorator来实现。但是通过结构图中的ConcreteComponentDecorator有一个公共基类,就可以利用OO中多态的思想来实现只要是Component型别的对象都可以提供修饰操作的类,这种情况下你就算新建了100Component型别的类ConcreteComponent,也都可以由Decorator一个类搞定。这也正是Decorator模式的关键和威力所在了。

           当然如果你只用给Component型别类添加一种修饰,则Decorator这个基类就不是很必要了。

    2.3 实现

    2.3.1 完整代码示例(code

           Decorator模式的实现起来并不是特别困难,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用C++实现,并在VC 6.0下测试运行)。

    代码片断1Decorator.h
    //Decorator.h

    #ifndef _DECORATOR_H_
    #define _DECORATOR_H_

    class Component
    {
    public:
     virtual ~Component();

     virtual void  Operation();

    protected:
     Component();

    private:

    };

    class ConcreteComponent:public Component
    {
    public:
     ConcreteComponent();

     ~ConcreteComponent();

     void  Operation();

    protected:

    private:

    };

    class Decorator:public Component
    {
    public:
     Decorator(Component* com);

     virtual ~Decorator();

     void  Operation();

    protected:
     Component* _com;

    private:
    };

    class ConcreteDecorator:public Decorator
    {
    public:
     ConcreteDecorator(Component* com);

     ~ConcreteDecorator();

     void  Operation();

     void AddedBehavior();

    protected:

    private:

    };

    #endif //~_DECORATOR_H_

    代码片断2Decorator.cpp
    //Decorator.cpp

    #include "Decorator.h"

    #include <iostream>

    Component::Component()
    {

    }

    Component::~Component()
    {

    }

    void Component::Operation()
    {

    }

    ConcreteComponent::ConcreteComponent()
    {

    }

    ConcreteComponent::~ConcreteComponent()
    {

    }

    void ConcreteComponent::Operation()
    {
     std::cout<<"ConcreteComponent operation..."<<std::endl;
    }

    Decorator::Decorator(Component* com)
    {
     this->_com = com;
    }

    Decorator::~Decorator()
    {
     delete _com;
    }

    void Decorator::Operation()
    {

    }

    ConcreteDecorator::ConcreteDecorator(Component* com):Decorator(com)
    {

    }

    ConcreteDecorator::~ConcreteDecorator()
    {

    }

    void ConcreteDecorator::AddedBehavior()
    {
     std::cout<<"ConcreteDecorator::AddedBehacior...."<<std::endl;
    }
    void ConcreteDecorator::Operation()
    {
     _com->Operation();

     this->AddedBehavior();
    }

     代码片断3main.cpp
    //main.cpp

    #include "Decorator.h"

    #include <iostream>
    using namespace std;

    int main(int argc,char* argv[])
    {
     Component* com = new ConcreteComponent();

     Decorator* dec = new ConcreteDecorator(com);

     dec->Operation();

     delete dec;

     return 0;
    }

    2.3.2 代码说明

    Decorator模式很简单,代码本身没有什么好说明的。运行示例代码可以看到,ConcreteDecorator给ConcreteComponent类添加了动作AddedBehavior。

    2.4 讨论

           Decorator模式和Composite模式有相似的结构图,其区别在Composite模式已经详细讨论过了,请参看相应文档。另外GoF在《设计模式》中也讨论到Decorator和Proxy模式有很大程度上的相似,初学设计模式可能实在看不出这之间的一个联系和相似,并且它们在结构图上也很不相似。实际上,在本文档2.2节模式选择中分析到,让Decorator直接拥有一个ConcreteComponent的引用(指针)也可以达到修饰的功能,大家再把这种方式的结构图画出来,就和Proxy很相似了!

           Decorator模式和Proxy模式的相似的地方在于它们都拥有一个指向其他对象的引用(指针),即通过组合的方式来为对象提供更多操作(或者Decorator模式)间接性(Proxy模式)。但是他们的区别是,Proxy模式会提供使用其作为代理的对象一样接口,使用代理类将其操作都委托给Proxy直接进行。这里可以简单理解为组合和委托之间的微妙的区别了。

           Decorator模式除了采用组合的方式取得了比采用继承方式更好的效果,Decorator模式还给设计带来一种“即用即付”的方式来添加职责。在OO设计和分析经常有这样一种情况:为了多态,通过父类指针指向其具体子类,但是这就带来另外一个问题,当具体子类要添加新的职责,就必须向其父类添加一个这个职责的抽象接口,否则是通过父类指针是调用不到这个方法了。这样处于高层的父类就承载了太多的特征(方法),并且继承自这个父类的所有子类都不可避免继承了父类的这些接口,但是可能这并不是这个具体子类所需要的。而在Decorator模式提供了一种较好的解决方法,当需要添加一个操作的时候就可以通过Decorator模式来解决,你可以一步步添加新的职责。

  • 相关阅读:
    LeetCode Minimum Path Sum
    第六章-2-数组练习
    第六章-1-数组练习
    第五章-for循环的练习
    第四章:if else switch使用
    第三章
    实训篇-JavaScript-打地鼠
    实训篇-Html-注册页面【简单】
    实训篇-Html-计算器
    实训篇-JavaScript-陶渊明去没去过桃花源
  • 原文地址:https://www.cnblogs.com/jameszhan/p/decorator.html
Copyright © 2011-2022 走看看