您的位置:首页 > 编程语言 > PHP开发

PHP设计模式之装饰器模式,委托模式,外观模式

2011-12-06 11:42 751 查看

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();
4000
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息