PHP設計模式之裝飾者模式

2021-07-25 02:39:25 字數 3383 閱讀 7175

php設計模式之裝飾者模式 介紹

裝飾者模式動態地將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。

思維導圖

有這樣乙個專案,做乙個餐廳訂餐系統。起初的**結構是這樣的。前面有很多beverage的繼承類,現在遇到的問題是牛奶的價錢**了,那麼所有相關的類,我們都要進行調整,比如milk,sugarandmilk類,這種類還有很多,我們需要逐個去修改類中的方法——開發人員每次都做這種事情,要瘋了!所以我們要改變現有的結構。以下的圖都是簡圖,實際的圖,可沒有這麼簡單。

設計問題:

1》類數量**,有很多類,難以維護;

2》整個設計呆板;

3》基類加入的新功能無法使用於子類;

復用類方法的方式很多,比如繼承,組合,委託。為什麼老是習慣用繼承呢?我看zend framework也有這種習慣!每次找對應方法,一直往上翻。——題外話!!!!

後來經過小組研究決定,我們決定把基礎類抽出來,比如,我們把咖啡做成乙個單獨的類,其他的咖啡,比如牛奶咖啡,甜味咖啡,我們只對材料單獨包裝成乙個類。

經過改良的設計:

詳解1》對於飲品,我們直接繼承beverage類,直接把**寫進飲品類裡面;

2》而對於一些需要新增調味品的特殊飲品,我們做累加操作。比如,我想要杯奶咖啡,則 總價=咖啡價+奶價

3》這樣不同的飲料就很容易知道它的**。

**<?php

abstractclassbeverage

// 被裝飾者類

classcoffeeextendsbeverage

publicfunctioncost()

}

// 以下三個類是裝飾者相關類

classcondimentdecoratorextendsbeverage

publicfunctioncost()

}

classmilkextendscondimentdecoratorelse

exit('failure');

}

publicfunctioncost()

}

classsugarextendscondimentdecoratorelse

}

publicfunctioncost()

}

// test case

//1.拿杯咖啡

$coffee=newcoffee();

//2.加點牛奶

$coffee=newmilk($coffee);

//3.加點糖

$coffee=newsugar($coffee);

printf("coffee total:%0.2f元\n",$coffee->cost());

總結

1.裝飾者(milk)和被裝飾者(coffee)必須是一樣的型別。目的是裝飾者必須取代被裝飾者。

2.新增行為:當裝飾者和元件組合時,就是在加入新的行為。

題外話:

1.利用繼承設計子類行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。打個比方,老子想學點功夫,看你小子會太極拳,老子只需要繼承你一下 ,老子也就會太極拳了——呵呵,這時老子就變成你兒子了,看來繼承是要付出代價的。

2.組合,我們可以擴充套件物件的行為,在執行時動態地進行擴充套件。利用組合我們可以隨時把我們當時設計超類時沒有想到的方法加入到物件中,而不用改變現有的**。打個比方,老子現在沒有內力,吸功**,把和尚,尼姑,道士的內力(行為物件)都吸過來,那在搏鬥(執行時)中,老子可以隨時都能使用不同的內力,但也不能胡亂吸內力,否則你就要走火入魔了!

3.類應該對擴充套件開放,對修改關閉。如果我們每個部分都用裝飾者模式進行設計,那麼對於整個框架來說有點浪費,而且你也加大了**的難度。那什麼時候使用這種模式呢?我們一般用於經常改變的地方。那我們又怎麼知道哪些是經常改變的地方呢?這個就需要我們的經驗和你對所處行業的了解。建議大家平時多看點例子。

4.裝飾模式為設計注入彈性,但同時會在設計中加入大量的小類,這偶爾會導致別人不容易了解這種設計。

5.在使用裝飾者模式的時候,對插入的的裝飾者要特別小心。因為裝飾者模式依賴某種特定的型別(beverage)。

6.要想很好的使用裝飾者模式,我們還要配合使用工廠模式和生成器模式,但今天只說裝飾者模式。要想知道更多,請聽下回分解。

參考文獻:《head first 設計模式》

PHP設計模式之裝飾者模式

裝飾者模式動態地將責任附加到物件上。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。abstract class beverage 被裝飾者類 class coffee extends beverage public function cost 以下三個類是裝飾者相關類 class cond...

php設計模式之 裝飾者模式

beverage.php namespace designpattern abstract class beverage param string name return beverage public function setname string name beverage return flo...

設計模式之 裝飾者模式

一 裝飾者模式 裝飾者模式又稱為包裝模式。動態地給乙個物件增加新的職責。若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾者模式顧名思義就是對乙個物件進行裝飾,具體怎樣裝飾呢?那就是給這個物件不斷的增加職責方法。給乙個物件增加方法不簡單啊,用繼承或者直接在物件的類中增加方法。如果我們要對自...