Home >Backend Development >PHP Tutorial >The codes are all from the book 'PHP Design Patterns'

The codes are all from the book 'PHP Design Patterns'

WBOY
WBOYOriginal
2016-07-25 09:08:46836browse
代码均来源于《PHP设计模式》一书
  1. ?/**
  2. * Reprinted from "PHP Design Patterns" Chapter 6: Decorator Pattern
  3. *
  4. * The decorator design pattern is suitable for the following workplaces: Changes in requirements are fast and small, and have little impact on other parts of the application. ()
  5. * The goal of designing a class using the decorator design pattern is to apply incremental changes to an object without having to rewrite any existing functional code.
  6. * The decorator design pattern is built in such a way that it should be possible to directly insert one or more decorators that change or "decorate" the target object in the main code flow without affecting other code flows.
  7. *
  8. */
  9. class CD {
  10. public $trackList;
  11. public function __construct() {
  12. $this->trackList = array();
  13. }
  14. public function addTrack($track) {
  15. $this->trackList[] = $track;
  16. }
  17. public function getTrackList() {
  18. $output = '';
  19. foreach ($this->trackList as $num => $track) {
  20. $output .= ($num + 1) . ") {$track}.";
  21. }
  22. return $output;
  23. }
  24. }
  25. $tracksFroExternalSource = array("What It Means", "Brr", "Goodbye");
  26. $myCD = new CD();
  27. foreach ($tracksFroExternalSource as $track) {
  28. $myCD->addTrack($track);
  29. }
  30. print "The CD contains:{$myCD->getTrackList()}n";
  31. /**
  32. * Small change in requirements: require each output parameter to be in uppercase. For such a small change, the best approach is not to modify the base class or create a parent-child relationship,
  33. but to create a decorator-based design Pattern object.
  34. *
  35. */
  36. class CDTrackListDecoratorCaps {
  37. private $_cd;
  38. public function __construct(CD $cd) {
  39. $this->_cd = $cd;
  40. }
  41. public function makeCaps() {
  42. foreach ($this->_cd->trackList as & $track) {
  43. $track = strtoupper($track);
  44. }
  45. }
  46. }
  47. $myCD = new CD();
  48. foreach ($tracksFroExternalSource as $track) {
  49. $myCD->addTrack($track);
  50. }
  51. //新增以下代码实现输出参数采用大写形式
  52. $myCDCaps = new CDTrackListDecoratorCaps($myCD);
  53. $myCDCaps->makeCaps();
  54. print "The CD contains:{$myCD->getTrackList()}n";
  55. /* End of Decorator.class.php */
  56. /* Location the file Design/Decorator.class.php */
