裝飾器模式(Decorator Pattern)容許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是做爲現有的類的一個包裝。php
這種模式建立了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。html
抽象組件角色(Component):定義一個對象接口,以規範準備接受附加責任的對象,便可以給這些對象動態地添加職責。設計模式
具體組件角色(ConcreteComponent) :被裝飾者,定義一個將要被裝飾增長功能的類。能夠給這個類的對象添加一些職責測試
抽象裝飾器(Decorator):維持一個指向構件Component對象的實例,並定義一個與抽象組件角色Component接口一致的接口this
具體裝飾器角色(ConcreteDecorator):向組件添加職責。spa
須要動態的給一個對象添加功能,這些功能能夠再動態的撤銷。設計
須要增長由一些基本功能的排列組合而產生的很是大量的功能,從而使繼承關係變的不現實。code
當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。component
代碼:htm
<?php header('Content-type:text/html;charset=utf-8'); /** * 裝飾器模式 */ /** * Interface IComponent 組件對象接口 */ interface IComponent { public function display(); } /** * Class Person 待裝飾對象 */ class Person implements IComponent { private $_name; /** * Person constructor. 構造方法 * * @param $name 對象人物名稱 */ public function __construct($name) { $this->_name = $name; } /** * 實現接口方法 */ public function display() { echo "裝扮者:{$this->_name}<br/>"; } } /** * Class Clothes 全部裝飾器父類-服裝類 */ class Clothes implements IComponent { protected $component; /** * 接收裝飾對象 * * @param IComponent $component */ public function decorate(IComponent $component) { $this->component = $component; } /** * 輸出 */ public function display() { if(!empty($this->component)) { $this->component->display(); } } } /** * 下面爲具體裝飾器類 */ /** * Class Sneaker 運動鞋 */ class Sneaker extends Clothes { public function display() { echo "運動鞋 "; parent::display(); } } /** * Class Tshirt T恤 */ class Tshirt extends Clothes { public function display() { echo "T恤 "; parent::display(); } } /** * Class Coat 外套 */ class Coat extends Clothes { public function display() { echo "外套 "; parent::display(); } } /** * Class Trousers 褲子 */ class Trousers extends Clothes { public function display() { echo "褲子 "; parent::display(); } } /** * 客戶端測試代碼 */ class Client { public static function test() { $zhangsan = new Person('張三'); $lisi = new Person('李四'); $sneaker = new Sneaker(); $coat = new Coat(); $sneaker->decorate($zhangsan); $coat->decorate($sneaker); $coat->display(); echo "<hr/>"; $trousers = new Trousers(); $tshirt = new Tshirt(); $trousers->decorate($lisi); $tshirt->decorate($trousers); $tshirt->display(); } } Client::test();
運行結果:
外套 運動鞋 裝扮者:張三 T恤 褲子 裝扮者:李四