首页 > 网站 > 帮助中心 > 正文

PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用详解

2024-07-09 22:42:38
字体:
来源:转载
供稿:网友

本文实例讲述了PHP设计模式之装饰器(装饰者)模式(Decorator)入门与应用。分享给大家供大家参考,具体如下:

通常情况下,我们如果要给对象添加功能,要么直接修改对象添加相应的功能,要么派生对应的子类来扩展,抑或是使用对象组合的方式。显然,直接修改对应的类这种方式并不可取。

在面向对象的设计中,我们也应该尽量使用对象组合,而不是对象继承来扩展和复用功能。装饰器模式就是基于对象组合的方式,可以很灵活的给对象添加所需要的功能,并且它的本质就是动态组合,一句话,动态是手段,组合才是目的。

也就是说,在这种模式下,我们可以对已有对象的部分内容或者功能进行调整,但是不需要修改原始对象结构,理解了不???

还可以理解为,我们不去修改已有的类,而是通过创建另外一个装饰器类,通过这个装饰器类去动态的扩展其需要修改的内容。而它的好处也是显而易见的,如下:

1、我们可以保证类的层次不会因过多而发生混乱。 2、当我们需求的修改很小时,不用改变原有的数据结构。

我们来看下《PHP设计模式》里面的一个案例:

/** * 被修饰类 现在的需求: 要求能够动态为CD添加音轨、能显示CD音轨列表。 显示时应采用单行并且为每个音轨都以音轨好为前缀。 */class CD {  public $trackList;  function __construct()  {    # code...    $this->trackList=array();  }  public function addTrack($track){    $this->trackList[]=$track;  }  public function getTrackList(){    $output=" ";    foreach ($this->trackList as $key => $value) {      # code...      $output.=($key+1).") {$value}. ";    }    return $output;  }}/* 现在需求发生变化: 要求将当前实例输出的音轨都采用大写形式。 这个需求并不是一个变化特别大的需求,不需要修改基类或创建一个父子关系的子类,此时创建一个基于装饰器模式的装饰器类。 */class CDTrackListDecoratorCaps{  private $_cd;  public function __construct(CD $CD){    $this->_cd=$CD;  }  public function makeCaps(){    foreach ($this->_cd->trackList as $key => $value) {      # code...      $this->_cd->trackList[$key]=strtoupper($value); //转换成大写    }  }}//客户端测试$myCD=new CD();$trackList=array(  "what It Means",  "brr",  "goodBye" );foreach ($trackList as $key => $value) {  # code...  $myCD->addTrack($value);}$myCDCaps=new CDTrackListDecoratorCaps($myCD);$myCDCaps->makeCaps();print "The CD contains the following tracks:".$myCD->getTrackList();

来看一个比较通俗但是比较简单的案例:

设计一个UserInfo类,里面有UserInfo数组,用于存储用户名信息 通过addUser来添加用户名 getUserList方法将打印出用户名信息 现在需要将添加的用户信息变成大写的,我们需要不改变原先的类,并且不改变原先的数据结构 我们设计了一个UserInfoDecorate类来完成这个需求的操作,就像装饰一样,给原先的数据进行了装修 装饰器模式有些像适配器模式,但是一定要注意,装饰器主要是不改变现有对象数据结构的前提

代码如下:

UserInfo.php

//装饰器模式,对已有对象的部分内容或者功能进行调整,但是不需要修改原始对象结构,可以使用装饰器设计模式class UserInfo { public $userInfo = array();   public function addUser($userInfo) { $this->userInfo[] = $userInfo; }  public function getUserList() { print_r($this->userInfo); }}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表