class Bervage { description; getDescription(); cost(); };
每種不一樣的飲料都是Bervage的一個派生類,因爲調料多種多樣,致使派生類「爆炸」ios
class Bervage { description; milk; soy; mocha; whip; getDescription(); cost(); hasMilk(); hasSoy(); hasMocha(); hasWhip(); setMilk(); setSoy(); setMocha(); setWhip(); };
基類中將全部調料做爲元素,基類cost()計算添加的調料的價格函數
派生類中cost()中 計算不一樣的飲料的價格加上基類cost計算出來的調料的價格,做爲某個單品的總價格網站
存在的問題:spa
1)調料價格的改變須要更新現有代碼設計
2)一旦出現新的調料,須要改變基類代碼指針
3)某些單品與調料並不搭配,這些單品的類中依然存在調料orm
4)雙倍或多倍調料問題對象
裝飾者模式將以飲料爲主體,在運行時以調料來裝飾飲料。例如若是顧客要摩卡和奶茶深焙咖啡,須要作的是:blog
1)一個深焙咖啡對象繼承
2)以摩卡對象裝飾它
3)以奶茶對象裝飾它
4)調用cost方法,並依賴委託將調料的價格加上去
如下轉自:http://www.jellythink.com/archives/171
類封裝了一個對象的核心操做,而這些操做就是客戶使用該類時都會去調用的操做
有一些非核心的操做,可能會使用,也可能不會使用;如今該怎麼辦呢?
1)將非核心的操做所有放到類中,這樣,一個類就包含了不少核心的操做和一些看似有關,可是又無關的操做;
這就會使核心類發生「爆炸」的現象,從而使核心類失去了必定的價值,也使使用核心類的客戶在覈心操做和非核心操做中掙扎;
2)使用繼承來擴展核心類,須要使用核心類時,直接創建核心類對象;
當須要使用核心類擴展類時,就創建核心類擴展類對象;這樣貌似是一種頗有效的方法
可是因爲繼承爲類型引入的靜態特質,使得這種擴展方式缺少靈活性,同時隨着擴展功能的增多,子類也會增多,各類子類的組合,就會致使類的膨脹
裝飾模式可以實現從對象的外部,動態的給對象添加功能 。
一般給對象添加功能,要麼直接修改對象添加相應的功能,要麼經過派生類來擴展。
在面向對象的設計中,應儘可能使用對象組合,而不是對象繼承來擴展和複用功能。
裝飾者模式就是經過對象組合的方式,靈活的給對象添加所須要的功能。
裝飾模式是經過把複雜的功能簡單化,分散化,而後在運行期間,根據須要來動態組合的這樣一個模式。它使得咱們能夠給某個對象而不是整個類添加一些功能
Component:定義對象接口,能夠給這些對象動態地添加職責(對象基類)
ConcreteComponent:定義一個具體的Component,繼承自Component,重寫了Component類的虛函數(對象派生類)
Decorator:維持一個指向Component對象的指針,該指針指向須要被裝飾的對象
同時定義一個與Component接口一致的接口,該接口將調用其維護的指針的operation操做
ConcreteDecorator:向組件添加職責,該類的operation操做將先執行添加操做,再執行Decorator::operation()
對於ConcreteDecotator,能夠繼續添加裝飾
/* ** FileName : DecoratorPatternDemo ** Author : Jelly Young ** Date : 2013/12/19 ** Description : More information, please go to http://www.jellythink.com */ #include <iostream> using namespace std; class Component { public: virtual void Operation() = 0; }; class ConcreteComponent : public Component { public: void Operation() { cout<<"I am no decoratored ConcreteComponent"<<endl; } }; class Decorator : public Component { public: Decorator(Component *pComponent) : m_pComponentObj(pComponent) {} void Operation() { if (m_pComponentObj != NULL) { m_pComponentObj->Operation(); } } protected: Component *m_pComponentObj; }; class ConcreteDecoratorA : public Decorator { public: ConcreteDecoratorA(Component *pDecorator) : Decorator(pDecorator){} void Operation() { AddedBehavior(); Decorator::Operation(); } void AddedBehavior() { cout<<"This is added behavior A."<<endl; } }; class ConcreteDecoratorB : public Decorator { public: ConcreteDecoratorB(Component *pDecorator) : Decorator(pDecorator){} void Operation() { AddedBehavior(); Decorator::Operation(); } void AddedBehavior() { cout<<"This is added behavior B."<<endl; } }; int main() { Component *pComponentObj = new ConcreteComponent(); Decorator *pDecoratorAOjb = new ConcreteDecoratorA(pComponentObj); pDecoratorAOjb->Operation(); cout<<"============================================="<<endl; Decorator *pDecoratorBOjb = new ConcreteDecoratorB(pComponentObj); pDecoratorBOjb->Operation(); cout<<"============================================="<<endl; Decorator *pDecoratorBAOjb = new ConcreteDecoratorB(pDecoratorAOjb); pDecoratorBAOjb->Operation(); cout<<"============================================="<<endl; delete pDecoratorBAOjb; pDecoratorBAOjb = NULL; delete pDecoratorBOjb; pDecoratorBOjb = NULL; delete pDecoratorAOjb; pDecoratorAOjb = NULL; delete pComponentObj; pComponentObj = NULL; }