標籤:atp idt 修改 自己的 ace ima http sys names
裝飾器模式是比較常用的一種設計模式,Python中就內建了對於裝飾器的支援。
具體來說,裝飾器模式是用來給對象增加某些特性或者對被裝飾對象進行某些修改。
如所示,需要被裝飾的對象在最上方,它自身可以有自己的執行個體,一般通過抽象類別來實現(Java中也可以通過介面實現)。
右側中間是一個裝飾器類或者介面,其實內容與原對象基本一致,不過我們自訂的裝飾器一般會繼承這個裝飾器基類。
最下層就是具體的裝飾器了,可以看到,具體裝飾器類中需要包含被裝飾對象成員(也就是說,裝飾器需要和被裝飾對象有同樣的子類),然後增加一些額外的操作。
下面的代碼是一個買煎餅的例子,如我們生活中所見,可以選基礎煎餅(雞蛋煎餅,肉煎餅等),然後再額外加別的東西:
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 class Pancake//基類 6 { 7 public: 8 string description = "Basic Pancake"; 9 virtual string getDescription(){ return description; }10 virtual double cost() = 0;11 };12 13 class CondimentDecorator :public Pancake//裝飾器基類14 {15 public:16 string getDescrition();17 };18 19 class MeatPancake :public Pancake//肉煎餅20 {21 public:22 MeatPancake(){ description = "MeatPancake"; }23 double cost(){ return 6; }24 };25 class EggPancake :public Pancake//雞蛋煎餅26 {27 public:28 EggPancake(){ description = "EggPancake"; }29 double cost(){ return 5; }30 };31 32 class Egg :public CondimentDecorator//額外加雞蛋33 {34 public:35 Pancake* base;36 string getDescription(){ return base->getDescription() + ", Egg"; }37 Egg(Pancake* d){ base = d; }38 double cost(){ return base->cost() + 1.5; }39 };40 class Potato :public CondimentDecorator//額外加馬鈴薯41 {42 public:43 Pancake* base;44 string getDescription(){ return base->getDescription() + ", Potato"; }45 Potato(Pancake* d){ base = d; }46 double cost(){ return base->cost() + 1; }47 };48 class Bacon :public CondimentDecorator//額外加培根49 {50 public:51 Pancake* base;52 string getDescription(){ return base->getDescription() + ", Bacon"; }53 Bacon(Pancake* d){ base = d; }54 double cost(){ return base->cost() + 2; }55 };56 57 58 int main()59 {60 Pancake* pan = new EggPancake();61 pan = &Potato(pan);62 pan = &Bacon(pan);63 cout << pan->getDescription() << " $ : " << pan->cost() << endl;64 system("pause");65 return 0;66 }
可以看到,Pancake是煎餅的基類,這個基類因為定義了純虛函數cost,所以不能被執行個體化。同樣,裝飾器基類CondimentDecorator也不能被執行個體化。
後面,EggPancake和MeatPancake是Pancake的衍生類別,是實際存在的類。
Egg、Bacon和Potato就是我們定義的裝飾器對象,其中包含了Pancake的指標,可以對Pancake及其衍生類別進行操作。
運行代碼的結果如下:
即我們選擇了一個雞蛋煎餅,然後額外加了馬鈴薯和培根,一共5+1+2=8塊。
裝飾器模式的優點:
1、可以輕鬆對已存在的對象進行修改和封裝,在被裝飾者的前面或者後面添加自己的行為,而無需修改原對象。
2、可以動態、不限量地進行裝飾,可以更靈活地擴充功能。
相對地,裝飾器模式有很明顯的缺點:
1、會加入大量的小類,即使只添加一個功能,也要額外建立一個類,使得程式更複雜。
2、增加代碼複雜度,使用裝飾器模式不但需要執行個體化組件,還要把組件封裝到裝飾者中。
裝飾器模式(Decorator) C++