動態地給一個對象添加一些額外的職責。就增加功能來說, D e c o r a t o r模式相比生成子類更爲靈活。
2. 動機
有時我們希望給某個對象而不是整個類添加一些功能。例如,一個圖形用戶界面工具箱允許你對任意一個用戶界面組件添加一些特性,例如邊框,或是一些行爲,例如窗口滾動。使用繼承機制是添加功能的一種有效途徑,從其他類繼承過來的邊框特性可以被多個子類的實例所使用。但這種方法不夠靈活,因爲邊框的選擇是靜態的,用戶不能控制對組件加邊框的方式和時機。
3.舉例
C++代碼:
#ifndef DECORATOR_H
#define DECORATOR_H
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
class CMeal{
private:
string m_strName;
public:
CMeal(){}
CMeal(string temp): m_strName(temp){}
virtual void GetName(){
cout<<m_strName<<" ";
}
};
class CNoodle : public CMeal{
public:
CNoodle(): CMeal("noodle"){}
};
class CDumpling : public CMeal{
public:
CDumpling() : CMeal("dumpling"){}
};
class CDressing : public CMeal{
private:
CMeal* meal;
public:
CDressing(CMeal* temp){meal = temp;}
virtual void GetName(){
meal->GetName();
}
};
class CVinegar : public CDressing{
public:
CVinegar(CMeal* temp): CDressing(temp){}
virtual void GetName(){
CDressing::GetName();
cout<<"with vinegar"<<" ";
}
};
class COil : public CDressing{
public:
COil(CMeal* temp): CDressing(temp){}
virtual void GetName(){
CDressing::GetName();
cout<<"with oil"<<" ";
}
};
#endif
#include <iostream>
#include "decorator.h"
int main(){
CMeal* firstMeal=new CVinegar(new COil(new CNoodle));
firstMeal->GetName();
cout<<endl;
CMeal* secondMeal=new CVinegar(new CDumpling);
secondMeal->GetName();
cout<<endl;
return 0;
}