设为首页 收藏本站
查看: 1353|回复: 0

[经验分享] PHP设计模式之装饰器模式,委托模式,外观模式

[复制链接]

尚未签到

发表于 2017-4-14 10:27:53 | 显示全部楼层 |阅读模式





1.装饰器模式
如果已有对象的部分内容或功能发生改变,但是不修改原始对象的结构,也不使用扩展类时,可以使用装饰器模式。
class CD
{

public $trackList;


public function __construct()
{
$this->trackList=array();
}


public function addTrack($track) //向CD中添加一首歌
{
$this->trackList[]=$track;
}


public function getTrackList()
{
$output=' ';
foreach($this->trackList as $num=>$track)
{
$output .= ($num+1) . "--{$track} ";
}
return $output;
}
}
调用时:
$trackExtends=array('Over My Head','Wake Me Up','Faint');
$myCD=new CD();
foreach($arrayExtends as $track)
$myCD->addTrack($track);


现在功能要把track的名字变为大写,在不修改原类和不使用继承的情况下,使用装饰器模式
class CDDecorator
{
private $__cd;


public function __construct(CD $cd)
{
$this->cd=$cd;
}


public function makeCaps
{
foreach($this->__cd->trackList as $track)
$track=strtoupper($track);
}
}
再次调用时:
$arrayExtends=array('Over My Head','Wake Me Up','Faint');

$myCD=new CD();
foreach($arrayExtends as $track)
$myCD->addTrack($track);



$myCDDecorator=new CDDecorator($myCD);
$myCDDecorator->makeCaps();      //完成了对CD中track变大写的功能


把要装饰的对象的一个实例作为装饰类的私有对象,进行加工处理,得到需要的功能
2.委托模式
通过分配或委托至其它对象,委托设计模式能够去除核心对象中的条件判断和复杂的功能性。
比如某MP3站点可以通过M3U或者PLS格式下载播放列表:
class Playlist
{
private $__songs;


public function __construct()
{
$this->__songs=array();
}


public function addSong($location,$title)
{
$song=array('location'=>$location,'title'=>$title);
$this->songs[]=$song; //把song添加到songs数组中
}


public function getM3U()
{
$m3u="somethingm3u";
return $m3u;
}
public function getPLS()
{
$pls="somethingpls"; //以另外一种方式显示歌曲列表
return $pls;
}
}


调用时:
$playlist=new PlayList();
$playlist->addSong('/music/taylor/1.mp3,'you belong with me'');
$playlist->addSong('/music/linkin/6.mp3,'papercut'');



if($externalRetrievedType=='pls')
$playlistContent=$playlist->getPLS();
else
$playlistContent=$playlist->getM3U();


可以看到现在只有两种可以判断,如果之后再添加新的分类,更改维护起来会很麻烦
下面用委托模式来解决:
class newPlaylist
{
private $__songs;
private $__typeObject;


public function __construct($type)
{
$this->__songs=array();
$object="{$type}Playlist";
$this->__typeObject=new $object;
}


public function addSong($location,$title)
{
$song=array('location'=>$location,'title'=>$title);
$this->__songs[]=$song;
}


public function getPlaylist()
{
$playlist=$this->__typeObject->getPlaylist($this->__songs);
return $playlist;
}
}


下面构造每个种类的委托类
class m3uPlaylistDelegate
{
public function getPlayList($songs)
{
$m3u="somethingm3u";
return $m3u;
}
}


class plsPlaylistDelegate
{
public function getPlayList($songs)
{
$pls="somethingpls";
return $pls;
}
}


调用时:
$extype='pls';
$playlist=new newPlaylist($extype);
$content=$playlist->getPlaylist();
这样,当增加新的类型时,开发人员不用修改上面的代码,只需要再写一个新的委托类就能完成功能。
委托模式去除了核心对象的复杂性并且能够动态添加新的功能。



3.外观模式
在应用进程中的一个步骤抱恨许多复杂的逻辑步骤和方法调用时,创建一个机遇外观模式的对象
外观模式隐藏了来自调用对象的复杂性



一张CD的信息需要进行两个操作:1.把CD相关信息转换为大写 2.生成一个XML文档
class CD
{
......
}


class CDUpperCase
{
public static function makeString(CD $cd,$type)
..
}


class CDMakeXML
{
public static function create(CD $cd)
....
}
之所以不把这两个类实现的功能直接加入CD类中,而是单独建类时为了之后重用方便着想。
调用时:
CDUpperCase::makeString($cd,'title');
CDUpperCase::makeString($cd,'band');
print CDMakeXML::create($cd);


用外观模式来实现:
class WebServiceFacade
{
public static function makeXMLCall(CD $cd)
{
CDUpperCase::makeString($cd,'title');CDUpperCase::makeString($cd,'band');

}
$xml=CDMakeXML::create($cd);
return $xml;
}


