## 模式定義:
? ? ? 裝飾者模式動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。
? ? ? 裝飾者和被裝飾者有相同的超累類型。
? ? ? 可以用一個或多個裝飾者包裝一個對象。
? ? ? 既然裝飾者和被裝飾者對象有相同的超累類型,所以在任何需要原始對象(被包裝的)的場合,可以用裝飾過的對象代替它。
? ? ? 裝飾者可以委托被裝飾者的行為之前與或之后,加上自己的行為,以達到特定的目的。
? ? ? 對象可以在任何時候被裝飾,所以可以在運行時動態地、不限量地用你喜歡的裝飾者來裝飾對象。
## 模式結構:

## 舉例:
? ? ? 購買咖啡時,可以在其中加入各種調料,例如:蒸奶(Steamed Milk),豆漿(Soy),摩卡(Mocha)或覆蓋奶泡。咖啡館會根據所加入的調料收取不同的費用。
? ? ? 解決方法:我們以飲料為主體,然后在運行時以調料來裝飾飲料。比方說顧客想要摩卡和奶泡深焙咖啡,那么,要做的是:拿一個深焙咖啡(DarkRoast)對象,以摩卡(Mocha)對象裝飾它,以奶泡對象裝飾它,調用cost()方法,并依賴委托將調料的價錢加上去。
## UML設計:

## 編程實現及執行結果:
~~~
#include <iostream>
#include <string>
using namespace std;
class Beverage
{
public:
Beverage(string str = "Unknow Beverage")
:description(str){}
virtual string getDescription()
{
return description;
}
virtual double cost(){return 0;}
private:
string description;
};
class CondimentDecorator : public Beverage
{
public:
string getDescription(){return "";}
};
class Espresso : public Beverage
{
public:
Espresso():Beverage("Espresso"){}
double cost()
{
return 1.99;
}
};
class HouseBlend : public Beverage
{
public:
HouseBlend():Beverage("HouseBlend Coffee"){}
double cost()
{
return 0.89;
}
};
class Mocha : public CondimentDecorator
{
public:
Mocha(Beverage* beve)
{
beverage = beve;
}
string getDescription()
{
return beverage->getDescription()+", Mocha";
}
double cost()
{
return 0.20 + beverage->cost();
}
private:
Beverage* beverage;
};
class Whip : public CondimentDecorator
{
public:
Whip(Beverage* beve)
{
beverage = beve;
}
string getDescription()
{
return beverage->getDescription()+", Whip";
}
double cost()
{
return 0.15 + beverage->cost();
}
private:
Beverage* beverage;
};
int main()
{
Beverage* pBeverage = new Espresso();
cout << pBeverage->getDescription() << " $" << pBeverage->cost() <<endl;
Beverage* pBeverage2 = new Espresso();
pBeverage2 = new Mocha(pBeverage2);
pBeverage2 = new Mocha(pBeverage2);
cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() <<endl;
pBeverage2 = new Whip(pBeverage2);
cout << pBeverage2->getDescription() << " $" << pBeverage2->cost() <<endl;
return 0;
}
~~~
執行結果:
**Espresso$1.99**
**Espresso,Mocha, Mocha $2.39**
**Espresso,Mocha, Mocha, Whip $2.54**
**請按任意鍵繼續. . .**
? ? ? 這樣就可以是不同飲料加入不同的配料,而不用改動源代碼,并且可以加入新的配料類型和飲料類型。
## 設計原則的應用:
? ? ? 設計原則5:類應該對外擴展,對修改關閉。如裝飾者模式中,我們的目標是允許類容易擴展,在不修改現有代碼的情況下,就可搭配新的行為。
? ? ? ?參考:Head First設計模式