复制代码
  1. ?/**
  2. * Reprinted from "PHP Design Patterns" Chapter 7: Delegation Pattern
  3. * When an object contains several parts of complex, independent functionality that must be executed based on decisions, the best method is to apply an object based on the delegation design pattern.
  4. *
  5. */
  6. /**
  7. * Example: The website has the function of creating a playlist of MP3 files, and also has the function of selecting to download the playlist in M3U or PLS format.
  8. *
  9. * The following code examples show the implementation of two modes, regular and delegated
  10. *
  11. */
  12. //常规实现
  13. class Playlist {
  14. private $_songs;
  15. public function __construct() {
  16. $this->_songs = array();
  17. }
  18. public function addSong($location, $title) {
  19. $song = array("location" => $location, "title" => $title);
  20. $this->_songs[] = $song;
  21. }
  22. public function getM3U() {
  23. $m3u = "#EXTM3Unn";
  24. foreach ($this->_songs as $song) {
  25. $m3u .= "#EXTINF: -1, {$song['title']}n";
  26. $m3u .= "{$song['location']}n";
  27. }
  28. return $m3u;
  29. }
  30. public function getPLS() {
  31. $pls = "[playlist]]nNumberOfEntries = ". count($this->_songs) . "nn";
  32. foreach ($this->_songs as $songCount => $song) {
  33. $counter = $songCount + 1;
  34. $pls .= "File{$counter} = {$song['location']}n";
  35. $pls .= "Title{$counter} = {$song['title']}n";
  36. $pls .= "LengthP{$counter} = -1 nn";
  37. }
  38. return $pls;
  39. }
  40. }
  41. $playlist = new Playlist();
  42. $playlist->addSong("/home/aaron/music/brr.mp3", "Brr");
  43. $playlist->addSong("/home/aaron/music/goodbye.mp3", "Goodbye");
  44. $externalRetrievedType = "pls";
  45. if ($externalRetrievedType == "pls") {
  46. $playlistContent = $playlist->getPLS();
  47. } else {
  48. $playlistContent = $playlist->getM3U();
  49. }
  50. echo $playlistContent;
  51. //委托模式实现
  52. class newPlaylist {
  53. private $_songs;
  54. private $_tyepObject;
  55. public function __construct($type) {
  56. $this->_songs = array();
  57. $object = "{$type}Playlist";
  58. $this->_tyepObject = new $object;
  59. }
  60. public function addSong($location, $title) {
  61. $song = array("location" => $location, "title" => $title);
  62. $this->_songs[] = $song;
  63. }
  64. public function getPlaylist() {
  65. $playlist = $this->_tyepObject->getPlaylist($this->_songs);
  66. return $playlist;
  67. }
  68. }
  69. class m3uPlaylist {
  70. public function getPlaylist($songs) {
  71. $m3u = "#EXTM3Unn";
  72. foreach ($songs as $song) {
  73. $m3u .= "#EXTINF: -1, {$song['title']}n";
  74. $m3u .= "{$song['location']}n";
  75. }
  76. return $m3u;
  77. }
  78. }
  79. class plsPlaylist {
  80. public function getPlaylist($songs) {
  81. $pls = "[playlist]]nNumberOfEntries = ". count($songs) . "nn";
  82. foreach ($songs as $songCount => $song) {
  83. $counter = $songCount + 1;
  84. $pls .= "File{$counter} = {$song['location']}n";
  85. $pls .= "Title{$counter} = {$song['title']}n";
  86. $pls .= "LengthP{$counter} = -1 nn";
  87. }
  88. return $pls;
  89. }
  90. }
  91. $externalRetrievedType = "pls";
  92. $playlist = new newPlaylist($externalRetrievedType);
  93. $playlist->addSong("/home/aaron/music/brr.mp3", "Brr");
  94. $playlist->addSong("/home/aaron/music/goodbye.mp3", "Goodbye");
  95. $playlistContent = $playlist->getPlaylist();
  96. echo $playlistContent;
  97. /* End of Delegate.class.php */
  98. /* Location the file Design/Delegate.class.php */
复制代码
  1. ?/**
  2. * Reprinted from "PHP Design Patterns" Chapter 8: Appearance Pattern
  3. * The goal of the Appearance Design Pattern is to: control the intricate external relationships, and provide a simple interface to utilize the capabilities of the above components.
  4. * In order to hide the complex methods and logical groups required to perform a certain step of the business process, classes based on the appearance design pattern should be used.
  5. *
  6. */
  7. /**
  8. * Code example: Get the CD object, apply uppercase to all its properties, and create a fully formatted XML document to be submitted to the web service.
  9. *
  10. */
  11. class CD {
  12. public $tracks = array();
  13. public $band = '';
  14. public $title = '';
  15. public function __construct($tracks, $band, $title) {
  16. $this->tracks = $tracks;
  17. $this->band = $band;
  18. $this->title = $title;
  19. }
  20. }
  21. class CDUpperCase {
  22. public static function makeString(CD $cd, $type) {
  23. $cd->$type = strtoupper($cd->$type);
  24. }
  25. public static function makeArray(CD $cd, $type) {
  26. $cd->$type = array_map("strtoupper", $cd->$type);
  27. }
  28. }
  29. class CDMakeXML {
  30. public static function create(CD $cd) {
  31. $doc = new DomDocument();
  32. $root = $doc->createElement("CD");
  33. $root = $doc->appendChild($root);
  34. $title = $doc->createElement("TITLE", $cd->title);
  35. $title = $root->appendChild($title);
  36. $band = $doc->createElement("BAND", $cd->band);
  37. $band = $root->appendChild($band);
  38. $tracks = $doc->createElement("TRACKS");
  39. $tracks = $root->appendChild($tracks);
  40. foreach ($cd->tracks as $track) {
  41. $track = $doc->createElement("TRACK", $track);
  42. $track = $tracks->appendChild($track);
  43. }
  44. return $doc->saveXML();
  45. }
  46. }
  47. class WebServiceFacade {
  48. public static function makeXMLCall(CD $cd) {
  49. CDUpperCase::makeString($cd, "title");
  50. CDUpperCase::makeString($cd, "band");
  51. CDUpperCase::makeArray($cd, "tracks");
  52. $xml = CDMakeXML::create($cd);
  53. return $xml;
  54. }
  55. }
  56. $tracksFromExternalSource = array("What It Means", "Brr", "Goodbye");
  57. $band = "Never Again";
  58. $title = "Waster of a Rib";
  59. $cd = new CD($tracksFromExternalSource, $band, $title);
  60. $xml = WebServiceFacade::makeXMLCall($cd);
  61. echo $xml;
  62. /* End of Facade.class.php */
  63. /* Location the file Design/Facade.class.php */