1.装饰器模式
如果已有对象的部分内容或功能发生改变,但是不修改原始对象的结构,也不使用扩展类时,可以使用装饰器模式。
class CD
{

public $trackList;


public function __construct()
{
$this->trackList=array();
}


public function addTrack($track) //向CD中添加一首歌
{
$this->trackList[]=$track;
}


public function getTrackList()
{
$output=' ';
foreach($this->trackList as $num=>$track)
{
$output .= ($num+1) . "--{$track} ";
}
return $output;
}
}
调用时:
$trackExtends=array('Over My Head','Wake Me Up','Faint');
$myCD=new CD();
foreach($arrayExtends as $track)
$myCD->addTrack($track);


现在功能要把track的名字变为大写,在不修改原类和不使用继承的情况下,使用装饰器模式
class CDDecorator
{
private $__cd;


public function __construct(CD $cd)
{
$this->cd=$cd;
}


public function makeCaps
{
foreach($this->__cd->trackList as $track)
$track=strtoupper($track);
}
}
再次调用时:
$arrayExtends=array('Over My Head','Wake Me Up','Faint');

$myCD=new CD();
foreach($arrayExtends as $track)
$myCD->addTrack($track);



$myCDDecorator=new CDDecorator($myCD);
$myCDDecorator->makeCaps();      //完成了对CD中track变大写的功能


2.委托模式
通过分配或委托至其它对象,委托设计模式能够去除核心对象中的条件判断和复杂的功能性。
比如某MP3站点可以通过M3U或者PLS格式下载播放列表:
class Playlist
{
private $__songs;


public function __construct()
{
$this->__songs=array();
}


public function addSong($location,$title)
{
$song=array('location'=>$location,'title'=>$title);
$this->songs[]=$song; //把song添加到songs数组中
}


public function getM3U()
{
$m3u="somethingm3u";
return $m3u;
}
public function getPLS()
{
$pls="somethingpls"; //以另外一种方式显示歌曲列表
return $pls;
}
}


调用时:
$playlist=new PlayList();
$playlist->addSong('/music/taylor/1.mp3,'you belong with me'');
$playlist->addSong('/music/linkin/6.mp3,'papercut'');



if($externalRetrievedType=='pls')
$playlistContent=$playlist->getPLS();
else
$playlistContent=$playlist->getM3U();


可以看到现在只有两种可以判断,如果之后再添加新的分类,更改维护起来会很麻烦
下面用委托模式来解决:
class newPlaylist
{
private $__songs;
private $__typeObject;


public function __construct($type)
{
$this->__songs=array();
$object="{$type}Playlist";
$this->__typeObject=new $object;
}


public function addSong($location,$title)
{
$song=array('location'=>$location,'title'=>$title);
$this->__songs[]=$song;
}


public function getPlaylist()
{
$playlist=$this->__typeObject->getPlaylist($this->__songs);
return $playlist;
}
}


下面构造每个种类的委托类
class m3uPlaylistDelegate
{
public function getPlayList($songs)
{
$m3u="somethingm3u";
return $m3u;
}
}


class plsPlaylistDelegate
{
public function getPlayList($songs)
{
$pls="somethingpls";
return $pls;
}
}


调用时:
$extype='pls';
$playlist=new newPlaylist($extype);
$content=$playlist->getPlaylist();
这样,当增加新的类型时,开发人员不用修改上面的代码,只需要再写一个新的委托类就能完成功能。
委托模式去除了核心对象的复杂性并且能够动态添加新的功能。



3.外观模式
在应用进程中的一个步骤抱恨许多复杂的逻辑步骤和方法调用时,创建一个机遇外观模式的对象
外观模式隐藏了来自调用对象的复杂性



一张CD的信息需要进行两个操作:1.把CD相关信息转换为大写 2.生成一个XML文档
class CD
{
......
}


class CDUpperCase
{
public static function makeString(CD $cd,$type)
..
}


class CDMakeXML
{
public static function create(CD $cd)
....
}
之所以不把这两个类实现的功能直接加入CD类中,而是单独建类时为了之后重用方便着想。
调用时:
CDUpperCase::makeString($cd,'title');
CDUpperCase::makeString($cd,'band');
print CDMakeXML::create($cd);


用外观模式来实现:
class WebServiceFacade
{
public static function makeXMLCall(CD $cd)
{
CDUpperCase::makeString($cd,'title');CDUpperCase::makeString($cd,'band');

}
$xml=CDMakeXML::create($cd);
return $xml;
}


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-364821-1-1.html 上篇帖子: 在 Windows 上安裝 PHP 5.3 開發環境 下篇帖子: PHP设计模式之适配器模式,建造者模式,数据访问对象模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表