裝飾者模式
1. 功能
動態將功能附加到對象上,對於功能的擴充,比繼承更靈活,有彈性。
2. 結構圖
3. 舉例說明
情境:某咖啡廳做了一個點咖啡系統,不同口味的咖啡價格不同,但某天,做咖啡的原料,例如牛奶、糖的價格上漲了,此時,如果按照繼承的方式來設計各個咖啡類,那麼咖啡的價格計算就比較麻煩了,需要修改每個類的價格,然後重新計算。這種設計方式,類的數量會爆炸式增長,而且不易維護,基類的新功能無法用於子類。
解決方案:裝飾者模式
1). 設計類圖如下:
2) 說明:
對於各種飲品直接繼承Beverage類,將價格寫入Beverage類中,當需要某種特定口味的咖啡時,價格計算(牛奶咖啡=咖啡+牛奶),當某種輔料的價格變化是只需修改特定輔料價格即可,而且各種口味的咖啡價格也非常容易計算。
3)代碼實現:
<?phpabstract class Beverage{ public $_name; abstract public function Cost();}// 被裝飾者類class Coffee extends Beverage{ public function __construct(){ $this->_name = 'Coffee'; } public function Cost(){ return 1.00; } }// 裝飾類class CondimentDecorator extends Beverage{ public function __construct(){ $this->_name = 'Condiment'; } public function Cost(){ return 0.1; } }//具體裝飾者類class Milk extends CondimentDecorator{ public $_beverage; public function __construct($beverage){ $this->_name = 'Milk'; if($beverage instanceof Beverage){ $this->_beverage = $beverage; }else{ exit('Failure'); } } public function Cost(){ return $this->_beverage->Cost() + 0.2; } } class Sugar extends CondimentDecorator{ public $_beverage; public function __construct($beverage){ $this->_name = 'Sugar'; if($beverage instanceof Beverage){ $this->_beverage = $beverage; }else{ exit('Failure'); } } public function Cost(){ return $this->_beverage->Cost() + 0.2; }} // Test Case//1.拿杯咖啡$coffee = new Coffee(); //2. 原咖啡基礎上加點牛奶$coffee = new Milk($coffee); //3.再加點糖$coffee = new Sugar($coffee); printf("Coffee Total:%0.2f元\n",$coffee->Cost());