PHP設計模式之裝飾器模式
來自: https://segmentfault.com/a/1190000004467783
裝飾器模式解決的問題
修飾模式,是面向對象編程領域中,一種動態地往一個類中添加新的行為的設計模式。就功能而言,修飾模式相比生成子類更為靈活,這樣可以給某個對象而不是整個類添加一些功能。
將所有的功能建立在繼承體系上會導致系統中的類越來越多,而且當你又要修改他們的分支的時候,可能還會出現重復代碼
我們來看下面這個例子,為了計算一塊區域的價值,我們把代碼寫成下面這個樣子:
// 區域抽象類 abstract class Area { abstract public function treasure(); } //森林類,價值100 class Forest extends Area { public function treasure() { return 100; } } //沙漠類,價值10 class Desert extends Area { function function treasure() { return 10; } }
上面的代碼看上去好像沒有什么問題,但是如果需要給一片被破壞的森林計算價值怎么辦呢,添加DamageForest子類么?顯然是不可行的,因為很有可能還有其他很多類型疊加的類,這會導致類中可能會有重復的代碼,且子類也會變的越來越多。
裝飾器模式的實現
裝飾器模式使用組合和委托,而不是使用繼承來解決上述的問題,我們在來看下面改良過的代碼:
// 區域抽象類 abstract class Area { abstract public function treasure(); } //森林類,價值100 class Forest extends Area { public function treasure() { return 100; } } //沙漠類,價值10 class Desert extends Area { function function treasure() { return 10; } } //區域類的裝飾器類 abstract class AreaDecorateor extends Area { protected $_area = null; public function __construct(Area $area) { $this->_area = $area; } } //被破壞了后的區域,價值只有之前的一半 class Damaged extends AreaDecorateor { public function treasure() { return $this->_area->treasure() * 0.5; } } //現在我們來獲取被破壞的森林類的價值 $damageForest = new Damaged(new Forest()); echo $damageForest->treasure(); //返回50
總結
上面的調用方法很像建立了一個管道,裝飾器模式經常被用于創建過濾器。
可以看到,這樣的模型很具有擴者性,我們可以輕松的添加其他裝飾器給區域對象,且不需要更改其他類,
本文由用戶 flutelover 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!