裝飾著模式
裝飾者模式動態地將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。
案例
有這樣乙個專案,做乙個餐廳訂餐系統。起初的**結構是這樣的。前面有很多beverage的繼承類,現在遇到的問題是牛奶的價錢**了,那麼所有相關的類,我們都要進行調整,比如milk,sugarandmilk類,這種類還有很多,我們需要逐個去修改類中的方法——開發人員每次都做這種事情,要瘋了!所以我們要改變現有的結構。以下的圖都是簡圖,實際的圖,可沒有這麼簡單。
設計問題:
1》類數量**,有很多類,難以維護;
2》整個設計呆板;
3》基類加入的新功能無法使用於子類;
後來經過小組研究決定,我們決定把基礎類抽出來,比如,我們把咖啡做成乙個單獨的類,其他的咖啡,比如牛奶咖啡,甜味咖啡,我們只對材料單獨包裝成乙個類。
經過改良的設計:
詳解:
1》對於飲品,我們直接繼承beverage類,直接把**寫進飲品類裡面;
2》而對於一些需要新增調味品的特殊飲品,我們做累加操作。比如,我想要杯奶咖啡,則 總價=咖啡價+奶價
3》這樣不同的飲料就很容易知道它的**。
**:
<?php
abstract class beverage
// 被裝飾者類
class coffee extends beverage
public function cost()
}// 以下三個類是裝飾者相關類
class condimentdecorator extends beverage
public function cost() }
class milk extends condimentdecoratorelse
exit('failure');
}
public function cost() }
class sugar extends condimentdecoratorelse
}public function cost()}
// test case
//1.拿杯咖啡
$coffee = new coffee();
//2.加點牛奶
$coffee = new milk($coffee);
//3.加點糖
$coffee = new sugar($coffee);
printf("coffee total:%0.2f元\n",$coffee->cost());
總結:1.裝飾者(milk)和被裝飾者(coffee)必須是一樣的型別。目的是裝飾者必須取代被裝飾者。
2.新增行為:當裝飾者和元件組合時,就是在加入新的行為。
題外話:
1.利用繼承設計子類行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。打個比方,老子想學點功夫,看你小子會太極拳,老子只需要繼承你一下 ,老子也就會太極拳了——呵呵,這時老子就變成你兒子了,看來繼承是要付出代價的。
2.組合,我們可以擴充套件物件的行為,在執行時動態地進行擴充套件。利用組合我們可以隨時把我們當時設計超類時沒有想到的方法加入到物件中,而不用改變現有的**。打個比方,老子現在沒有內力,吸功**,把和尚,尼姑,道士的內力(行為物件)都吸過來,那在搏鬥(執行時)中,老子可以隨時都能使用不同的內力,但也不能胡亂吸內力,否則你就要走火入魔了!
3.類應該對擴充套件開放,對修改關閉。如果我們每個部分都用裝飾者模式進行設計,那麼對於整個框架來說有點浪費,而且你也加大了**的難度。那什麼時候使用這種模式呢?我們一般用於經常改變的地方。那我們又怎麼知道哪些是經常改變的地方呢?這個就需要我們的經驗和你對所處行業的了解。建議大家平時多看點例子。
4.裝飾模式為設計注入彈性,但同時會在設計中加入大量的小類,這偶爾會導致別人不容易了解這種設計。
5.在使用裝飾者模式的時候,對插入的的裝飾者要特別小心。因為裝飾者模式依賴某種特定的型別(beverage)。
裝飾著模式
package com.henu.decorator 漢堡基類 author rock public abstract class humburger public abstract double getprice package com.henu.decorator 雞腿堡類 被裝飾者的初始狀態,...
裝飾著模式(Decorator Pattern)
裝飾者模式是動態的將責任附加到物件上,若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。簡單的說,裝飾者模式由三部分組成,分別是基礎抽象類,可以被裝飾者包裝的類 裝飾者類,後兩種類均是基礎抽象類的子類,但是裡面的方法對於基礎類有更多的擴充套件,最終使用,均是使用的基礎類進行操作,因此,無論怎麼...
設計模式 裝飾著模式
裝飾者模式的應用場景覆蓋,擴充套件,is a,前置,寫法 裝飾者模式 decorator pattern 是指在不改變原有物件的基礎之上,將功能附加到物件上,提供了比繼承更有彈性的替代方案 擴充套件原有物件的功能 裝飾者在 程式中適用於以下場景 1 用於擴充套件乙個類的功能或給乙個類新增附加職責。2...