裝飾者模式指的是動態的將責任附加到對象上,想要擴展其功能,裝飾者提供有別於繼承的另外一種選擇。(參考《Head First 設計模式》)c++
我的理解:裝飾者就是一種類包類 就是在構造函數裏面,添加類做爲參數。編程
首先是基準類的頭文件,男生女生都是人 因此以人做爲基準類的聲明以下,定義了兩個純虛函數,一個是人的類別,一個是人的行爲。設計模式
//全部的基類 人
class People {
public:
virtual void personType()= 0; //人的類型
virtual void personAction() = 0; //人的活動
};
複製代碼
接下來是被裝飾者男生女生各自的類的行爲和活動bash
頭文件:函數
//被裝飾者 :男生
class Boy:public People
{
public:
//繼承人的兩個方法
void personType();
void personAction();
};
//被裝飾者:女生
class Girl:public People
{
public:
void personType();
void personAction();
};
複製代碼
各自類的實現以下:測試
//實現相關類
//男生類
void Boy::personType()
{
cout << "Boy:" << endl;
}
void Boy::personAction()
{
cout << "Boy要作的事情是" << endl;
}
//女生類
void Girl::personType()
{
cout << "Girl:" << endl;
}
void Girl::personAction()
{
cout << "Girl要作的事情是" << endl;
}
複製代碼
接下來是定義一個裝飾行爲的基類,也是繼承於人,這個是裝飾者模式必需要作的一個東西。ui
裝飾者基類的聲明spa
//裝飾者行爲基類:繼承於人
class PersonConduct:public People
{
public:
PersonConduct(People *cur_people);
void personType();
void personAction();
protected:
People *m_pPeople;
};
複製代碼
接下來是兩個吃飯和洗澡行爲的聲明設計
//裝飾行爲:吃飯
class Eat:public PersonConduct
{
public:
Eat(People *cur_people):PersonConduct(cur_people){}
void personType();
void personAction();
};
//裝飾行爲:洗澡
class Bash:public PersonConduct
{
public:
Bash(People *cur_people):PersonConduct(cur_people){}
void personType();
void personAction();
};
複製代碼
其中一個主要的點,須要構造函數中添加 基類的指針,以實現可以調用被裝飾者的動做。3d
具體裝飾行爲類實現的代碼以下:
//裝飾行爲基類
PersonConduct::PersonConduct(People *cur_people)
{
m_pPeople= cur_people;
}
void PersonConduct::personType()
{
m_pPeople->personType();
}
void PersonConduct::personAction()
{
m_pPeople->personAction();
}
//裝飾行爲:基類
void Eat::personType()
{
m_pPeople->personType();
cout << "肚子很餓" << endl;
return;
}
void Eat::personAction()
{
m_pPeople->personAction();
cout << "正在吃飯" << endl;
}
//裝飾行爲:洗澡類
void Bash::personType()
{
m_pPeople->personType();
cout << "身上有味道" << endl;
}
void Bash::personAction()
{
m_pPeople->personAction();
cout << "正在洗澡" << endl;
}
複製代碼
測試是否實現裝飾者模式的代碼以下:
People * cur_boy = new Boy();
People * cur_girl = new Girl();
PersonConduct * cur_eat_action = new Eat(cur_girl); //綁定女孩
cur_eat_action->personType();
cur_eat_action->personAction();
PersonConduct * cur_bash_action = new Bash(cur_boy);//綁定男孩
cur_bash_action->personType();
cur_bash_action->personAction();
複製代碼
執行結果:
能夠看出,完美的實現了裝飾者行爲,固然,代碼還有不完善的地方 在於沒有釋放內存最後。都要delete 指針。可是但願能夠幫助你們很好的理解裝飾者模式。
顯然 裝飾者模式的好處顯而易見,就是對象和操做分離,能夠這麼理解。吃飯不是隻有男生能吃,也不是隻有女生能吃,若是使用繼承的話,須要寫男生繼承一次,女生繼承一次,若是有不少行爲的話,顯然代碼量巨大,因此使用裝飾者模式能夠很好的解決這一問題,固然,若是當對象是單一的狀況下,使用裝飾者模式就顯得很麻煩了,由於還要寫裝飾者基類啥的,每一個行爲一個類 很麻煩,但願你們能夠活學活用最好。這也是設計模式的意義所在。
頭文件:
#include "stdafx.h"
using namespace std;
//全部的基類 人
class People {
public:
virtual void personType()= 0; //人的類型
virtual void personAction() = 0; //人的活動
};
//被裝飾者 :男生
class Boy:public People
{
public:
//繼承人的兩個方法
void personType();
void personAction();
};
//被裝飾者:女生
class Girl:public People
{
public:
void personType();
void personAction();
};
//裝飾者行爲基類:繼承於人
class PersonConduct:public People
{
public:
PersonConduct(People *cur_people);
void personType();
void personAction();
protected:
People *m_pPeople;
};
//裝飾行爲:吃飯
class Eat:public PersonConduct
{
public:
Eat(People *cur_people):PersonConduct(cur_people){}
void personType();
void personAction();
};
//裝飾行爲:洗澡
class Bash:public PersonConduct
{
public:
Bash(People *cur_people):PersonConduct(cur_people){}
void personType();
void personAction();
};
複製代碼
實現文件
// DecorationMode.cpp : 定義控制檯應用程序的入口點。
// 裝飾者模式
#include "stdafx.h"
#include "DecorationMode.h"
using namespace std;
//實現相關類
//男生類
void Boy::personType()
{
cout << "Boy:" << endl;
}
void Boy::personAction()
{
cout << "Boy要作的事情是" << endl;
}
//女生類
void Girl::personType()
{
cout << "Girl:" << endl;
}
void Girl::personAction()
{
cout << "Girl要作的事情是" << endl;
}
//裝飾行爲基類
PersonConduct::PersonConduct(People *cur_people)
{
m_pPeople= cur_people;
}
void PersonConduct::personType()
{
m_pPeople->personType();
}
void PersonConduct::personAction()
{
m_pPeople->personAction();
}
//裝飾行爲:基類
void Eat::personType()
{
m_pPeople->personType();
cout << "肚子很餓" << endl;
return;
}
void Eat::personAction()
{
m_pPeople->personAction();
cout << "正在吃飯" << endl;
}
//裝飾行爲:洗澡類
void Bash::personType()
{
m_pPeople->personType();
cout << "身上有味道" << endl;
}
void Bash::personAction()
{
m_pPeople->personAction();
cout << "正在洗澡" << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
People * cur_boy = new Boy();
People * cur_girl = new Girl();
PersonConduct * cur_eat_action = new Eat(cur_girl); //綁定女孩
cur_eat_action->personType();
cur_eat_action->personAction();
PersonConduct * cur_bash_action = new Bash(cur_boy);//綁定男孩
cur_bash_action->personType();
cur_bash_action->personAction();
return 0;
}
複製代碼