复制代码
  1. ?/**
  2. * Reprinted from "PHP Design Patterns" Chapter 9: Factory Pattern
  3. * Factory Design Pattern: Provides an interface to obtain a new instance of an object, while allowing the calling code to avoid determining the steps to actually instantiate the base class
  4. *
  5. */
  6. //Basic standard CD class
  7. class CD {
  8. public $tracks = array();
  9. public $band = '';
  10. public $ title = '';
  11. public function __construct() {}
  12. public function setTitle($title) {
  13. $this->title = $title;
  14. }
  15. public function setBand($band) {
  16. $this ->band = $band;
  17. }
  18. public function addTrack($track) {
  19. $this->tracks[] = $track;
  20. }
  21. }
  22. //Enhanced CD class, and standard CD The only difference is that the first track written to CD is the data track("DATA TRACK")
  23. class enhadcedCD {
  24. public $tracks = array();
  25. public $band = '';
  26. public $title = '' ;
  27. public function __construct() {
  28. $this->tracks = "DATA TRACK";
  29. }
  30. public function setTitle($title) {
  31. $this->title = $title;
  32. }
  33. public function setBand($band) {
  34. $this->band = $band;
  35. }
  36. public function addTrack($track) {
  37. $this->tracks[] = $track;
  38. }
  39. }
  40. / /CD factory class, implements the specific instantiation operation of the above two classes
  41. class CDFactory {
  42. public static function create($type) {
  43. $class = strtolower($type) . "CD";
  44. return new $class ;
  45. }
  46. }
  47. //Instance operation
  48. $type = "enhadced";
  49. $cd = CDFactory::create($type);
  50. $tracksFromExternalSource = array("What It Means", "Brr", "Goodbye");
  51. $cd->setBand("Never Again");
  52. $cd->setTitle("Waste of a Rib");
  53. foreach ($tracksFromExternalSource as $track) {
  54. $cd- >addTrack($track);
  55. }
  56. /* End of Factory.class.php */
  57. /* End of file Design/Factory.class.php */
Copy code
  1. ?/**
  2. * Reprinted from "PHP Design Patterns" Chapter 10: Interpreter Pattern
  3. * Interpreter: The interpreter design pattern is used to analyze the key elements of an entity and provide its own explanation or corresponding action for each element.
  4. * The interpreter design pattern is most commonly used in PHP/HTML template systems.
  5. *
  6. */
  7. class User {
  8. protected $_username = "";
  9. public function __construct($username) {
  10. $this->_username = $ username;
  11. }
  12. public function getProfilePage() {
  13. $profile = "

    I like Never Again !

    ";
  14. $profile .= "I love all of their songs. My favorite CD:
    ";
  15. $profile .= "{{myCD.getTitle}}!!";
  16. return $profile;
  17. }
  18. }
  19. class userCD {
  20. protected $_user = NULL;
  21. public function setUser(User $user) {
  22. $this->_user = $user;
  23. }
  24. public function getTitle() {
  25. $title = "Waste of a Rib";
  26. return $title;
  27. }
  28. }
  29. class userCDInterpreter {
  30. protected $_user = NULL;
  31. public function setUser(User $user) {
  32. $this->_user = $user;
  33. }
  34. public function getInterpreted() {
  35. $profile = $this->_user->getProfilePage();
  36. if (preg_match_all('/{{myCD.(.*?)}}/', $profile, $triggers, PREG_SET_ORDER)) {
  37. $replacements = array ();
  38. foreach ($triggers as $trigger) {
  39. $replacements[] = $trigger[1];
  40. }
  41. $replacements = array_unique($replacements);
  42. $myCD = new userCD();
  43. $myCD->setUser($this->_user);
  44. foreach ($replacements as $replacement) {
  45. $profile = str_replace("{{myCD.{$replacement}}}", call_user_func(array($ myCD, $replacement)), $profile);
  46. }
  47. }
  48. return $profile;
  49. }
  50. }
  51. $username = "aaron";
  52. $user = new User($username);
  53. $interpreter = new userCDInterpreter();
  54. $interpreter->setUser($user);
  55. print "

    {$username}'s Profile

    ";
  56. print $interpreter->getInterpreted();
  57. /* End of Interpreter.class.php */
  58. /* Location the file Design/Interpreter.class.php */
