代码均来源于《php设计模式》一书
?tracklist = array(); } public function addtrack($track) { $this->tracklist[] = $track; } public function gettracklist() { $output = ''; foreach ($this->tracklist as $num => $track) { $output .= ($num + 1) . ) {$track}.; } return $output; }}$tracksfroexternalsource = array(what it means, brr, goodbye);$mycd = new cd();foreach ($tracksfroexternalsource as $track) { $mycd->addtrack($track);}print the cd contains:{$mycd->gettracklist()}\n;/** * 需求发生小变化: 要求每个输出的参数都采用大写形式. 对于这么小的变化而言, 最佳的做法并非修改基类或创建父 - 子关系, 而是创建一个基于装饰器设计模式的对象。 * */class cdtracklistdecoratorcaps { private $_cd; public function __construct(cd $cd) { $this->_cd = $cd; } public function makecaps() { foreach ($this->_cd->tracklist as & $track) { $track = strtoupper($track); } }}$mycd = new cd();foreach ($tracksfroexternalsource as $track) { $mycd->addtrack($track);}//新增以下代码实现输出参数采用大写形式$mycdcaps = new cdtracklistdecoratorcaps($mycd);$mycdcaps->makecaps();print the cd contains:{$mycd->gettracklist()}\n;/* end of decorator.class.php *//* location the file design/decorator.class.php */
复制代码
?_songs = array(); } public function addsong($location, $title) { $song = array(location => $location, title => $title); $this->_songs[] = $song; } public function getm3u() { $m3u = #extm3u\n\n; foreach ($this->_songs as $song) { $m3u .= #extinf: -1, {$song['title']}\n; $m3u .= {$song['location']}\n; } return $m3u; } public function getpls() { $pls = [playlist]]\nnumberofentries = . count($this->_songs) . \n\n; foreach ($this->_songs as $songcount => $song) { $counter = $songcount + 1; $pls .= file{$counter} = {$song['location']}\n; $pls .= title{$counter} = {$song['title']}\n; $pls .= lengthp{$counter} = -1 \n\n; } return $pls; }}$playlist = new playlist();$playlist->addsong(/home/aaron/music/brr.mp3, brr);$playlist->addsong(/home/aaron/music/goodbye.mp3, goodbye);$externalretrievedtype = pls;if ($externalretrievedtype == pls) { $playlistcontent = $playlist->getpls();} else { $playlistcontent = $playlist->getm3u();}echo $playlistcontent;//委托模式实现 class newplaylist { private $_songs; private $_tyepobject; public function __construct($type) { $this->_songs = array(); $object = {$type}playlist; $this->_tyepobject = new $object; } public function addsong($location, $title) { $song = array(location => $location, title => $title); $this->_songs[] = $song; } public function getplaylist() { $playlist = $this->_tyepobject->getplaylist($this->_songs); return $playlist; }}class m3uplaylist { public function getplaylist($songs) { $m3u = #extm3u\n\n; foreach ($songs as $song) { $m3u .= #extinf: -1, {$song['title']}\n; $m3u .= {$song['location']}\n; } return $m3u; } }class plsplaylist { public function getplaylist($songs) { $pls = [playlist]]\nnumberofentries = . count($songs) . \n\n; foreach ($songs as $songcount => $song) { $counter = $songcount + 1; $pls .= file{$counter} = {$song['location']}\n; $pls .= title{$counter} = {$song['title']}\n; $pls .= lengthp{$counter} = -1 \n\n; } return $pls; }}$externalretrievedtype = pls;$playlist = new newplaylist($externalretrievedtype);$playlist->addsong(/home/aaron/music/brr.mp3, brr);$playlist->addsong(/home/aaron/music/goodbye.mp3, goodbye);$playlistcontent = $playlist->getplaylist();echo $playlistcontent;/* end of delegate.class.php *//* location the file design/delegate.class.php */
复制代码
?tracks = $tracks; $this->band = $band; $this->title = $title; }}class cduppercase { public static function makestring(cd $cd, $type) { $cd->$type = strtoupper($cd->$type); } public static function makearray(cd $cd, $type) { $cd->$type = array_map(strtoupper, $cd->$type); } }class cdmakexml { public static function create(cd $cd) { $doc = new domdocument(); $root = $doc->createelement(cd); $root = $doc->appendchild($root); $title = $doc->createelement(title, $cd->title); $title = $root->appendchild($title); $band = $doc->createelement(band, $cd->band); $band = $root->appendchild($band); $tracks = $doc->createelement(tracks); $tracks = $root->appendchild($tracks); foreach ($cd->tracks as $track) { $track = $doc->createelement(track, $track); $track = $tracks->appendchild($track); } return $doc->savexml(); }}class webservicefacade { public static function makexmlcall(cd $cd) { cduppercase::makestring($cd, title); cduppercase::makestring($cd, band); cduppercase::makearray($cd, tracks); $xml = cdmakexml::create($cd); return $xml; }}$tracksfromexternalsource = array(what it means, brr, goodbye);$band = never again;$title = waster of a rib;$cd = new cd($tracksfromexternalsource, $band, $title);$xml = webservicefacade::makexmlcall($cd);echo $xml;/* end of facade.class.php *//* location the file design/facade.class.php */
复制代码
?title = $title; } public function setband($band) { $this->band = $band; } public function addtrack($track) { $this->tracks[] = $track; } }//增强型cd类, 与标准cd的唯一不同是写至cd的第一个track是数据track(data track)class enhadcedcd { public $tracks = array(); public $band = ''; public $title = ''; public function __construct() { $this->tracks = data track; } public function settitle($title) { $this->title = $title; } public function setband($band) { $this->band = $band; } public function addtrack($track) { $this->tracks[] = $track; }}//cd工厂类,实现对以上两个类具体实例化操作class cdfactory { public static function create($type) { $class = strtolower($type) . cd; return new $class; }}//实例操作$type = enhadced;$cd = cdfactory::create($type);$tracksfromexternalsource = array(what it means, brr, goodbye);$cd->setband(never again);$cd->settitle(waste of a rib);foreach ($tracksfromexternalsource as $track) { $cd->addtrack($track);}/* end of factory.class.php *//* end of file design/factory.class.php */
复制代码
?_username = $username; } public function getprofilepage() { $profile = i like never again ! ; $profile .= i love all of their songs. my favorite cd:
; $profile .= {{mycd.gettitle}}!!; return $profile; }}class usercd { protected $_user = null; public function setuser(user $user) { $this->_user = $user; } public function gettitle() { $title = waste of a rib; return $title; }}class usercdinterpreter { protected $_user = null; public function setuser(user $user) { $this->_user = $user; } public function getinterpreted() { $profile = $this->_user->getprofilepage(); if (preg_match_all('/\{\{mycd\.(.*?)\}\}/', $profile, $triggers, preg_set_order)) { $replacements = array(); foreach ($triggers as $trigger) { $replacements[] = $trigger[1]; } $replacements = array_unique($replacements); $mycd = new usercd(); $mycd->setuser($this->_user); foreach ($replacements as $replacement) { $profile = str_replace({{mycd.{$replacement}}}, call_user_func(array($mycd, $replacement)), $profile); } } return $profile; } }$username = aaron;$user = new user($username);$interpreter = new usercdinterpreter();$interpreter->setuser($user);print {$username}'s profile;print $interpreter->getinterpreted();/* end of interpreter.class.php *//* location the file design/interpreter.class.php */
复制代码
?band = $band; $this->title = $title; } public function addtrack($track) { $this->tracklist[] = $track; }}class cdsearchbybanditerator implements iterator { private $_cds = array(); private $_valid = false; public function __construct($bandname) { $db = mysql_connect(localhost, root, root); mysql_select_db(test); $sql = select cd.id, cd.band, cd.title, tracks.tracknum, tracks.title as tracktitle ; $sql .= from cd left join tracks on cd.id = tracks.cid ; $sql .= where band = ' . mysql_real_escape_string($bandname) . ' ; $sql .= order by tracks.tracknum; $results = mysql_query($sql); $cdid = 0; $cd = null; while ($result = mysql_fetch_array($results)) { if ($result[id] !== $cdid) { if ( ! is_null($cd)) { $this->_cds[] = $cd; } $cdid = $result['id']; $cd = new cd($result['band'], $result['title']); } $cd->addtrack($result['tracktitle']); } $this->_cds[] = $cd; } public function next() { $this->_valid = (next($this->_cds) === false) ? false : true; } public function rewind() { $this->_valid = (reset($this->_cds) === false) ? false : true; } public function valid() { return $this->_valid; } public function current() { return current($this->_cds); } public function key() { return key($this->_cds); }}$queryitem = never again;$cds = new cdsearchbybanditerator($queryitem);print found the following cds;print bandttilenum tracks
;foreach ($cds as $cd) { print {$cd->band} {$cd->title} ; print count($cd->tracklist).
;}print
;/* end of iterator.class.php *//* location the file design/iterator.class.php */
复制代码
?_mediator = $mediator; } public function save() { //具体实现待定 var_dump($this); } public function changebandname($bandname) { if ( ! is_null($this->_mediator)) { $this->_mediator->change($this, array(band => $bandname)); } $this->band = $bandname; $this->save(); }}//mp3archive类class mp3archive { protected $_mediator; public function __construct(musiccontainermediator $mediator = null) { $this->_mediator = $mediator; } public function save() { //具体实现待定 var_dump($this); } public function changebandname($bandname) { if ( ! is_null($this->_mediator)) { $this->_mediator->change($this, array(band => $bandname)); } $this->band = $bandname; $this->save(); }}//中介者类class musiccontainermediator { protected $_containers = array(); public function __construct() { $this->_containers[] = cd; $this->_containers[] = mp3archive; } public function change($originalobject, $newvalue) { $title = $originalobject->title; $band = $originalobject->band; foreach ($this->_containers as $container) { if ( ! ($originalobject instanceof $container)) { $object = new $container; $object->title = $title; $object->band = $band; foreach ($newvalue as $key => $val) { $object->$key = $val; } $object->save(); } } }}//测试实例$titlefromdb = waste of a rib;$bandfromdb = never again;$mediator = new musiccontainermediator();$cd = new cd($mediator);$cd->title = $titlefromdb;$cd->band = $bandfromdb;$cd->changebandname(maybe once more);/* end of mediator.class.php *//* location the file design/mediator.class.php */
复制代码
/*sqlyog 企业版 - mysql gui v8.14 mysql - 5.1.52-community : database - test**********************************************************************//*!40101 set names utf8 */;/*!40101 set sql_mode=''*/;/*!40014 set @old_unique_checks=@@unique_checks, unique_checks=0 */;/*!40014 set @old_foreign_key_checks=@@foreign_key_checks, foreign_key_checks=0 */;/*!40101 set @old_sql_mode=@@sql_mode, sql_mode='no_auto_value_on_zero' */;/*!40111 set @old_sql_notes=@@sql_notes, sql_notes=0 */;/*table structure for table `cd` */drop table if exists `cd`;create table `cd` ( `id` int(8) not null auto_increment, `band` varchar(500) collate latin1_bin not null default '', `title` varchar(500) collate latin1_bin not null default '', `bought` int(8) default null, `amount` int(8) default null, primary key (`id`)) engine=innodb auto_increment=2 default charset=latin1 collate=latin1_bin;/*data for the table `cd` */insert into `cd`(`id`,`band`,`title`,`bought`,`amount`) values (1,'never again','waster of a rib',1,98);/*table structure for table `tracks` */drop table if exists `tracks`;create table `tracks` ( `cid` int(8) default null, `tracknum` int(8) default null, `title` varchar(500) collate latin1_bin not null default '') engine=innodb default charset=latin1 collate=latin1_bin;/*data for the table `tracks` */insert into `tracks`(`cid`,`tracknum`,`title`) values (1,3,'what it means'),(1,3,'brr'),(1,3,'goodbye');/*!40101 set sql_mode=@old_sql_mode */;/*!40014 set foreign_key_checks=@old_foreign_key_checks */;/*!40014 set unique_checks=@old_unique_checks */;/*!40111 set sql_notes=@old_sql_notes */;
复制代码