[设计模式]Decorator装饰者模式
问题
在OO设计和开发过程中,可能会经常遇到以下情况:我们需要为一个已经定义好的类添加新的职责(操作),通常的情况我们会给定义一个新类继承自定义好的类,但是通过继承的方式解决这样的情况带来了系统的复杂性,因为继承的深度会变得很深。
而Decorator提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合。
Decorator装饰者模式动态地给一个对象添加一些额外的职责。就扩展功能而言, 它比生成子类方式更为灵活。
解析
1)Component:定义一个对象接口,可以为这个接口动态的添加职责2)Decorator:维持一个指向Component的指针,并且有一个和Component一致的接口函数。3)Component::Operation:这个接口函数由Component声明,因此Component的派生类都需要实现,可以在这个接口函数的基础上给它动态添加职责。Decorator的派生类可以为ConcreteComponent类的对象动态的添加职责,或者可以这么说:Decorator的派生类装饰ConcreteComponent类的对象。具体是这么实现的,首先初始化一个ConcreteComponent类的对象(被装饰者),采用这个对象去生成Decorator对象(装饰者),之后对Operation函数的调用则是对这个Decorator对象成员函数的多态调用。
这里实现要点是Decorator类和ConcreteComponent类都继承Component,从而两者的接口函数是一致的;其次Decorator维护了一个指向Component的指针,从而可以实现对Component::operation函数的动态调用。
小demodecorator.h
#ifndef DECORATOR_H#define DECORATOR_H// 抽象基类,定义一个对象接口,可以为这个接口动态的添加职责.class Component{public:Component(){}virtual ~Component(){}// 纯虚函数,由派生类实现virtual void Operation() = 0;};// 抽象基类,维护一个指向Component对象的指针class Decorator: public Component{public:Decorator(Component* pComponent) : m_pComponent(pComponent){}virtual ~Decorator();protected:Component* m_pComponent;};// 派生自Component,在这里表示需要给它动态添加职责的类class ConcreateComponent : public Component{public:ConcreateComponent(){}virtual ~ConcreateComponent(){}virtual void Operation();};// 派生自Decorator,这里代表为ConcreateComponent动态添加职责的类class ConcreateDecorator: public Decorator{public:ConcreateDecorator(Component* pComponent) : Decorator(pComponent){}virtual ~ConcreateDecorator(){}virtual void Operation();private:void AddedBehavior();};#endif
decorator.cpp
#include "Decorator.h"#include <iostream>Decorator::~Decorator(){delete m_pComponent;m_pComponent = NULL;}void ConcreateComponent::Operation(){std::cout << "Operation of ConcreateComponent\n";}void ConcreateDecorator::Operation(){m_pComponent->Operation();AddedBehavior();}void ConcreateDecorator::AddedBehavior(){std::cout << "AddedBehavior of ConcreateDecorator\n";}
main.cpp
#include "Decorator.h"#include <stdlib.h>int main(){// 初始化一个Component对象Component* pComponent = new ConcreateComponent();// 采用这个Component对象去初始化一个Decorator对象,// 这样就可以为这个Component对象动态添加职责Decorator* pDecorator = new ConcreateDecorator(pComponent);pDecorator->Operation();delete pDecorator;system("pause");return 0;}
Decorator模式和Composite模式有相似的结构图。
Decorator模式和Proxy模式的相似的地方在于他们都拥有一个指向其他对象的引用(指针),即通过组合的方式来为对象提供更多操作(或者Decorator模式)间接性(Proxy模式)。但是他们的区别是,Proxy模式会提供使用其代理的对象一样接口,使用代理类将其操作都委托给Proxy直接进行。这里可以简单理解为组合和委托之间的微妙的区别。
Decorator模式除了采用组合的方式取得了比采用继承方式更好的效果,Decorator没搜还给设计带来一种“即用即付”的方式来添加职责。在OO设计和开发中经常有这样一种情况:为了多态,通过父类指针指向其具体子类,但是这就带来另外一个问题,当具体子类要添加新的职责,就必须向其父类添加一个这个职责的抽象接口,否则是通过父类指针是调用不到这个方法的。这样处于高层的父类就承载了太多的特征(方法),并且继承这父类的所有子类都不可避免继承了父类的这些接口,但是可能这并不是这个具体子类所需要的。而在Decorator模式提供了一种较好的解决方法,当需要添加一个操作时候可以通过Decorator模式来解决,你可以一步步添加新的职责。