天天看点

c++设计模式----Decorator(装饰)

装饰模式:

            首先我回忆一下桥接模式:桥接模式的意图是让抽象和实现分离开来,让两者独立的变化。而装饰模式的重点在于装饰,一个功能用一个简单的类来表示装饰的职责,这个简单的类与他要装饰的对象的类提供一致的接口,这样保持了接口的一致性。我们要仔细分析桥接模式与装饰模式两者具体的实现而把他们区分开来。要熟悉各种设计模式是一个长时间的过程,不是一下子就能体会的,要多多去揣摩这样的实现的意图是什么,仔细品味,就会发现容易混淆的模式也很容易区分开来。

           装饰模式提供了更加灵活的向对象添加职责的方式。可以用添加和分离的方法,用装饰在运行时刻增加和删除职责。装饰模式提供了一种“即用即付”的方法来添加职责。它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用装饰类给它逐渐地添加功能。可以从简单的部件组合出复杂的功能。

意图:

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

适用性:

           在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

           处理那些可以撤消的职责。

           当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

#include <iostream>
using namespace std;

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

class concreteComponent :public Component
{
public:
  void Operation()
  {
    cout << "this is a concreteComponent, not a decorator." << endl;
  }
};

class Decorator :public Component
{
public:
  Decorator(Component *p) : p_Component(p) {}
  void Operation()
  {
    if (p_Component != NULL)
    {
      p_Component->Operation();
    }
  }

private:
  Component *p_Component;
};

class DecoratorA :public Decorator
{
public:
  DecoratorA(Component *p) : Decorator(p) {}
  void Operation()
  {
    add_status();
    Decorator::Operation();
  }

  void add_status()
  {
    cout << "I am DecoratorA. " << endl;
  }
};

class DecoratorB :public Decorator
{
public:
  DecoratorB(Component *p) : Decorator(p) {}
  void Operation()
  {
    add_bahavior();
    Decorator::Operation();
  }

  void add_bahavior()
  {
    cout << "I am DecoratorB. " << endl;
  }
};

int main(int argc, char*argv[])
{
  Component* object = new concreteComponent();
  Decorator *a = new DecoratorA(object);
  a->Operation();
  cout << "-----------------------------------------------------" << endl;

  Decorator *b = new DecoratorB(object);
  b->Operation();
  cout << "------------------------------------------------------" << endl;

  Decorator *ab = new DecoratorB(a);
  ab->Operation();
}      

我们来看一个实际的具体的例子:

          比如有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。一种灵活的设计方式是,将手机嵌入到另一对象中,由这个对象完成特性的添加,我们称这个嵌入的对象为装饰。这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。

#include <iostream>
#include <string>
using namespace std;

//公共抽象类
class Phone
{
public:
  virtual void ShowDecorate() {}
};

//具体的手机类
class iPhone : public Phone
{
public:
  iPhone(string s) :name(s){}

  void ShowDecorate()
  {
    cout << "I am " << name << endl;
  }

private:
  string name;//手机名
};

//装饰类
class DecoratorPhone : public Phone
{
private:
  Phone *m_phone;  //要装饰的手机

public:
  DecoratorPhone(Phone *phone) : m_phone(phone) {}

  virtual void ShowDecorate() { m_phone->ShowDecorate(); }
};
//具体的装饰类
class DecoratorPhoneA : public DecoratorPhone
{
public:
  DecoratorPhoneA(Phone *phone) : DecoratorPhone(phone) {}

  void ShowDecorate()
  {
    DecoratorPhone::ShowDecorate();
    AddDecorate();
  }

private:
  void AddDecorate() { cout << "升级为Plus" << endl; } //增加的装饰
};

//具体的装饰类
class DecoratorPhoneB : public DecoratorPhone
{
public:
  DecoratorPhoneB(Phone *phone) : DecoratorPhone(phone) {}

  void ShowDecorate()
  {
    DecoratorPhone::ShowDecorate(); 
    AddDecorate();
  }

private:
  void AddDecorate() { cout << "升级为6s" << endl; } //增加的装饰
};

int main()
{
  Phone *iphone = new iPhone("iPhone6");
  Phone *plus = new DecoratorPhoneA(iphone); 

  Phone *s_6 = new DecoratorPhoneB(plus);    
  s_6->ShowDecorate();
  delete plus;
  delete s_6;
  delete iphone;
  return 0;
}      

继续阅读