Copy code
  1. ?/**
  2. * Reprinted from "PHP Design Patterns" Chapter 11: Iterator Pattern
  3. * Iterator: The iterator design pattern helps construct specific objects that can provide a single standard interface for looping or iterating any type of countable data.
  4. * When dealing with countable data that needs to be traversed, the best solution is to create an object based on the iterator design pattern.
  5. *
  6. */
  7. class CD {
  8. public $band = "";
  9. public $title = "";
  10. public $trackList = array();
  11. public function __construct($band, $title) {
  12. $this->band = $band;
  13. $this->title = $title;
  14. }
  15. public function addTrack($track) {
  16. $this->trackList[] = $track;
  17. }
  18. }
  19. class CDSearchByBandIterator implements Iterator {
  20. private $_CDs = array();
  21. private $_valid = FALSE;
  22. public function __construct($bandName) {
  23. $db = mysql_connect("localhost", "root", "root");
  24. mysql_select_db("test");
  25. $sql = "select CD.id, CD.band, CD.title, tracks.tracknum, tracks.title as tracktitle ";
  26. $sql .= "from CD left join tracks on CD.id = tracks.cid ";
  27. $sql .= "where band = '" . mysql_real_escape_string($bandName) . "' ";
  28. $sql .= "order by tracks.tracknum";
  29. $results = mysql_query($sql);
  30. $cdID = 0;
  31. $cd = NULL;
  32. while ($result = mysql_fetch_array($results)) {
  33. if ($result["id"] !== $cdID) {
  34. if ( ! is_null($cd)) {
  35. $this->_CDs[] = $cd;
  36. }
  37. $cdID = $result['id'];
  38. $cd = new CD($result['band'], $result['title']);
  39. }
  40. $cd->addTrack($result['tracktitle']);
  41. }
  42. $this->_CDs[] = $cd;
  43. }
  44. public function next() {
  45. $this->_valid = (next($this->_CDs) === FALSE) ? FALSE : TRUE;
  46. }
  47. public function rewind() {
  48. $this->_valid = (reset($this->_CDs) === FALSE) ? FALSE : TRUE;
  49. }
  50. public function valid() {
  51. return $this->_valid;
  52. }
  53. public function current() {
  54. return current($this->_CDs);
  55. }
  56. public function key() {
  57. return key($this->_CDs);
  58. }
  59. }
  60. $queryItem = "Never Again";
  61. $cds = new CDSearchByBandIterator($queryItem);
  62. print "

    Found the Following CDs

    ";
  63. print "";
  64. foreach ($cds as $cd) {
  65. print "
  66. ";
  67. }
  68. print "
  69. BandTtileNum Tracks
    {$cd->band}{$cd->title}";
  70. print count($cd->trackList). "
  71. ";
  72. /* End of Iterator.class.php */
  73. /* Location the file Design/Iterator.class.php */
