1. 概述ios
若你從事過面向對象開發,實現給一個類或對象增長行爲,使用繼承機制,這是全部面嚮對象語言的一個基本特性。若是已經存在的一個類缺乏某些方法,或者需要給方法添加更多的功能(魅力),你也許會僅僅繼承這個類來產生一個新類—這創建在額外的代碼上。ui
經過繼承一個現有類可使得子類在擁有自身方法的同時還擁有父類的方法。可是這種方法是靜態的,用戶不能控制增長行爲的方式和時機。若是 你但願改變一個已經初始化的對象的行爲,你怎麼辦?或者,你但願繼承許多類的行爲,改怎麼辦?前一個,只能在於運行時完成,後者顯然時可能的,可是可能會致使產生大量的不一樣的類—可怕的事情。this
2. 問題spa
你如何組織你的代碼使其能夠容易的添加基本的或者一些不多用到的 特性,而不是直接不額外的代碼寫在你的類的內部?.net
3. 解決方案3d
裝飾器模式: 動態地給一個對象添加一些額外的職責或者行爲。就增長功能來講, Decorator模式相比生成子類更爲靈活。code
裝飾器模式提供了改變子類的靈活方案。裝飾器模式在沒必要改變原類文件和使用繼承的狀況下,動態的擴展一個對象的功能。它是經過建立一個包裝對象,也就是裝飾來包裹真實的對象。對象
當用於一組子類時,裝飾器模式更加有用。若是你擁有一族子類(從一個父類派生而來),你須要在與子類獨立使用狀況下添加額外的特性,你可使用裝飾器模式,以免代碼重複和具體子類數量的增長。blog
4. 適用性繼承
如下狀況使用Decorator模式
1)• 在不影響其餘對象的狀況下,以動態、透明的方式給單個對象添加職責。
2)• 處理那些能夠撤消的職責。
3)• 當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,
爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。
另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。
5. 結構
UML圖以下:
Component是定義一個對象接口,能夠給這些對象動態地添加職責。
ConcreteComponent是定義了一個具體的對象,也能夠給這個對象添加一些職責。
Decorator,裝飾抽象類,繼承了Component,從外類來擴展Component類的功能,但對於Component來講,是無需知道Decorator的存在的。
至於ConcreteDecorator就是具體的裝飾對象,起到給Component添加職責的功能。
要善於變通,若是隻有一個ConcreteComponent類而沒有抽象的Component類,那麼Decorator類能夠是ConcreteComponent的一個子類。
一樣道理,若是隻有一個ConcreteDecorator類,那麼就沒有必要創建一個單獨的Decorator類,而能夠把Decorator和ConcreteDecorator的責任合併成一個類。
新加入的東西僅僅是爲了知足一些只在某種特定狀況下才會執行的特殊行爲 的須要。而裝飾模式卻提供了一個很是好的解決方案,它把每一個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象,所以,當須要執行特殊行爲 時,客戶代碼就能夠在運行時根據須要有選擇地、按順序地使用裝飾功能包裝對象了。
代碼以下:
Decorator.h
#ifndef _DECORATOR_H_
#define _DECORATOR_H_ //Component抽象類,定義該類對象的接口 class Component { public: virtual ~Component(); virtual void Operation()=0; protected: Component(); }; //ConcreteDecorator:具體的Component對象,能夠給該對象動態 添加職責 class ConcreteComponent:public Component { public: ConcreteComponent(); ~ConcreteComponent(); virtual void Operation(); }; //Decorator:裝飾抽象類,繼承自Component class Decorator:public Component { public: Decorator(Component* com); void SetComponent(Component* com); virtual ~Decorator(); virtual void Operation(); protected: Component* _com; }; //ConcreteDecorator就是具體的裝飾對象之一,起到給Component添加職責的功能 class ConcreteDecoratorA:public Decorator { public: ConcreteDecoratorA(Component* com); ~ConcreteDecoratorA(); virtual void Operation(); void AddBehavorA(); }; //ConcreteDecorator就是具體的裝飾對象之二,起到給Component添加職責的功能 class ConcreteDecoratorB:public Decorator { public: ConcreteDecoratorB(Component* com); ~ConcreteDecoratorB(); virtual void Operation(); void AddBehavorB(); }; //ConcreteDecorator就是具體的裝飾對象之三,起到給Component添加職責的功能 class ConcreteDecoratorC:public Decorator { public: ConcreteDecoratorC(Component* com); ~ConcreteDecoratorC(); virtual void Operation(); void AddBehavorC(); }; //ConcreteDecorator就是具體的裝飾對象之四,起到給Component添加職責的功能 class ConcreteDecoratorD:public Decorator { public: ConcreteDecoratorD(Component* com); ~ConcreteDecoratorD(); virtual void Operation(); void AddBehavorD(); }; //只添加一種裝飾,則不用抽象出裝飾基類 class DecoratorOnlyOne:public Component { public: DecoratorOnlyOne(Component* com); ~DecoratorOnlyOne(); virtual void Operation(); void AddBehavor(); private: Component* _com; }; //若是隻有一個ConcreteComponent類而沒有抽象的Component類,那麼Decorator類能夠是ConcreteComponent的一個子類。 //略 #endif
Decorator.cpp
#include "Decorator.h" #include <iostream> using namespace std; Component::Component() {} Component::~Component() { cout << "~Component" << endl; } ConcreteComponent::ConcreteComponent() {} ConcreteComponent::~ConcreteComponent() { cout << "~ConcreteComponent" << endl; } void ConcreteComponent::Operation() { cout << "原職責:ConcreteComponent::Operation" << endl; } Decorator::Decorator(Component* com) { this->_com = com; } void Decorator::SetComponent(Component* com) { this->_com = com; } Decorator::~Decorator() { cout << "~Decorator" << endl; delete this->_com; this->_com = NULL; } void Decorator::Operation() {} ConcreteDecoratorA::ConcreteDecoratorA(Component* com):Decorator(com) {} ConcreteDecoratorA::~ConcreteDecoratorA() { cout << "~ConcreteDecoratorA" << endl; } void ConcreteDecoratorA::Operation() { this->_com->Operation(); //附加職責A this->AddBehavorA(); } void ConcreteDecoratorA::AddBehavorA() { cout << "附加職責A:ConcreteDecoratorA::AddBehavorA" << endl; } ConcreteDecoratorB::ConcreteDecoratorB(Component* com):Decorator(com) {} ConcreteDecoratorB::~ConcreteDecoratorB() { cout << "~ConcreteDecoratorB" << endl; } void ConcreteDecoratorB::Operation() { this->_com->Operation(); //附加職責B this->AddBehavorB(); } void ConcreteDecoratorB::AddBehavorB() { cout << "附加職責B:ConcreteDecoratorB::AddBehavorB" << endl; } ConcreteDecoratorC::ConcreteDecoratorC(Component* com):Decorator(com) {} ConcreteDecoratorC::~ConcreteDecoratorC() { cout << "~ConcreteDecoratorC" << endl; } void ConcreteDecoratorC::Operation() { this->_com->Operation(); //附加職責C this->AddBehavorC(); } void ConcreteDecoratorC::AddBehavorC() { cout << "附加職責C:ConcreteDecoratorC::AddBehavorC" << endl; } ConcreteDecoratorD::ConcreteDecoratorD(Component* com):Decorator(com) {} ConcreteDecoratorD::~ConcreteDecoratorD() { cout << "~ConcreteDecoratorD" << endl; } void ConcreteDecoratorD::Operation() { this->_com->Operation(); //附加職責D this->AddBehavorD(); } void ConcreteDecoratorD::AddBehavorD() { cout << "附加職責D:ConcreteDecoratorD::AddBehavorD" << endl; } //**************只添加一種修飾****************** DecoratorOnlyOne::DecoratorOnlyOne(Component* com):_com(com) { } DecoratorOnlyOne::~DecoratorOnlyOne() { cout << "~DecoratorOnlyOne" << endl; delete this->_com; this->_com = NULL; } void DecoratorOnlyOne::Operation() { this->_com->Operation(); this->AddBehavor(); } void DecoratorOnlyOne::AddBehavor() { cout << "附加惟一職責:DecoratorOnlyOne::AddBehavor" << endl; }
main.cpp
#include "Decorator.h" #include <iostream> using namespace std; int main() { Component* pCom = new ConcreteComponent(); //要裝飾的對象 Decorator* pDec = NULL; pDec = new ConcreteDecoratorA(pCom); //給裝飾對象附加職責A pDec = new ConcreteDecoratorB(pDec); //給裝飾對象附加職責B pDec = new ConcreteDecoratorC(pDec); //給裝飾對象附加職責C pDec = new ConcreteDecoratorD(pDec); //給裝飾對象附加職責D pDec->Operation(); cout << "-------------------------------" << endl; //只添加一種修飾 Component* pCom1 = new ConcreteComponent(); DecoratorOnlyOne* pDec1 = new DecoratorOnlyOne(pCom1); pDec1->Operation(); cout << "-------------------------------" << endl; delete pDec; cout << "-------------------------------" << endl; delete pDec1; return 0; }
總結
通常,當系統須要新功能的時候,是向舊的類中添加新的代碼。這些新加的代碼一般裝飾了原有類的核心職責或主要行爲,但這種作法的問題在於,它們在主類中加入了新的字段,新的方法和新的邏輯,從而增長了主類的複雜度,而且新加入的東西僅僅是爲了知足一些只在某種特定狀況下才會執行的特殊行爲的須要。而裝飾模式卻提供了一個很是好的解決方案,它把每一個要裝飾的功能放在單獨的類中,並讓這個類包裝它所要裝飾的對象,所以,當須要執行特殊行爲時,客戶代碼就能夠在運行時根據須要有選擇地、按順序地使用裝飾功能包裝對象了。
那麼裝飾模式的優勢有:1 把類中的裝飾功能從類中搬移去除,這樣能夠簡化原有的類,這樣作更大的好處就是有效地把類的核心職責和裝飾功能區分開了。並且能夠去除相關類中重複的裝飾邏輯。