Decorator装饰模式详解--设计模式(8)

来源:互联网 发布:伊藤润二漫画软件 编辑:程序博客网 时间:2024/06/06 12:29

Decorator装饰模式产生原因:        

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

Decorator装饰模式作用:

        Decorator提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合。这样就大大降低了基类的复杂性!

Decorator装饰模式典型的UML结构图如图1所示:

                      

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

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

Decorator装饰模式典型的示例代码如下:

Decorator.h

#ifndef _DECORATOR_H_#define _DECORATOR_H_//Component抽象类,定义该类对象的接口class Component{public:    virtual ~Component();    virtual void Operation()=0;protected:    Component();};//ConcreteDecorator:具体的Component对象,可以给该对象动态 添加职责class ConcreteComponent:public Component{public:    ConcreteComponent();    ~ConcreteComponent();    virtual void Operation();};//Decorator:装饰抽象类,继承自Componentclass Decorator:public Component{public:    Decorator(Component* com);    void SetComponent(Component* com);    virtual ~Decorator();    virtual void Operation();protected:    Component* _com;};//ConcreteDecorator就是具体的装饰对象之一,起到给Component添加职责的功能class ConcreteDecoratorA:public Decorator{public:    ConcreteDecoratorA(Component* com);    ~ConcreteDecoratorA();    virtual void Operation();    void AddBehavorA();};//ConcreteDecorator就是具体的装饰对象之二,起到给Component添加职责的功能class ConcreteDecoratorB:public Decorator{public:    ConcreteDecoratorB(Component* com);    ~ConcreteDecoratorB();    virtual void Operation();    void AddBehavorB();};//ConcreteDecorator就是具体的装饰对象之三,起到给Component添加职责的功能class ConcreteDecoratorC:public Decorator{public:    ConcreteDecoratorC(Component* com);    ~ConcreteDecoratorC();    virtual void Operation();    void AddBehavorC();};//只添加一种装饰,则不用抽象出装饰基类class DecoratorOnlyOne:public Component{public:    DecoratorOnlyOne(Component* com);    ~DecoratorOnlyOne();    virtual void Operation();    void AddBehavor();private:    Component* _com;};//如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类。//略#endif

Decorator.cpp

#include "Decorator.h"#include <iostream>using namespace std;Component::Component(){}Component::~Component(){    cout << "~Component" << endl;}ConcreteComponent::ConcreteComponent(){}ConcreteComponent::~ConcreteComponent(){    cout << "~ConcreteComponent" << endl;}void ConcreteComponent::Operation(){    cout << "原职责:ConcreteComponent::Operation" << endl;}Decorator::Decorator(Component* com){    this->_com = com;}void Decorator::SetComponent(Component* com){    this->_com = com;}Decorator::~Decorator(){    cout << "~Decorator" << endl;    delete this->_com;    this->_com = NULL;}void Decorator::Operation(){}ConcreteDecoratorA::ConcreteDecoratorA(Component* com):Decorator(com){}ConcreteDecoratorA::~ConcreteDecoratorA(){    cout << "~ConcreteDecoratorA" << endl;}void ConcreteDecoratorA::Operation(){    this->_com->Operation();    //附加职责A    this->AddBehavorA();}void ConcreteDecoratorA::AddBehavorA(){    cout << "附加职责A:ConcreteDecoratorA::AddBehavorA" << endl;}ConcreteDecoratorB::ConcreteDecoratorB(Component* com):Decorator(com){}ConcreteDecoratorB::~ConcreteDecoratorB(){    cout << "~ConcreteDecoratorB" << endl;}void ConcreteDecoratorB::Operation(){    this->_com->Operation();    //附加职责B    this->AddBehavorB();}void ConcreteDecoratorB::AddBehavorB(){    cout << "附加职责B:ConcreteDecoratorB::AddBehavorB" << endl;}ConcreteDecoratorC::ConcreteDecoratorC(Component* com):Decorator(com){}ConcreteDecoratorC::~ConcreteDecoratorC(){    cout << "~ConcreteDecoratorC" << endl;}void ConcreteDecoratorC::Operation(){    this->_com->Operation();    //附加职责C    this->AddBehavorC();}void ConcreteDecoratorC::AddBehavorC(){    cout << "附加职责C:ConcreteDecoratorC::AddBehavorC" << endl;}//**************只添加一种修饰******************DecoratorOnlyOne::DecoratorOnlyOne(Component* com):_com(com){}DecoratorOnlyOne::~DecoratorOnlyOne(){    cout << "~DecoratorOnlyOne" << endl;    delete this->_com;    this->_com = NULL;}void DecoratorOnlyOne::Operation(){    this->_com->Operation();    this->AddBehavor();}void DecoratorOnlyOne::AddBehavor(){    cout << "附加唯一职责:DecoratorOnlyOne::AddBehavor" << endl;}

main.cpp

#include "Decorator.h"#include <iostream>using namespace std;int main(){    Component* pCom = new ConcreteComponent();        //要装饰的对象    Decorator* pDec = NULL;    pDec = new ConcreteDecoratorA(pCom);            //给装饰对象附加职责A    pDec = new ConcreteDecoratorB(pDec);            //给装饰对象附加职责B    pDec = new ConcreteDecoratorC(pDec);            //给装饰对象附加职责C    pDec->Operation();    cout << "-------------------------------" << endl;    //只添加一种修饰    Component* pCom1 = new ConcreteComponent();    DecoratorOnlyOne* pDec1 = new DecoratorOnlyOne(pCom1);    pDec1->Operation();    cout << "-------------------------------" << endl;    delete pDec;    cout << "-------------------------------" << endl;    delete pDec1;    return 0;}

Decorator模式使用总结:

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

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



2 0