首页 > 代码库 > 装饰模式

装饰模式

      装饰模式,是在不改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。是为已有功能动态添加更多功能的一种方式。当系统需要新功能的时候,把每个要装饰的功能放在单独的类中,并让这个类包装它所装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择的、按顺序地使用装饰功能包装对象。

装饰模式适用的场景:
  1. 需要动态的给一个对象添加功能,这些功能还可以动态的撤销。
  2. 需要增加一些基本功能的排列组合而产生的非常大量的功能。或者因排列的顺序不同产生不同的效果的时候。
装饰模式的优点:
  1. Deorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
  2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造床很多不同行为的组合。
  3. 更重要的是,装饰模式把类中的装饰功能从类中搬移去除,这样可以简化原有的类,有效的把类的核心职责和装饰功能区分开了,而且可以去除相关类中重复的装饰逻辑。
装饰模式的缺点:
  1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。
  2. 装饰模式会导致设计中出现很多的小类,如果过度使用,会使程序变得很复杂。


C++代码实现:

Decorator.h
#include "stdafx.h"
#include <iostream>
#include <memory>
using namespace std;

class Component
{
public:
        virtual void Operation() = 0;
};


class ConcreteComponent :public Component
{
        virtual void Operation()
       {
              cout << "具体对象的操作!" << endl;
       }
};

class Decorator :public Component
{
private:
        shared_ptr<Component > _pComponent;
protected:
        shared_ptr<Component > GetComponent()
       {
               return _pComponent;
       }
       
public:
        void SetComponent( shared_ptr<Component > pComponent )
       {
              _pComponent = pComponent;
       }


        virtual void Operation()
       {
               if (_pComponent != NULL)
              {
                     _pComponent->Operation();
              }
       }
};

class ConcreteDecorator1 :public Decorator
{
public:
        virtual void Operation()
       {
               //首先运行原Component的方法,再运行本类的方法
              GetComponent()->Operation();
              cout << "具体装饰对象ConcreteDecorator1" << endl;
       }

};

class ConcreteDecorator2 :public Decorator
{
public:
        virtual void Operation()
       {
              GetComponent()->Operation();
              cout << "具体装饰对象ConcreteDecorator2" << endl;
       }

};
DecoratorMethod.cpp
// DecorateMethod.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Decorator.h"


int _tmain (int argc , _TCHAR * argv [])
{

        //装饰的方法是,首先建造ConcreteComponent对象,
        //然后建造ConcreteDecorator1来装饰ConcreteComponent
        //借助智能指针来实现.
        //最后执行的是最后的装饰类的Operation
        shared_ptr<ConcreteComponent > pConcreteComponent(new ConcreteComponent);

        shared_ptr<ConcreteDecorator1 > pConcreteDecorator1(new ConcreteDecorator1);
       pConcreteDecorator1->SetComponent(pConcreteComponent);
       pConcreteDecorator1->Operation();
       std::cout << std::endl;

        shared_ptr<ConcreteDecorator2 > pConcreteDecorator2(new ConcreteDecorator2);
       pConcreteDecorator2->SetComponent(pConcreteDecorator1);

       pConcreteDecorator2->Operation();
       getchar();
        return 0;
}