標籤:des style blog http 使用 os
修飾模式是一種動態地往一個對象中添加新的行為的設計模式。繼承是對現有類進行擴充,用來增加基類功能,該擴充動作是在編譯期完成;而修飾模式是對一個對象進行擴充,從而達到修飾的目的,該修飾動作是在運行期完成。下面是一個用C++編寫的關於描述一個人的樣本程式,並使用了裝飾模式。
#include <iostream>#include <string> using namespace std; // Componentclass Person {public: virtual void Describe() = 0; virtual ~Person() // 存在繼承關係,需要使用虛解構函式 {}}; // ConcreteComponentclass Student : public Person {public: Student(const string &n) : name(n) {} // 重寫虛函數 void Describe() { cout << "Name : " << name << endl; }private: string name;}; // Decoratorclass Decorator : public Person {public: Decorator(Person *p) { person = p; } void Describe() { person->Describe(); // 調用被修飾對象自身的方法 } private: Person *person; // 儲存需要被修飾的對象}; // ConcreteDecoratorclass DecoratorAge : public Decorator {public: DecoratorAge(Person *p, int a) : Decorator(p), age(a) {} void Describe() { Decorator::Describe(); cout << "Age : " << age << endl; // 修飾 }private: int age;}; // ConcreteDecoratorclass DecoratorSex : public Decorator {public: DecoratorSex(Person *p, const string &s) : Decorator(p), sex(s) {} void Describe() { Decorator::Describe(); cout << "Sex : " << sex << endl; // 修飾 }private: string sex;}; int main(){ Student s("Nestle"); cout << "無修飾:" << endl; s.Describe(); cout << endl; cout << "修飾年齡:" << endl; DecoratorAge decoratorAge(&s, 24); // 修飾器 decoratorAge.Describe(); cout << endl; cout << "修飾性別:" << endl; DecoratorSex decoratorSex(&s, "man"); // 修飾器 decoratorSex.Describe(); cout << endl; cout << "同時修飾年齡和性別:" << endl; DecoratorSex decoratorAll(&decoratorAge, "man"); // 修飾器 decoratorAll.Describe(); cout << endl; system("pause"); return 0;}
運行結果:
在這個例子中,我把人作為修飾對象,並從Person抽象類別(在裝飾模式中被稱為Component)派生出一個Student非抽象類別(在裝飾模式中被稱為ConcreteComponent)。該類中有一個描述自己的成員函數Describe,但描述的內容十分簡單,所以需要使用裝飾模式對描述內容進行修飾擴充。接下來在從Person類派生出一個Decorator類,這個類是其它修飾器類的基類,也就是說,真正對Student對象進行修飾的類必須繼承自Decorator類。在Decorator類中儲存有被修飾對象的指標,我們需要用這個指標完成被修飾對象自身的操作。我在這個例子中構建了兩個具體的修飾類(在裝飾模式中被稱為ConcreteDecorator),一個是修飾Student年齡的DecoratorAge類,另一個是修飾Student性別的DecoratorSex類。它們執行完被修飾對象原有的操作後,就執行自己的修飾行為,分別輸出年齡和性別,從而達到修飾目的。在使用者代碼中,執行個體化了一個Student對象和三個修飾器,修飾器可隨意的對Student對象進行修飾。
裝飾模式的好處在於,對一個對象功能的擴充不需要在該對象所屬類中添加代碼,只需要單獨建立一個或幾個類,用這些類來修飾對象。這樣便有效地把類的核心職責和裝飾功能分離開來。並且修飾方法非常靈活,在上面的例子中,我們可以只修飾年齡或對象或同時修飾,形成一個修飾鏈。
參考:
《大話設計模式》第6章
維基百科