装饰器模式:
如果已有对象的部分内容或功能性发生改变,但是不需要修改原始对象的结构或不使用继承,动态的扩展一个对象的功能,则应该使用装饰器模式。
简单点说:就是我们不应该去修改已有的类,而是通过创建另外一个装饰器类,通过这个装饰器类去动态的扩展其需要修改的内容,这样做的好处就是————
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();