天天看點

設計模式(十五)裝飾模式 C++

意圖:動态地給一個對象添加一些額外的職責。就增加功能來說,裝飾器模式相比生成子類更為靈活。

好處就是把核心功能和裝飾功能區分開來了

(要想真正了解裝飾模式的代碼實作,首先要了解多态的實作)

裝飾模式主要包含以下角色。

  1. 抽象構件(Component)角色:定義一個抽象接口以規範準備接收附加責任的對象。
  2. 具體構件(Concrete    Component)角色:實作抽象構件,通過裝飾角色為其添加一些職責。
  3. 抽象裝飾(Decorator)角色:繼承抽象構件,并包含具體構件的執行個體,可以通過其子類擴充具體構件的功能。
  4. 具體裝飾(ConcreteDecorator)角色:實作抽象裝飾的相關方法,并給具體構件對象添加附加的責任。

    在下面的demo中,手機作為抽象構件,iPhone 和Nokia 作為具體構件,DecoratorPhone作為抽象裝飾,

DecoratorPhoneA,DecoratorPhoneB作為具體裝飾,一個代表挂件,一個代碼貼膜。

裝飾模式的技術思想是:通過多态性調用各個裝飾

#include <iostream>
#include <windows.h>
using namespace std;

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

//具體的手機類
class iPhone : public Phone
{
private:
  string m_name; //手機名稱
public:
  iPhone(string name) : m_name(name)
  {}
  ~iPhone() 
  {}
  void ShowDecorate()
  { 
    cout << m_name.c_str() << "   的裝飾" << endl; 
  }
};

//具體的手機類
class NokiaPhone : public Phone
{
private:
  string m_name;
public:
  NokiaPhone(string name) : m_name(name) 
  {}
  ~NokiaPhone()
  {}
  void ShowDecorate()
  { 
    cout << m_name.c_str() << "   的裝飾" << endl;
  }
};

//裝飾類
class DecoratorPhone : public Phone
{

public:
  DecoratorPhone(Phone *phone) : m_phone(phone) 
  {}
  virtual void ShowDecorate() 
  { 
    m_phone->ShowDecorate(); 
  }

private:
  Phone *m_phone;  //要裝飾的手機
};

//具體的裝飾類
class DecoratorPhoneA : public DecoratorPhone
{
public:
  DecoratorPhoneA(Phone *phone) : DecoratorPhone(phone)
  {}
  void ShowDecorate() 
  { 
    DecoratorPhone::ShowDecorate();
    AddDecorate(); 
  }
private:
  //增加的裝飾
  void AddDecorate() 
  { 
    cout <<   "增加挂件" << endl; 
  }
};

//具體的裝飾類
class DecoratorPhoneB : public DecoratorPhone
{
public:
  DecoratorPhoneB(Phone *phone) : DecoratorPhone(phone) {}
  void ShowDecorate() 
  {
    DecoratorPhone::ShowDecorate(); 

    AddDecorate(); 
  }
private:
  //增加的裝飾
  void AddDecorate() 
  { 
    cout << "螢幕貼膜" << endl;
  } 
};

int main()
{
  Phone *pNokia = new NokiaPhone("Nokia6300");
  Phone *pPendant = new DecoratorPhoneA(pNokia); //裝飾,增加挂件
  Phone *pPatch = new DecoratorPhoneB(pPendant);    //裝飾,螢幕貼膜
  pPatch->ShowDecorate();

  delete pPendant;
  delete pPatch;
  delete pNokia;


  system("pause");
  return 0;
}