裝飾器模式:
如果已有對象的部分內容或功能性發生改變,但是不需要修改原始對象的結構或不使用繼承,動態的擴展一個對象的功能,則應該使用裝飾器模式。
簡單點說:就是我們不應該去修改已有的類,而是通過創建另外一個裝飾器類,通過這個裝飾器類去動態的擴展其需要修改的內容,這樣做的好處就是————
1、我們可以保證類的層次不會因過多而發生混亂。
2、當我們需求的修改很小時,不用改變原有的數據結構。
代碼引用自《PHP設計模式》。
1 /** 2 * 被修飾類 3 現在的需求: 4 要求能夠動態為CD添加音軌、能顯示CD音軌列表。 5 顯示時應采用單行並且為每個音軌都以音軌好為前綴。 6 */ 7 class CD 8 { 9 public $trackList; 10 function __construct() 11 { 12 # code... 13 $this->trackList=array(); 14 } 15 16 public function addTrack($track){ 17 $this->trackList[]=$track; 18 } 19 20 public function getTrackList(){ 21 $output=" "; 22 foreach ($this->trackList as $key => $value) { 23 # code... 24 $output.=($key+1).") {$value}. "; 25 } 26 return $output; 27 } 28 } 29 30 /* 31 現在需求發生變化: 32 要求將當前實例輸出的音軌都采用大寫形式。 33 這個需求並不是一個變化特別大的需求,不需要修改基類或創建一個父子關系的子類,此時創建一個基於裝飾器模式的裝飾器類。 34 */ 35 class CDTrackListDecoratorCaps{ 36 private $_cd; 37 38 public function __construct(CD $CD){ 39 $this->_cd=$CD; 40 } 41 42 public function makeCaps(){ 43 foreach ($this->_cd->trackList as $key => $value) { 44 # code... 45 $this->_cd->trackList[$key]=strtoupper($value); //轉換成大寫 46 } 47 } 48 } 49 50 51 //客戶端測試: 52 $myCD=new CD(); 53 54 $trackList=array( 55 "what It Means", 56 "brr", 57 "goodBye" 58 ); 59 foreach ($trackList as $key => $value) { 60 # code... 61 $myCD->addTrack($value); 62 } 63 $myCDCaps=new CDTrackListDecoratorCaps($myCD); 64 $myCDCaps->makeCaps(); 65 print "The CD contains the following tracks:".$myCD->getTrackList();