设计模式之装饰者模式

装饰模式:动态的给对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加的灵活。

装饰者模式与传统模式的区别

一般要给对象添加功能时的做法:

传统模式:

  (1)直接修改对象添加相应的功能,

  (2)派生对应的子类来拓展原有类的功能

装饰者模式:

  使用对象组合的方式,动态的组合功能

装饰者模式的具体做法

在这种模式下,对已有对象的部分内容或者是功能进行调整,但是不修改原始的对象结构。换句话说,不修改已有的类,而是通过创建另外一个装饰者类去动态的拓展其需要修改的内容。

优势:

(1)可以保证类的层次不会因过多而发生混乱

(2)当我们需求的修改很小时,不用改变原有的数据结构

装饰者模式把每个要装饰的功能放在单独的类中,并让这个类包装它需要装饰的对象。因此,当需要执行特殊行为时吗,客户端代码就可以在运行时根据需求有选择的,按顺序的的使用装饰功能来包装对象。有效的把类的核心职责和装饰功能区分开,而且可以去除相关类中重复的逻辑代码。

案例1

 1 <?php
 2 
 3 /** * 被修饰类 现在的需求: 要求能够动态为CD添加音轨、能显示CD音轨列表。 显示时应采用单行并且为每个音轨都以音轨好为前缀。 */
 4 
 5 
 6 class CD {
 7     public $trackList;
 8  
 9     function __construct()   {
10         # code...
11         $this->trackList=array();
12     }
13  
14     public function addTrack($track){
15         $this->trackList[]=$track;
16     }
17  
18     public function getTrackList(){
19         $output=" ";
20         foreach ($this->trackList as $key => $value) {
21             # code...
22             $output.=($key+1).") {$value}. ";
23         }
24         return $output;
25     }
26 
27 }
28 
29 /* 现在需求发生变化: 要求将当前实例输出的音轨都采用大写形式。 这个需求并不是一个变化特别大的需求,不需要修改基类或创建一个父子关系的子类,此时创建一个基于装饰器模式的装饰器类。 */
30 
31 class CDTrackListDecoratorCaps{
32     private $_cd;
33  
34     public function __construct(CD $CD){
35         $this->_cd=$CD;
36     }
37  
38     public function makeCaps(){
39         foreach ($this->_cd->trackList as $key => $value) {
40             # code...
41             $this->_cd->trackList[$key]=strtoupper($value); //转换成大写
42         }
43     }
44 }
45  
46 //客户端测试
47 $myCD=new CD();
48 $trackList=array(   "what It Means",   "brr",   "goodBye"  );
49 foreach ($trackList as $key => $value) {
50     # code...
51     $myCD->addTrack($value);
52 }
53  
54 $myCDCaps=new CDTrackListDecoratorCaps($myCD);
55 $myCDCaps->makeCaps();
56 print "The CD contains the following tracks:".$myCD->getTrackList();

案例2

 1 UserInfo.php
 2 //装饰器模式,对已有对象的部分内容或者功能进行调整,但是不需要修改原始对象结构,可以使用装饰器设计模式
 3 class UserInfo {
 4  
 5     public $userInfo = array(); 
 6         
 7     public function addUser($userInfo) {
 8         $this->userInfo[] = $userInfo;
 9     }
10         
11     public function getUserList() {
12         print_r($this->userInfo);
13     }
14 }
15  
16 //UserInfoDecorate 装饰一样,改变用户信息输出为大写格式,不改变原先UserInfo类
17 <?php
18 include("UserInfo.php");
19 class UserInfoDecorate {
20     
21     public function makeCaps($UserInfo) {
22         foreach ($UserInfo->userInfo as &$val) {
23             $val = strtoupper($val);
24         }
25     }
26     
27 }
28  
29 $UserInfo = new UserInfo;
30 $UserInfo->addUser('zhu');
31 $UserInfo->addUser('initphp');
32 $UserInfoDecorate = new UserInfoDecorate;
33 $UserInfoDecorate->makeCaps($UserInfo);
34 $UserInfo->getUserList();

 

posted @ 2019-06-06 11:23  sfengz  阅读(123)  评论(0编辑  收藏  举报