代码均来源于《PHP设计模式》一书
- ?/**
- * 转自 《PHP设计模式》 第六章: 装饰器模式
- *
- * 装饰器设计模式适用于下列工作场合: 需求变化是快速和细小的,而且几乎不影响应用程序的其他部分。()
- * 使用装饰器设计模式设计类的目标是: 不必重写任何已有的功能性代码,而是对某个基于对象应用增量变化。
- * 装饰器设计模式采用这样的构建方式: 在主代码流中应该能够直接插入一个或多个更改或“装饰”目标对象的装饰器,同时不影响其他代码流。
- *
- */
- class CD {
- public $trackList;
-
- public function __construct() {
- $this->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 */
复制代码
- ?/**
- * 转自 《PHP设计模式》 第七章: 委托模式
- * 当一个对象包含复杂单独立的,必须基于判决执行的功能性的若*分时,最佳的方法是适用基于委托设计模式的对象。
- *
- */
-
- /**
- * 示例: Web站点具有创建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;
- }
-
- 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 */
复制代码
- ?/**
- * 转自 《PHP设计模式》 第八章: 外观模式
- * 外观设计模式的目标是: 控制外部错综复杂的关系, 并且提供简单的接口以利用上述组件的能力。
- * 为了隐藏复杂的,执行业务进程某个步骤所需的方法和逻辑组,就应当使用基于外观设计模式的类。
- *
- */
- /**
- * 代码示例: 获取CD对象,对其所有属性应用大写形式,并且创建一个要提交给Web服务的,格式完整的XML文档。
- *
- */
- class CD {
-
- public $tracks = array();
- public $band = '';
- public $title = '';
-
- public function __construct($tracks, $band, $title) {
- $this->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 */
复制代码
- ?/**
- * 转自 《PHP设计模式》 第九章: 工厂模式
- * 工厂设计模式: 提供获取某个对象的新实例的一个接口, 同时使调用代码避免确定实际实例化基类的步骤
- *
- */
- //基础标准CD类
- class CD {
-
- public $tracks = array();
- public $band = '';
- public $title = '';
-
- public function __construct() {}
-
- public function setTitle($title) {
- $this->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 */
复制代码
- ?/**
- * 转自 《PHP设计模式》 第十章: 解释器模式
- * 解释器: 解释器设计模式用于分析一个实体的关键元素,并且针对每个元素都提供自己的解释或相应的动作。
- * 解释器设计模式最常用于PHP/HTML 模板系统。
- *
- */
- class User {
-
- protected $_username = "";
-
- public function __construct($username) {
- $this->_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 */
复制代码
- ?/**
- * 转自 《PHP设计模式》 第十一章: 迭代器模式
- * 迭代器:迭代器设计模式可帮助构造特定对象, 那些对象能够提供单一标准接口循环或迭代任何类型的可计数数据。
- * 处理需要遍历的可计数数据时, 最佳的解决办法是创建一个基于迭代器设计模式的对象。
- *
- */
- class CD {
-
- public $band = "";
- public $title = "";
- public $trackList = array();
-
- public function __construct($band, $title) {
- $this->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 "
Band |
Ttile |
Num 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 */
复制代码
- /*
- 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 */;
-
复制代码
|