复制代码
  1. ?/**
  2. * Reprinted from "PHP Design Patterns" Chapter 12: Mediator Pattern
  3. * Mediator: Mediator design should not be used to develop an object that can transmit or mediate interactions between similar objects without direct interaction with each other. Modifications to collections of these objects
  4. * When dealing with uncoupled objects that have similar properties and whose properties need to be kept in sync, the best practice is to use objects based on the Mediator design pattern.
  5. *
  6. */
  7. /**
  8. * Test case description: The sample code not only allows the band to enter and manage their music collection, but also allows the band to update their configuration files, modify band related information and update their CD information
  9. *     Artists can now upload MP3 collections and download them from the Web The site pulled the CD. Therefore, the Web site needs to keep the corresponding CDs and MP3s synchronized with each other.
  10. *
  11. */
  12. //CD类
  13. class CD {
  14. public $band = '';
  15. public $title = '';
  16. protected $_mediator;
  17. public function __construct(MusicContainerMediator $mediator = NULL) {
  18. $this->_mediator = $mediator;
  19. }
  20. public function save() {
  21. //具体实现待定
  22. var_dump($this);
  23. }
  24. public function changeBandName($bandname) {
  25. if ( ! is_null($this->_mediator)) {
  26. $this->_mediator->change($this, array("band" => $bandname));
  27. }
  28. $this->band = $bandname;
  29. $this->save();
  30. }
  31. }
  32. //MP3Archive类
  33. class MP3Archive {
  34. protected $_mediator;
  35. public function __construct(MusicContainerMediator $mediator = NULL) {
  36. $this->_mediator = $mediator;
  37. }
  38. public function save() {
  39. //具体实现待定
  40. var_dump($this);
  41. }
  42. public function changeBandName($bandname) {
  43. if ( ! is_null($this->_mediator)) {
  44. $this->_mediator->change($this, array("band" => $bandname));
  45. }
  46. $this->band = $bandname;
  47. $this->save();
  48. }
  49. }
  50. //中介者类
  51. class MusicContainerMediator {
  52. protected $_containers = array();
  53. public function __construct() {
  54. $this->_containers[] = "CD";
  55. $this->_containers[] = "MP3Archive";
  56. }
  57. public function change($originalObject, $newValue) {
  58. $title = $originalObject->title;
  59. $band = $originalObject->band;
  60. foreach ($this->_containers as $container) {
  61. if ( ! ($originalObject instanceof $container)) {
  62. $object = new $container;
  63. $object->title = $title;
  64. $object->band = $band;
  65. foreach ($newValue as $key => $val) {
  66. $object->$key = $val;
  67. }
  68. $object->save();
  69. }
  70. }
  71. }
  72. }
  73. //测试实例
  74. $titleFromDB = "Waste of a Rib";
  75. $bandFromDB = "Never Again";
  76. $mediator = new MusicContainerMediator();
  77. $cd = new CD($mediator);
  78. $cd->title = $titleFromDB;
  79. $cd->band = $bandFromDB;
  80. $cd->changeBandName("Maybe Once More");
  81. /* End of Mediator.class.php */
  82. /* Location the file Design/Mediator.class.php */
复制代码
  1. /*
  2. SQLyog 企业版 - MySQL GUI v8.14
  3. MySQL - 5.1.52-community : Database - test
  4. *********************************************************************
  5. */
  6. /*!40101 SET NAMES utf8 */;
  7. /*!40101 SET SQL_MODE=''*/;
  8. /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
  9. /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
  10. /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
  11. /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
  12. /*Table structure for table `cd` */
  13. DROP TABLE IF EXISTS `cd`;
  14. CREATE TABLE `cd` (
  15. `id` int(8) NOT NULL AUTO_INCREMENT,
  16. `band` varchar(500) COLLATE latin1_bin NOT NULL DEFAULT '',
  17. `title` varchar(500) COLLATE latin1_bin NOT NULL DEFAULT '',
  18. `bought` int(8) DEFAULT NULL,
  19. `amount` int(8) DEFAULT NULL,
  20. PRIMARY KEY (`id`)
  21. ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
  22. /*Data for the table `cd` */
  23. insert into `cd`(`id`,`band`,`title`,`bought`,`amount`) values (1,'Never Again','Waster of a Rib',1,98);
  24. /*Table structure for table `tracks` */
  25. DROP TABLE IF EXISTS `tracks`;
  26. CREATE TABLE `tracks` (
  27. `cid` int(8) DEFAULT NULL,
  28. `tracknum` int(8) DEFAULT NULL,
  29. `title` varchar(500) COLLATE latin1_bin NOT NULL DEFAULT ''
  30. ) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
  31. /*Data for the table `tracks` */
  32. insert into `tracks`(`cid`,`tracknum`,`title`) values (1,3,'What It Means'),(1,3,'Brr'),(1,3,'Goodbye');
  33. /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
  34. /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
  35. /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
  36. /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
复制代码


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn