├── README.md ├── behavioral-patterns ├── chain-of-responsibility.php ├── command.php ├── interpreter.php ├── iterator.php ├── mediator.php ├── momento.php ├── observer.php ├── state.php ├── strategy.php ├── template-method.php └── visitor.php ├── creational-patterns ├── abstract-factory.php ├── builder.php ├── factory-method.php ├── prototype.php └── singleton.php └── structural-patterns ├── adapter.php ├── bridge.php ├── composite.php ├── decorator.php ├── facade.php ├── flyweight.php ├── null_object.php └── proxy.php /README.md: -------------------------------------------------------------------------------- 1 | ## Design Patterns in PHP with Real Examples 2 | In this repo you can find all familiar design patterns that uses in most php frameworks. 3 | Design patterns divided into three categories as below : 4 | 5 | Creational 6 | ---------- 7 | 8 | - [**Abstract Factory**](https://github.com/ehsangazar/design-patterns-php/blob/master/creational-patterns/abstract-factory.php) 9 | - [**Builder**](https://github.com/ehsangazar/design-patterns-php/blob/master/creational-patterns/builder.php) 10 | - [**Factory Method**](https://github.com/ehsangazar/design-patterns-php/blob/master/creational-patterns/factory-method.php) 11 | - [**Prototype**](https://github.com/ehsangazar/design-patterns-php/blob/master/creational-patterns/prototype.php) 12 | - [**Singleton**](https://github.com/ehsangazar/design-patterns-php/blob/master/creational-patterns/singleton.php) 13 | 14 | 15 | Structural 16 | ---------- 17 | 18 | - [**Adapter**](https://github.com/ehsangazar/design-patterns-php/blob/master/structural-patterns/adapter.php) 19 | - [**Bridge**](https://github.com/ehsangazar/design-patterns-php/blob/master/structural-patterns/bridge.php) 20 | - [**Composite**](https://github.com/ehsangazar/design-patterns-php/blob/master/structural-patterns/composite.php) 21 | - [**Decorator**](https://github.com/ehsangazar/design-patterns-php/blob/master/structural-patterns/decorator.php) 22 | - [**Facade**](https://github.com/ehsangazar/design-patterns-php/blob/master/structural-patterns/facade.php) 23 | - [**Flyweight**](https://github.com/ehsangazar/design-patterns-php/blob/master/structural-patterns/flyweight.php) 24 | - [**Null Object**](https://github.com/ehsangazar/design-patterns-php/blob/master/structural-patterns/null_object.php) 25 | - [**Proxy**](https://github.com/ehsangazar/design-patterns-php/blob/master/structural-patterns/proxy.php) 26 | 27 | Behavioral 28 | ---------- 29 | 30 | - [**Chain Of Responsibility**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/chain-of-responsibility.php) 31 | - [**Command**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/command.php) 32 | - [**Interpreter**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/interpreter.php) 33 | - [**Iterator**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/iterator.php) 34 | - [**Mediator**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/mediator.php) 35 | - [**Momento**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/momento.php) 36 | - [**Observer**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/observer.php) 37 | - [**State**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/state.php) 38 | - [**Strategy**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/strategy.php) 39 | - [**Template Method**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/template-method.php) 40 | - [**Visitor**](https://github.com/ehsangazar/design-patterns-php/blob/master/behavioral-patterns/visitor.php) 41 | -------------------------------------------------------------------------------- /behavioral-patterns/chain-of-responsibility.php: -------------------------------------------------------------------------------- 1 | topic = $topic_in; 14 | $this->title = NULL; 15 | } 16 | function getTopic() { 17 | return $this->topic; 18 | } 19 | //this is the end of the chain - returns title or says there is none 20 | function getTitle() { 21 | if (NULL != $this->title) { 22 | return $this->title; 23 | } else { 24 | return 'there is no title avaialble'; 25 | } 26 | } 27 | function setTitle($title_in) {$this->title = $title_in;} 28 | } 29 | 30 | class BookSubTopic extends AbstractBookTopic { 31 | private $topic; 32 | private $parentTopic; 33 | private $title; 34 | function __construct($topic_in, BookTopic $parentTopic_in) { 35 | $this->topic = $topic_in; 36 | $this->parentTopic = $parentTopic_in; 37 | $this->title = NULL; 38 | } 39 | function getTopic() { 40 | return $this->topic; 41 | } 42 | function getParentTopic() { 43 | return $this->parentTopic; 44 | } 45 | function getTitle() { 46 | if (NULL != $this->title) { 47 | return $this->title; 48 | } else { 49 | return $this->parentTopic->getTitle(); 50 | } 51 | } 52 | function setTitle($title_in) {$this->title = $title_in;} 53 | } 54 | 55 | class BookSubSubTopic extends AbstractBookTopic { 56 | private $topic; 57 | private $parentTopic; 58 | private $title; 59 | function __construct($topic_in, BookSubTopic $parentTopic_in) { 60 | $this->topic = $topic_in; 61 | $this->parentTopic = $parentTopic_in; 62 | $this->title = NULL; 63 | } 64 | function getTopic() { 65 | return $this->topic; 66 | } 67 | function getParentTopic() { 68 | return $this->parentTopic; 69 | } 70 | function getTitle() { 71 | if (NULL != $this->title) { 72 | return $this->title; 73 | } else { 74 | return $this->parentTopic->getTitle(); 75 | } 76 | } 77 | function setTitle($title_in) {$this->title = $title_in;} 78 | } 79 | 80 | writeln("BEGIN TESTING CHAIN OF RESPONSIBILITY PATTERN"); 81 | writeln(""); 82 | 83 | $bookTopic = new BookTopic("PHP 5"); 84 | writeln("bookTopic before title is set:"); 85 | writeln("topic: " . $bookTopic->getTopic()); 86 | writeln("title: " . $bookTopic->getTitle()); 87 | writeln(""); 88 | 89 | $bookTopic->setTitle("PHP 5 Recipes by Babin, Good, Kroman, and Stephens"); 90 | writeln("bookTopic after title is set: "); 91 | writeln("topic: " . $bookTopic->getTopic()); 92 | writeln("title: " . $bookTopic->getTitle()); 93 | writeln(""); 94 | 95 | $bookSubTopic = new BookSubTopic("PHP 5 Patterns",$bookTopic); 96 | writeln("bookSubTopic before title is set: "); 97 | writeln("topic: " . $bookSubTopic->getTopic()); 98 | writeln("title: " . $bookSubTopic->getTitle()); 99 | writeln(""); 100 | 101 | $bookSubTopic->setTitle("PHP 5 Objects Patterns and Practice by Zandstra"); 102 | writeln("bookSubTopic after title is set: "); 103 | writeln("topic: ". $bookSubTopic->getTopic()); 104 | writeln("title: ". $bookSubTopic->getTitle()); 105 | writeln(""); 106 | 107 | $bookSubSubTopic = new BookSubSubTopic("PHP 5 Patterns for Cats", 108 | $bookSubTopic); 109 | writeln("bookSubSubTopic with no title set: "); 110 | writeln("topic: " . $bookSubSubTopic->getTopic()); 111 | writeln("title: " . $bookSubSubTopic->getTitle()); 112 | writeln(""); 113 | 114 | $bookSubTopic->setTitle(NULL); 115 | writeln("bookSubSubTopic with no title for set for bookSubTopic either:"); 116 | writeln("topic: " . $bookSubSubTopic->getTopic()); 117 | writeln("title: " . $bookSubSubTopic->getTitle()); 118 | writeln(""); 119 | 120 | writeln("END TESTING CHAIN OF RESPONSIBILITY PATTERN"); 121 | 122 | function writeln($line_in) { 123 | echo $line_in."
"; 124 | } -------------------------------------------------------------------------------- /behavioral-patterns/command.php: -------------------------------------------------------------------------------- 1 | setAuthor($author_in); 8 | $this->setTitle($title_in); 9 | } 10 | function getAuthor() { 11 | return $this->author; 12 | } 13 | function setAuthor($author_in) { 14 | $this->author = $author_in; 15 | } 16 | function getTitle() { 17 | return $this->title; 18 | } 19 | function setTitle($title_in) { 20 | $this->title = $title_in; 21 | } 22 | function setStarsOn() { 23 | $this->setAuthor(Str_replace(' ','*',$this->getAuthor())); 24 | $this->setTitle(Str_replace(' ','*',$this->getTitle())); 25 | } 26 | function setStarsOff() { 27 | $this->setAuthor(Str_replace('*',' ',$this->getAuthor())); 28 | $this->setTitle(Str_replace('*',' ',$this->getTitle())); 29 | } 30 | function getAuthorAndTitle() { 31 | return $this->getTitle().' by '.$this->getAuthor(); 32 | } 33 | } 34 | 35 | abstract class BookCommand { 36 | protected $bookCommandee; 37 | function __construct($bookCommandee_in) { 38 | $this->bookCommandee = $bookCommandee_in; 39 | } 40 | abstract function execute(); 41 | } 42 | 43 | class BookStarsOnCommand extends BookCommand { 44 | function execute() { 45 | $this->bookCommandee->setStarsOn(); 46 | } 47 | } 48 | 49 | class BookStarsOffCommand extends BookCommand { 50 | function execute() { 51 | $this->bookCommandee->setStarsOff(); 52 | } 53 | } 54 | 55 | writeln('BEGIN TESTING COMMAND PATTERN'); 56 | writeln(''); 57 | 58 | $book = new BookCommandee('Design Patterns', 'Gamma, Helm, Johnson, and Vlissides'); 59 | writeln('book after creation: '); 60 | writeln($book->getAuthorAndTitle()); 61 | writeln(''); 62 | 63 | $starsOn = new BookStarsOnCommand($book); 64 | callCommand($starsOn); 65 | writeln('book after stars on: '); 66 | writeln($book->getAuthorAndTitle()); 67 | writeln(''); 68 | 69 | $starsOff = new BookStarsOffCommand($book); 70 | callCommand($starsOff); 71 | writeln('book after stars off: '); 72 | writeln($book->getAuthorAndTitle()); 73 | writeln(''); 74 | 75 | writeln('END TESTING COMMAND PATTERN'); 76 | 77 | // the callCommand function demonstrates that a specified 78 | // function in BookCommandee can be executed with only 79 | // an instance of BookCommand. 80 | function callCommand(BookCommand $bookCommand_in) { 81 | $bookCommand_in->execute(); 82 | } 83 | 84 | function writeln($line_in) { 85 | echo $line_in."
"; 86 | } 87 | -------------------------------------------------------------------------------- /behavioral-patterns/interpreter.php: -------------------------------------------------------------------------------- 1 | bookList = $bookListIn; 7 | } 8 | public function interpret($stringIn) { 9 | $arrayIn = explode(" ",$stringIn); 10 | $returnString = NULL; 11 | // go through the array validating 12 | // and if possible calling a book method 13 | // could use refactoring, some duplicate logic 14 | if ('book' == $arrayIn[0]) { 15 | if ('author' == $arrayIn[1]) { 16 | if (is_numeric($arrayIn[2])) { 17 | $book = $this->bookList->getBook($arrayIn[2]); 18 | if (NULL == $book) { 19 | $returnString = 'Can not process, there is no book # '.$arrayIn[2]; 20 | } else { 21 | $returnString = $book->getAuthor(); 22 | } 23 | } elseif ('title' == $arrayIn[2]) { 24 | if (is_numeric($arrayIn[3])) { 25 | $book = $this->bookList->getBook($arrayIn[3]); 26 | if (NULL == $book) { 27 | $returnString = 'Can not process, there is no book # '. 28 | $arrayIn[3]; 29 | } else { 30 | $returnString = $book->getAuthorAndTitle(); 31 | } 32 | } else { 33 | $returnString = 'Can not process, book # must be numeric.'; 34 | } 35 | } else { 36 | $returnString = 'Can not process, book # must be numeric.'; 37 | } 38 | } 39 | if ('title' == $arrayIn[1]) { 40 | if (is_numeric($arrayIn[2])) { 41 | $book = $this->bookList->getBook($arrayIn[2]); 42 | if (NULL == $book) { 43 | $returnString = 'Can not process, there is no book # '. 44 | $arrayIn[2]; 45 | } else { 46 | $returnString = $book->getTitle(); 47 | } 48 | } else { 49 | $returnString = 'Can not process, book # must be numeric.'; 50 | } 51 | } 52 | } else { 53 | $returnString = 'Can not process, can only process book author #, book title #, or book author title #'; 54 | } 55 | return $returnString; 56 | } 57 | } 58 | 59 | class BookList { 60 | private $books = array(); 61 | private $bookCount = 0; 62 | public function __construct() { 63 | } 64 | public function getBookCount() { 65 | return $this->bookCount; 66 | } 67 | private function setBookCount($newCount) { 68 | $this->bookCount = $newCount; 69 | } 70 | public function getBook($bookNumberToGet) { 71 | if ( (is_numeric($bookNumberToGet)) && 72 | ($bookNumberToGet <= $this->getBookCount())) { 73 | return $this->books[$bookNumberToGet]; 74 | } else { 75 | return NULL; 76 | } 77 | } 78 | public function addBook(Book $book_in) { 79 | $this->setBookCount($this->getBookCount() + 1); 80 | $this->books[$this->getBookCount()] = $book_in; 81 | return $this->getBookCount(); 82 | } 83 | public function removeBook(Book $book_in) { 84 | $counter = 0; 85 | while (++$counter <= $this->getBookCount()) { 86 | if ($book_in->getAuthorAndTitle() == 87 | $this->books[$counter]->getAuthorAndTitle()) 88 | { 89 | for ($x = $counter; $x < $this->getBookCount(); $x++) { 90 | $this->books[$x] = $this->books[$x + 1]; 91 | } 92 | $this->setBookCount($this->getBookCount() - 1); 93 | } 94 | } 95 | return $this->getBookCount(); 96 | } 97 | } 98 | 99 | class Book { 100 | private $author; 101 | private $title; 102 | function __construct($title_in, $author_in) { 103 | $this->author = $author_in; 104 | $this->title = $title_in; 105 | } 106 | function getAuthor() { 107 | return $this->author; 108 | } 109 | function getTitle() { 110 | return $this->title; 111 | } 112 | function getAuthorAndTitle() { 113 | return $this->getTitle().' by '.$this->getAuthor(); 114 | } 115 | } 116 | 117 | writeln('BEGIN TESTING INTERPRETER PATTERN'); 118 | writeln(''); 119 | 120 | //load BookList for test data 121 | $bookList = new BookList(); 122 | $inBook1 = new Book('PHP for Cats','Larry Truett'); 123 | $inBook2 = new Book('MySQL for Cats','Larry Truett'); 124 | $bookList->addBook($inBook1); 125 | $bookList->addBook($inBook2); 126 | 127 | $interpreter = new Interpreter($bookList); 128 | 129 | writeln('test 1 - invalid request missing "book"'); 130 | writeln($interpreter->interpret('author 1')); 131 | writeln(''); 132 | 133 | writeln('test 2 - valid book author request'); 134 | writeln($interpreter->interpret('book author 1')); 135 | writeln(''); 136 | 137 | writeln('test 3 - valid book title request'); 138 | writeln($interpreter->interpret('book title 2')); 139 | writeln(''); 140 | 141 | writeln('test 4 - valid book author title request'); 142 | writeln($interpreter->interpret('book author title 1')); 143 | writeln(''); 144 | 145 | writeln('test 5 - invalid request with invalid book number'); 146 | writeln($interpreter->interpret('book title 3')); 147 | writeln(''); 148 | 149 | writeln('test 6 - invalid request with nuo numeric book number'); 150 | writeln($interpreter->interpret('book title one')); 151 | writeln(''); 152 | 153 | writeln('END TESTING INTERPRETER PATTERN'); 154 | 155 | function writeln($line_in) { 156 | echo $line_in."
"; 157 | } 158 | -------------------------------------------------------------------------------- /behavioral-patterns/iterator.php: -------------------------------------------------------------------------------- 1 | author = $author_in; 8 | $this->title = $title_in; 9 | } 10 | function getAuthor() {return $this->author;} 11 | function getTitle() {return $this->title;} 12 | function getAuthorAndTitle() { 13 | return $this->getTitle() . ' by ' . $this->getAuthor(); 14 | } 15 | } 16 | 17 | class BookList { 18 | private $books = array(); 19 | private $bookCount = 0; 20 | public function __construct() { 21 | } 22 | public function getBookCount() { 23 | return $this->bookCount; 24 | } 25 | private function setBookCount($newCount) { 26 | $this->bookCount = $newCount; 27 | } 28 | public function getBook($bookNumberToGet) { 29 | if ( (is_numeric($bookNumberToGet)) && 30 | ($bookNumberToGet <= $this->getBookCount())) { 31 | return $this->books[$bookNumberToGet]; 32 | } else { 33 | return NULL; 34 | } 35 | } 36 | public function addBook(Book $book_in) { 37 | $this->setBookCount($this->getBookCount() + 1); 38 | $this->books[$this->getBookCount()] = $book_in; 39 | return $this->getBookCount(); 40 | } 41 | public function removeBook(Book $book_in) { 42 | $counter = 0; 43 | while (++$counter <= $this->getBookCount()) { 44 | if ($book_in->getAuthorAndTitle() == 45 | $this->books[$counter]->getAuthorAndTitle()) 46 | { 47 | for ($x = $counter; $x < $this->getBookCount(); $x++) { 48 | $this->books[$x] = $this->books[$x + 1]; 49 | } 50 | $this->setBookCount($this->getBookCount() - 1); 51 | } 52 | } 53 | return $this->getBookCount(); 54 | } 55 | } 56 | 57 | class BookListIterator { 58 | protected $bookList; 59 | protected $currentBook = 0; 60 | 61 | public function __construct(BookList $bookList_in) { 62 | $this->bookList = $bookList_in; 63 | } 64 | public function getCurrentBook() { 65 | if (($this->currentBook > 0) && 66 | ($this->bookList->getBookCount() >= $this->currentBook)) { 67 | return $this->bookList->getBook($this->currentBook); 68 | } 69 | } 70 | public function getNextBook() { 71 | if ($this->hasNextBook()) { 72 | return $this->bookList->getBook(++$this->currentBook); 73 | } else { 74 | return NULL; 75 | } 76 | } 77 | public function hasNextBook() { 78 | if ($this->bookList->getBookCount() > $this->currentBook) { 79 | return TRUE; 80 | } else { 81 | return FALSE; 82 | } 83 | } 84 | } 85 | 86 | class BookListReverseIterator extends BookListIterator { 87 | public function __construct(BookList $bookList_in) { 88 | $this->bookList = $bookList_in; 89 | $this->currentBook = $this->bookList->getBookCount() + 1; 90 | } 91 | public function getNextBook() { 92 | if ($this->hasNextBook()) { 93 | return $this->bookList->getBook(--$this->currentBook); 94 | } else { 95 | return NULL; 96 | } 97 | } 98 | public function hasNextBook() { 99 | if (1 < $this->currentBook) { 100 | return TRUE; 101 | } else { 102 | return FALSE; 103 | } 104 | } 105 | } 106 | 107 | 108 | writeln('BEGIN TESTING ITERATOR PATTERN'); 109 | writeln(''); 110 | 111 | $firstBook = new Book('Core PHP Programming, Third Edition', 'Atkinson and Suraski'); 112 | $secondBook = new Book('PHP Bible', 'Converse and Park'); 113 | $thirdBook = new Book('Design Patterns', 'Gamma, Helm, Johnson, and Vlissides'); 114 | 115 | $books = new BookList(); 116 | $books->addBook($firstBook); 117 | $books->addBook($secondBook); 118 | $books->addBook($thirdBook); 119 | 120 | writeln('Testing the Iterator'); 121 | 122 | $booksIterator = new BookListIterator($books); 123 | 124 | while ($booksIterator->hasNextBook()) { 125 | $book = $booksIterator->getNextBook(); 126 | writeln('getting next book with iterator :'); 127 | writeln($book->getAuthorAndTitle()); 128 | writeln(''); 129 | } 130 | 131 | $book = $booksIterator->getCurrentBook(); 132 | writeln('getting current book with iterator :'); 133 | writeln($book->getAuthorAndTitle()); 134 | writeln(''); 135 | 136 | writeln('Testing the Reverse Iterator'); 137 | 138 | $booksReverseIterator = new BookListReverseIterator($books); 139 | 140 | while ($booksReverseIterator->hasNextBook()) { 141 | $book = $booksReverseIterator->getNextBook(); 142 | writeln('getting next book with reverse iterator :'); 143 | writeln($book->getAuthorAndTitle()); 144 | writeln(''); 145 | } 146 | 147 | $book = $booksReverseIterator->getCurrentBook(); 148 | writeln('getting current book with reverse iterator :'); 149 | writeln($book->getAuthorAndTitle()); 150 | writeln(''); 151 | 152 | writeln('END TESTING ITERATOR PATTERN'); 153 | 154 | function writeln($line_in) { 155 | echo $line_in."
"; 156 | } 157 | -------------------------------------------------------------------------------- /behavioral-patterns/mediator.php: -------------------------------------------------------------------------------- 1 | authorObject = new BookAuthorColleague($author_in,$this); 8 | $this->titleObject = new BookTitleColleague($title_in,$this); 9 | } 10 | function getAuthor() {return $this->authorObject;} 11 | function getTitle() {return $this->titleObject;} 12 | // when title or author change case, this makes sure the other 13 | // stays in sync 14 | function change(BookColleague $changingClassIn) { 15 | if ($changingClassIn instanceof BookAuthorColleague) { 16 | if ('upper' == $changingClassIn->getState()) { 17 | if ('upper' != $this->getTitle()->getState()) { 18 | $this->getTitle()->setTitleUpperCase(); 19 | } 20 | } elseif ('lower' == $changingClassIn->getState()) { 21 | if ('lower' != $this->getTitle()->getState()) { 22 | $this->getTitle()->setTitleLowerCase(); 23 | } 24 | } 25 | } elseif ($changingClassIn instanceof BookTitleColleague) { 26 | if ('upper' == $changingClassIn->getState()) { 27 | if ('upper' != $this->getAuthor()->getState()) { 28 | $this->getAuthor()->setAuthorUpperCase(); 29 | } 30 | } elseif ('lower' == $changingClassIn->getState()) { 31 | if ('lower' != $this->getAuthor()->getState()) { 32 | $this->getAuthor()->setAuthorLowerCase(); 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | abstract class BookColleague { 40 | private $mediator; 41 | function __construct($mediator_in) { 42 | $this->mediator = $mediator_in; 43 | } 44 | function getMediator() {return $this->mediator;} 45 | function changed($changingClassIn) { 46 | getMediator()->titleChanged($changingClassIn); 47 | } 48 | } 49 | 50 | class BookAuthorColleague extends BookColleague { 51 | private $author; 52 | private $state; 53 | function __construct($author_in, $mediator_in) { 54 | $this->author = $author_in; 55 | parent::__construct($mediator_in); 56 | } 57 | function getAuthor() {return $this->author;} 58 | function setAuthor($author_in) {$this->author = $author_in;} 59 | function getState() {return $this->state;} 60 | function setState($state_in) {$this->state = $state_in;} 61 | function setAuthorUpperCase() { 62 | $this->setAuthor(strtoupper($this->getAuthor())); 63 | $this->setState('upper'); 64 | $this->getMediator()->change($this); 65 | } 66 | function setAuthorLowerCase() { 67 | $this->setAuthor(strtolower($this->getAuthor())); 68 | $this->setState('lower'); 69 | $this->getMediator()->change($this); 70 | } 71 | } 72 | 73 | class BookTitleColleague extends BookColleague { 74 | private $title; 75 | private $state; 76 | function __construct($title_in, $mediator_in) { 77 | $this->title = $title_in; 78 | parent::__construct($mediator_in); 79 | } 80 | function getTitle() {return $this->title;} 81 | function setTitle($title_in) {$this->title = $title_in;} 82 | function getState() {return $this->state;} 83 | function setState($state_in) {$this->state = $state_in;} 84 | function setTitleUpperCase() { 85 | $this->setTitle(strtoupper($this->getTitle())); 86 | $this->setState('upper'); 87 | $this->getMediator()->change($this); 88 | } 89 | function setTitleLowerCase() { 90 | $this->setTitle(strtolower($this->getTitle())); 91 | $this->setState('lower'); 92 | $this->getMediator()->change($this); 93 | } 94 | } 95 | 96 | writeln('BEGIN TESTING MEDIATOR PATTERN'); 97 | writeln(''); 98 | 99 | $mediator = new BookMediator('Gamma, Helm, Johnson, and Vlissides', 'Design Patterns'); 100 | 101 | $author = $mediator->getAuthor(); 102 | $title = $mediator->getTitle(); 103 | 104 | writeln('Original Author and Title: '); 105 | writeln('author: ' . $author->getAuthor()); 106 | writeln('title: ' . $title->getTitle()); 107 | writeln(''); 108 | 109 | $author->setAuthorLowerCase(); 110 | 111 | writeln('After Author set to Lower Case: '); 112 | writeln('author: ' . $author->getAuthor()); 113 | writeln('title: ' . $title->getTitle()); 114 | writeln(''); 115 | 116 | $title->setTitleUpperCase(); 117 | 118 | writeln('After Title set to Upper Case: '); 119 | writeln('author: ' . $author->getAuthor()); 120 | writeln('title: ' . $title->getTitle()); 121 | writeln(''); 122 | 123 | writeln('END TESTING MEDIATOR PATTERN'); 124 | 125 | function writeln($line_in) { 126 | echo $line_in.'
'; 127 | } 128 | -------------------------------------------------------------------------------- /behavioral-patterns/momento.php: -------------------------------------------------------------------------------- 1 | setPage($page_in); 8 | $this->setTitle($title_in); 9 | } 10 | public function getPage() { 11 | return $this->page; 12 | } 13 | public function setPage($page_in) { 14 | $this->page = $page_in; 15 | } 16 | public function getTitle() { 17 | return $this->title; 18 | } 19 | public function setTitle($title_in) { 20 | $this->title = $title_in; 21 | } 22 | } 23 | 24 | class BookMark { 25 | private $title; 26 | private $page; 27 | function __construct(BookReader $bookReader) { 28 | $this->setPage($bookReader); 29 | $this->setTitle($bookReader); 30 | } 31 | public function getPage(BookReader $bookReader) { 32 | $bookReader->setPage($this->page); 33 | } 34 | public function setPage(BookReader $bookReader) { 35 | $this->page = $bookReader->getPage(); 36 | } 37 | public function getTitle(BookReader $bookReader) { 38 | $bookReader->setTitle($this->title); 39 | } 40 | public function setTitle(BookReader $bookReader) { 41 | $this->title = $bookReader->getTitle(); 42 | } 43 | } 44 | 45 | // Client 46 | 47 | writeln('BEGIN TESTING MEMENTO PATTERN'); 48 | writeln(''); 49 | 50 | $bookReader = new BookReader('Core PHP Programming, Third Edition','103'); 51 | $bookMark = new BookMark($bookReader); 52 | 53 | writeln('(at beginning) bookReader title: '.$bookReader->getTitle()); 54 | writeln('(at beginning) bookReader page: '.$bookReader->getPage()); 55 | 56 | $bookReader->setPage("104"); 57 | $bookMark->setPage($bookReader); 58 | writeln('(one page later) bookReader page: '.$bookReader->getPage()); 59 | 60 | $bookReader->setPage('2005'); //oops! a typo 61 | writeln('(after typo) bookReader page: '.$bookReader->getPage()); 62 | 63 | $bookMark->getPage($bookReader); 64 | writeln('(back to one page later) bookReader page: '.$bookReader->getPage()); 65 | writeln(''); 66 | 67 | writeln('END TESTING MEMENTO PATTERN'); 68 | 69 | function writeln($line_in) { 70 | echo $line_in."
"; 71 | } 72 | -------------------------------------------------------------------------------- /behavioral-patterns/observer.php: -------------------------------------------------------------------------------- 1 | "; 15 | } 16 | 17 | class PatternObserver extends AbstractObserver { 18 | public function __construct() { 19 | } 20 | public function update(AbstractSubject $subject) { 21 | writeln('*IN PATTERN OBSERVER - NEW PATTERN GOSSIP ALERT*'); 22 | writeln(' new favorite patterns: '.$subject->getFavorites()); 23 | writeln('*IN PATTERN OBSERVER - PATTERN GOSSIP ALERT OVER*'); 24 | } 25 | } 26 | 27 | class PatternSubject extends AbstractSubject { 28 | private $favoritePatterns = NULL; 29 | private $observers = array(); 30 | function __construct() { 31 | } 32 | function attach(AbstractObserver $observer_in) { 33 | //could also use array_push($this->observers, $observer_in); 34 | $this->observers[] = $observer_in; 35 | } 36 | function detach(AbstractObserver $observer_in) { 37 | //$key = array_search($observer_in, $this->observers); 38 | foreach($this->observers as $okey => $oval) { 39 | if ($oval == $observer_in) { 40 | unset($this->observers[$okey]); 41 | } 42 | } 43 | } 44 | function notify() { 45 | foreach($this->observers as $obs) { 46 | $obs->update($this); 47 | } 48 | } 49 | function updateFavorites($newFavorites) { 50 | $this->favorites = $newFavorites; 51 | $this->notify(); 52 | } 53 | function getFavorites() { 54 | return $this->favorites; 55 | } 56 | } 57 | 58 | writeln('BEGIN TESTING OBSERVER PATTERN'); 59 | writeln(''); 60 | 61 | $patternGossiper = new PatternSubject(); 62 | $patternGossipFan = new PatternObserver(); 63 | $patternGossiper->attach($patternGossipFan); 64 | $patternGossiper->updateFavorites('abstract factory, decorator, visitor'); 65 | $patternGossiper->updateFavorites('abstract factory, observer, decorator'); 66 | $patternGossiper->detach($patternGossipFan); 67 | $patternGossiper->updateFavorites('abstract factory, observer, paisley'); 68 | 69 | writeln('END TESTING OBSERVER PATTERN'); 70 | -------------------------------------------------------------------------------- /behavioral-patterns/state.php: -------------------------------------------------------------------------------- 1 | book = $book_in; 9 | $this->setTitleState(new BookTitleStateStars()); 10 | } 11 | public function getBookTitle() { 12 | return $this->bookTitleState->showTitle($this); 13 | } 14 | public function getBook() { 15 | return $this->book; 16 | } 17 | public function setTitleState($titleState_in) { 18 | $this->bookTitleState = $titleState_in; 19 | } 20 | } 21 | 22 | interface BookTitleStateInterface { 23 | public function showTitle($context_in); 24 | } 25 | 26 | class BookTitleStateExclaim implements BookTitleStateInterface { 27 | private $titleCount = 0; 28 | public function showTitle($context_in) { 29 | $title = $context_in->getBook()->getTitle(); 30 | $this->titleCount++; 31 | $context_in->setTitleState(new BookTitleStateStars()); 32 | return Str_replace(' ','!',$title); 33 | } 34 | } 35 | 36 | class BookTitleStateStars implements BookTitleStateInterface { 37 | private $titleCount = 0; 38 | public function showTitle($context_in) { 39 | $title = $context_in->getBook()->getTitle(); 40 | $this->titleCount++; 41 | if (1 < $this->titleCount) { 42 | $context_in->setTitleState(new BookTitleStateExclaim); 43 | } 44 | return Str_replace(' ','*',$title); 45 | } 46 | } 47 | 48 | class Book { 49 | private $author; 50 | private $title; 51 | function __construct($title_in, $author_in) { 52 | $this->author = $author_in; 53 | $this->title = $title_in; 54 | } 55 | function getAuthor() {return $this->author;} 56 | function getTitle() {return $this->title;} 57 | function getAuthorAndTitle() { 58 | return $this->getTitle() . ' by ' . $this->getAuthor(); 59 | } 60 | } 61 | 62 | writeln('BEGIN TESTING STATE PATTERN'); 63 | writeln(''); 64 | 65 | $book = new Book('PHP for Cats','Larry Truett');; 66 | $context = new bookContext($book); 67 | 68 | writeln('test 1 - show name'); 69 | writeln($context->getBookTitle()); 70 | writeln(''); 71 | 72 | writeln('test 2 - show name'); 73 | writeln($context->getBookTitle()); 74 | writeln(''); 75 | 76 | writeln('test 3 - show name'); 77 | writeln($context->getBookTitle()); 78 | writeln(''); 79 | 80 | writeln('test 4 - show name'); 81 | writeln($context->getBookTitle()); 82 | writeln(''); 83 | 84 | writeln('END TESTING STATE PATTERN'); 85 | 86 | function writeln($line_in) { 87 | echo $line_in."
"; 88 | } 89 | -------------------------------------------------------------------------------- /behavioral-patterns/strategy.php: -------------------------------------------------------------------------------- 1 | strategy = new StrategyCaps(); 10 | break; 11 | case "E": 12 | $this->strategy = new StrategyExclaim(); 13 | break; 14 | case "S": 15 | $this->strategy = new StrategyStars(); 16 | break; 17 | } 18 | } 19 | public function showBookTitle($book) { 20 | return $this->strategy->showTitle($book); 21 | } 22 | } 23 | 24 | interface StrategyInterface { 25 | public function showTitle($book_in); 26 | } 27 | 28 | class StrategyCaps implements StrategyInterface { 29 | public function showTitle($book_in) { 30 | $title = $book_in->getTitle(); 31 | $this->titleCount++; 32 | return strtoupper ($title); 33 | } 34 | } 35 | 36 | class StrategyExclaim implements StrategyInterface { 37 | public function showTitle($book_in) { 38 | $title = $book_in->getTitle(); 39 | $this->titleCount++; 40 | return Str_replace(' ','!',$title); 41 | } 42 | } 43 | 44 | class StrategyStars implements StrategyInterface { 45 | public function showTitle($book_in) { 46 | $title = $book_in->getTitle(); 47 | $this->titleCount++; 48 | return Str_replace(' ','*',$title); 49 | } 50 | } 51 | 52 | class Book { 53 | private $author; 54 | private $title; 55 | function __construct($title_in, $author_in) { 56 | $this->author = $author_in; 57 | $this->title = $title_in; 58 | } 59 | function getAuthor() { 60 | return $this->author; 61 | } 62 | function getTitle() { 63 | return $this->title; 64 | } 65 | function getAuthorAndTitle() { 66 | return $this->getTitle() . ' by ' . $this->getAuthor(); 67 | } 68 | } 69 | 70 | writeln('BEGIN TESTING STRATEGY PATTERN'); 71 | writeln(''); 72 | 73 | $book = new Book('PHP for Cats','Larry Truett'); 74 | 75 | $strategyContextC = new StrategyContext('C'); 76 | $strategyContextE = new StrategyContext('E'); 77 | $strategyContextS = new StrategyContext('S'); 78 | 79 | writeln('test 1 - show name context C'); 80 | writeln($strategyContextC->showBookTitle($book)); 81 | writeln(''); 82 | 83 | writeln('test 2 - show name context E'); 84 | writeln($strategyContextE->showBookTitle($book)); 85 | writeln(''); 86 | 87 | writeln('test 3 - show name context S'); 88 | writeln($strategyContextS->showBookTitle($book)); 89 | writeln(''); 90 | 91 | writeln('END TESTING STRATEGY PATTERN'); 92 | 93 | function writeln($line_in) { 94 | echo $line_in."
"; 95 | } 96 | -------------------------------------------------------------------------------- /behavioral-patterns/template-method.php: -------------------------------------------------------------------------------- 1 | getTitle(); 8 | $author = $book_in->getAuthor(); 9 | $processedTitle = $this->processTitle($title); 10 | $processedAuthor = $this->processAuthor($author); 11 | if (NULL == $processedAuthor) { 12 | $processed_info = $processedTitle; 13 | } else { 14 | $processed_info = $processedTitle.' by '.$processedAuthor; 15 | } 16 | return $processed_info; 17 | } 18 | //the primitive operation 19 | // this function must be overridded 20 | abstract function processTitle($title); 21 | //the hook operation 22 | // this function may be overridden, 23 | // but does nothing if it is not 24 | function processAuthor($author) { 25 | return NULL; 26 | } 27 | } 28 | 29 | class TemplateExclaim extends TemplateAbstract { 30 | function processTitle($title) { 31 | return Str_replace(' ','!!!',$title); 32 | } 33 | function processAuthor($author) { 34 | return Str_replace(' ','!!!',$author); 35 | } 36 | } 37 | 38 | class TemplateStars extends TemplateAbstract { 39 | function processTitle($title) { 40 | return Str_replace(' ','*',$title); 41 | } 42 | } 43 | 44 | class Book { 45 | private $author; 46 | private $title; 47 | function __construct($title_in, $author_in) { 48 | $this->author = $author_in; 49 | $this->title = $title_in; 50 | } 51 | function getAuthor() {return $this->author;} 52 | function getTitle() {return $this->title;} 53 | function getAuthorAndTitle() { 54 | return $this->getTitle() . ' by ' . $this->getAuthor(); 55 | } 56 | } 57 | 58 | writeln('BEGIN TESTING TEMPLATE PATTERN'); 59 | writeln(''); 60 | 61 | $book = new Book('PHP for Cats','Larry Truett'); 62 | 63 | $exclaimTemplate = new TemplateExclaim(); 64 | $starsTemplate = new TemplateStars(); 65 | 66 | writeln('test 1 - show exclaim template'); 67 | writeln($exclaimTemplate->showBookTitleInfo($book)); 68 | writeln(''); 69 | 70 | writeln('test 2 - show stars template'); 71 | writeln($starsTemplate->showBookTitleInfo($book)); 72 | writeln(''); 73 | 74 | writeln('END TESTING TEMPLATE PATTERN'); 75 | 76 | function writeln($line_in) { 77 | echo $line_in."
"; 78 | } 79 | -------------------------------------------------------------------------------- /behavioral-patterns/visitor.php: -------------------------------------------------------------------------------- 1 | author = $author_in; 12 | $this->title = $title_in; 13 | } 14 | function getAuthor() {return $this->author;} 15 | function getTitle() {return $this->title;} 16 | function accept(Visitor $visitorIn) { 17 | $visitorIn->visitBook($this); 18 | } 19 | } 20 | 21 | class SoftwareVisitee extends Visitee { 22 | private $title; 23 | private $softwareCompany; 24 | private $softwareCompanyURL; 25 | function __construct($title_in, $softwareCompany_in, $softwareCompanyURL_in) { 26 | $this->title = $title_in; 27 | $this->softwareCompany = $softwareCompany_in; 28 | $this->softwareCompanyURL = $softwareCompanyURL_in; 29 | } 30 | function getSoftwareCompany() {return $this->softwareCompany;} 31 | function getSoftwareCompanyURL() {return $this->softwareCompanyURL;} 32 | function getTitle() {return $this->title;} 33 | function accept(Visitor $visitorIn) { 34 | $visitorIn->visitSoftware($this); 35 | } 36 | } 37 | 38 | abstract class Visitor { 39 | abstract function visitBook(BookVisitee $bookVisitee_In); 40 | abstract function visitSoftware(SoftwareVisitee $softwareVisitee_In); 41 | } 42 | 43 | class PlainDescriptionVisitor extends Visitor { 44 | private $description = NULL; 45 | function getDescription() { 46 | return $this->description; 47 | } 48 | function setDescription($descriptionIn) { 49 | $this->description = $descriptionIn; 50 | } 51 | function visitBook(BookVisitee $bookVisiteeIn) { 52 | $this->setDescription($bookVisiteeIn->getTitle().'. written by '.$bookVisiteeIn->getAuthor()); 53 | } 54 | function visitSoftware(SoftwareVisitee $softwareVisiteeIn) { 55 | $this->setDescription($softwareVisiteeIn->getTitle(). 56 | '. made by '.$softwareVisiteeIn->getSoftwareCompany(). 57 | '. website at '.$softwareVisiteeIn->getSoftwareCompanyURL()); 58 | } 59 | } 60 | 61 | class FancyDescriptionVisitor extends Visitor { 62 | private $description = NULL; 63 | function getDescription() { return $this->description; } 64 | function setDescription($descriptionIn) { 65 | $this->description = $descriptionIn; 66 | } 67 | function visitBook(BookVisitee $bookVisiteeIn) { 68 | $this->setDescription($bookVisiteeIn->getTitle(). 69 | '...!*@*! written !*! by !@! '.$bookVisiteeIn->getAuthor()); 70 | } 71 | function visitSoftware(SoftwareVisitee $softwareVisiteeIn) { 72 | $this->setDescription($softwareVisiteeIn->getTitle(). 73 | '...!!! made !*! by !@@! '.$softwareVisiteeIn->getSoftwareCompany(). 74 | '...www website !**! at http://'.$softwareVisiteeIn->getSoftwareCompanyURL()); 75 | } 76 | } 77 | 78 | writeln('BEGIN TESTING VISITOR PATTERN'); 79 | writeln(''); 80 | 81 | $book = new BookVisitee('Design Patterns', 'Gamma, Helm, Johnson, and Vlissides'); 82 | $software = new SoftwareVisitee('Zend Studio', 'Zend Technologies', 'www.zend.com'); 83 | 84 | $plainVisitor = new PlainDescriptionVisitor(); 85 | 86 | acceptVisitor($book,$plainVisitor); 87 | writeln('plain description of book: '.$plainVisitor->getDescription()); 88 | acceptVisitor($software,$plainVisitor); 89 | writeln('plain description of software: '.$plainVisitor->getDescription()); 90 | writeln(''); 91 | 92 | $fancyVisitor = new FancyDescriptionVisitor(); 93 | 94 | acceptVisitor($book,$fancyVisitor); 95 | writeln('fancy description of book: '.$fancyVisitor->getDescription()); 96 | acceptVisitor($software,$fancyVisitor); 97 | writeln('fancy description of software: '.$fancyVisitor->getDescription()); 98 | 99 | writeln('END TESTING VISITOR PATTERN'); 100 | 101 | //double dispatch any visitor and visitee objects 102 | function acceptVisitor(Visitee $visitee_in, Visitor $visitor_in) { 103 | $visitee_in->accept($visitor_in); 104 | } 105 | 106 | function writeln($line_in) { 107 | echo $line_in."
"; 108 | } 109 | -------------------------------------------------------------------------------- /creational-patterns/abstract-factory.php: -------------------------------------------------------------------------------- 1 | get(); 45 | $shape->draw(); -------------------------------------------------------------------------------- /creational-patterns/builder.php: -------------------------------------------------------------------------------- 1 | page; 28 | } 29 | function setTitle($title_in) { 30 | $this->page_title = $title_in; 31 | } 32 | function setHeading($heading_in) { 33 | $this->page_heading = $heading_in; 34 | } 35 | function setText($text_in) { 36 | $this->page_text .= $text_in; 37 | } 38 | function formatPage() { 39 | $this->page = ''; 40 | $this->page .= ''.$this->page_title.''; 41 | $this->page .= ''; 42 | $this->page .= '

'.$this->page_heading.'

'; 43 | $this->page .= $this->page_text; 44 | $this->page .= ''; 45 | $this->page .= ''; 46 | } 47 | } 48 | 49 | class HTMLPageBuilder extends AbstractPageBuilder { 50 | private $page = NULL; 51 | function __construct() { 52 | $this->page = new HTMLPage(); 53 | } 54 | function setTitle($title_in) { 55 | $this->page->setTitle($title_in); 56 | } 57 | function setHeading($heading_in) { 58 | $this->page->setHeading($heading_in); 59 | } 60 | function setText($text_in) { 61 | $this->page->setText($text_in); 62 | } 63 | function formatPage() { 64 | $this->page->formatPage(); 65 | } 66 | function getPage() { 67 | return $this->page; 68 | } 69 | } 70 | 71 | class HTMLPageDirector extends AbstractPageDirector { 72 | private $builder = NULL; 73 | public function __construct(AbstractPageBuilder $builder_in) { 74 | $this->builder = $builder_in; 75 | } 76 | public function buildPage() { 77 | $this->builder->setTitle('Testing the HTMLPage'); 78 | $this->builder->setHeading('Testing the HTMLPage'); 79 | $this->builder->setText('Testing, testing, testing!'); 80 | $this->builder->setText('Testing, testing, testing, or!'); 81 | $this->builder->setText('Testing, testing, testing, more!'); 82 | $this->builder->formatPage(); 83 | } 84 | public function getPage() { 85 | return $this->builder->getPage(); 86 | } 87 | } 88 | 89 | writeln('BEGIN TESTING BUILDER PATTERN'); 90 | writeln(''); 91 | 92 | $pageBuilder = new HTMLPageBuilder(); 93 | $pageDirector = new HTMLPageDirector($pageBuilder); 94 | $pageDirector->buildPage(); 95 | $page = $pageDirector->GetPage(); 96 | writeln($page->showPage()); 97 | writeln(''); 98 | 99 | writeln('END TESTING BUILDER PATTERN'); 100 | 101 | function writeln($line_in) { 102 | echo $line_in."
"; 103 | } -------------------------------------------------------------------------------- /creational-patterns/factory-method.php: -------------------------------------------------------------------------------- 1 | vehicleMake = $make; 16 | $this->vehicleModel = $model; 17 | } 18 | 19 | public function getMakeAndModel() 20 | { 21 | return $this->vehicleMake . ' ' . $this->vehicleModel; 22 | } 23 | } 24 | 25 | class AutomobileFactory 26 | { 27 | public static function create($make, $model) 28 | { 29 | return new Automobile($make, $model); 30 | } 31 | } 32 | 33 | // have the factory create the Automobile object 34 | $Aventador = AutomobileFactory::create('Lomborghini', 'Aventador'); 35 | 36 | print_r($Aventador->getMakeAndModel()); // outputs "Lomborghinni Aventador" -------------------------------------------------------------------------------- /creational-patterns/prototype.php: -------------------------------------------------------------------------------- 1 | instance = ++self::$instances; 13 | } 14 | public function __clone() { 15 | $this->instance = ++self::$instances; 16 | } 17 | } 18 | 19 | class MyCloneable 20 | { 21 | public $object1; 22 | public $object2; 23 | function __clone() { 24 | // Force a copy of this->object, otherwise it will point to same object. 25 | $this->object1 = clone $this->object1; 26 | } 27 | } 28 | 29 | $obj = new MyCloneable(); 30 | 31 | $obj->object1 = new SubObject(); 32 | $obj->object2 = new SubObject(); 33 | 34 | $obj2 = clone $obj; 35 | 36 | print("Original Object:\n"); 37 | print_r($obj); 38 | 39 | print("Cloned Object:\n"); 40 | print_r($obj2); 41 | -------------------------------------------------------------------------------- /creational-patterns/singleton.php: -------------------------------------------------------------------------------- 1 | author = $author_in; 14 | $this->title = $title_in; 15 | } 16 | function getAuthor() { 17 | return $this->author; 18 | } 19 | function getTitle() { 20 | return $this->title; 21 | } 22 | } 23 | 24 | class BookAdapter { 25 | private $book; 26 | function __construct(SimpleBook $book_in) { 27 | $this->book = $book_in; 28 | } 29 | function getAuthorAndTitle() { 30 | return $this->book->getTitle().' by '.$this->book->getAuthor(); 31 | } 32 | } 33 | 34 | // client 35 | 36 | writeln('BEGIN TESTING ADAPTER PATTERN'); 37 | writeln(''); 38 | 39 | $book = new SimpleBook("Gamma, Helm, Johnson, and Vlissides", "Design Patterns"); 40 | $bookAdapter = new BookAdapter($book); 41 | writeln('Author and Title: '.$bookAdapter->getAuthorAndTitle()); 42 | writeln(''); 43 | 44 | writeln('END TESTING ADAPTER PATTERN'); 45 | 46 | function writeln($line_in) { 47 | echo $line_in."
"; 48 | } -------------------------------------------------------------------------------- /structural-patterns/bridge.php: -------------------------------------------------------------------------------- 1 | bbAuthor = $author_in; 17 | $this->bbTitle = $title_in; 18 | if ('STARS' == $choice_in) { 19 | $this->bbImp = new BridgeBookStarsImp(); 20 | } else { 21 | $this->bbImp = new BridgeBookCapsImp(); 22 | } 23 | } 24 | function showAuthor() { 25 | return $this->bbImp->showAuthor($this->bbAuthor); 26 | } 27 | function showTitle() { 28 | return $this->bbImp->showTitle($this->bbTitle); 29 | } 30 | } 31 | 32 | class BridgeBookAuthorTitle extends BridgeBook { 33 | function showAuthorTitle() { 34 | return $this->showAuthor() . "'s " . $this->showTitle(); 35 | } 36 | } 37 | 38 | class BridgeBookTitleAuthor extends BridgeBook { 39 | function showTitleAuthor() { 40 | return $this->showTitle() . ' by ' . $this->showAuthor(); 41 | } 42 | } 43 | 44 | abstract class BridgeBookImp { 45 | abstract function showAuthor($author); 46 | abstract function showTitle($title); 47 | } 48 | 49 | class BridgeBookCapsImp extends BridgeBookImp { 50 | function showAuthor($author_in) { 51 | return strtoupper($author_in); 52 | } 53 | function showTitle($title_in) { 54 | return strtoupper($title_in); 55 | } 56 | } 57 | 58 | class BridgeBookStarsImp extends BridgeBookImp { 59 | function showAuthor($author_in) { 60 | return Str_replace(" ","*",$author_in); 61 | } 62 | function showTitle($title_in) { 63 | return Str_replace(" ","*",$title_in); 64 | } 65 | } 66 | 67 | writeln('BEGIN TESTING BRIDGE PATTERN'); 68 | writeln(''); 69 | 70 | writeln('test 1 - author title with caps'); 71 | $book = new BridgeBookAuthorTitle('Larry Truett','PHP for Cats','CAPS'); 72 | writeln($book->showAuthorTitle()); 73 | writeln(''); 74 | 75 | writeln('test 2 - author title with stars'); 76 | $book = new BridgeBookAuthorTitle('Larry Truett','PHP for Cats','STARS'); 77 | writeln($book->showAuthorTitle()); 78 | writeln(''); 79 | 80 | writeln('test 3 - title author with caps'); 81 | $book = new BridgeBookTitleAuthor('Larry Truett','PHP for Cats','CAPS'); 82 | writeln($book->showTitleAuthor()); 83 | writeln(''); 84 | 85 | writeln('test 4 - title author with stars'); 86 | $book = new BridgeBookTitleAuthor('Larry Truett','PHP for Cats','STARS'); 87 | writeln($book->showTitleAuthor()); 88 | writeln(''); 89 | 90 | writeln('END TESTING BRIDGE PATTERN'); 91 | 92 | function writeln($line_in) { 93 | echo $line_in."
"; 94 | } -------------------------------------------------------------------------------- /structural-patterns/composite.php: -------------------------------------------------------------------------------- 1 | title = $title; 25 | $this->author = $author; 26 | } 27 | function getBookInfo($bookToGet) { 28 | if (1 == $bookToGet) { 29 | return $this->title." by ".$this->author; 30 | } else { 31 | return FALSE; 32 | } 33 | } 34 | function getBookCount() { 35 | return 1; 36 | } 37 | function setBookCount($newCount) { 38 | return FALSE; 39 | } 40 | function addBook($oneBook) { 41 | return FALSE; 42 | } 43 | function removeBook($oneBook) { 44 | return FALSE; 45 | } 46 | } 47 | 48 | class SeveralBooks extends OnTheBookShelf { 49 | private $oneBooks = array(); 50 | private $bookCount; 51 | public function __construct() { 52 | $this->setBookCount(0); 53 | } 54 | public function getBookCount() { 55 | return $this->bookCount; 56 | } 57 | public function setBookCount($newCount) { 58 | $this->bookCount = $newCount; 59 | } 60 | public function getBookInfo($bookToGet) { 61 | if ($bookToGet <= $this->bookCount) { 62 | return $this->oneBooks[$bookToGet]->getBookInfo(1); 63 | } else { 64 | return FALSE; 65 | } 66 | } 67 | public function addBook($oneBook) { 68 | $this->setBookCount($this->getBookCount() + 1); 69 | $this->oneBooks[$this->getBookCount()] = $oneBook; 70 | return $this->getBookCount(); 71 | } 72 | public function removeBook($oneBook) { 73 | $counter = 0; 74 | while (++$counter <= $this->getBookCount()) { 75 | if ($oneBook->getBookInfo(1) == 76 | $this->oneBooks[$counter]->getBookInfo(1)) { 77 | for ($x = $counter; $x < $this->getBookCount(); $x++) { 78 | $this->oneBooks[$x] = $this->oneBooks[$x + 1]; 79 | } 80 | $this->setBookCount($this->getBookCount() - 1); 81 | } 82 | } 83 | return $this->getBookCount(); 84 | } 85 | } 86 | 87 | writeln("BEGIN TESTING COMPOSITE PATTERN"); 88 | writeln(''); 89 | 90 | $firstBook = new OneBook('Core PHP Programming, Third Edition', 'Atkinson and Suraski'); 91 | writeln('(after creating first book) oneBook info: '); 92 | writeln($firstBook->getBookInfo(1)); 93 | writeln(''); 94 | 95 | $secondBook = new OneBook('PHP Bible', 'Converse and Park'); 96 | writeln('(after creating second book) oneBook info: '); 97 | writeln($secondBook->getBookInfo(1)); 98 | writeln(''); 99 | 100 | $thirdBook = new OneBook('Design Patterns', 'Gamma, Helm, Johnson, and Vlissides'); 101 | writeln('(after creating third book) oneBook info: '); 102 | writeln($thirdBook->getBookInfo(1)); 103 | writeln(''); 104 | 105 | $books = new SeveralBooks(); 106 | 107 | $booksCount = $books->addBook($firstBook); 108 | writeln('(after adding firstBook to books) SeveralBooks info : '); 109 | writeln($books->getBookInfo($booksCount)); 110 | writeln(''); 111 | 112 | $booksCount = $books->addBook($secondBook); 113 | writeln('(after adding secondBook to books) SeveralBooks info : '); 114 | writeln($books->getBookInfo($booksCount)); 115 | writeln(''); 116 | 117 | $booksCount = $books->addBook($thirdBook); 118 | writeln('(after adding thirdBook to books) SeveralBooks info : '); 119 | writeln($books->getBookInfo($booksCount)); 120 | writeln(''); 121 | 122 | $booksCount = $books->removeBook($firstBook); 123 | writeln('(after removing firstBook from books) SeveralBooks count : '); 124 | writeln($books->getBookCount()); 125 | writeln(''); 126 | 127 | writeln('(after removing firstBook from books) SeveralBooks info 1 : '); 128 | writeln($books->getBookInfo(1)); 129 | writeln(''); 130 | 131 | writeln('(after removing firstBook from books) SeveralBooks info 2 : '); 132 | writeln($books->getBookInfo(2)); 133 | writeln(''); 134 | 135 | writeln('END TESTING COMPOSITE PATTERN'); 136 | 137 | function writeln($line_in) { 138 | echo $line_in."
"; 139 | } 140 | -------------------------------------------------------------------------------- /structural-patterns/decorator.php: -------------------------------------------------------------------------------- 1 | author = $author_in; 14 | $this->title = $title_in; 15 | } 16 | function getAuthor() { 17 | return $this->author; 18 | } 19 | function getTitle() { 20 | return $this->title; 21 | } 22 | function getAuthorAndTitle() { 23 | return $this->getTitle().' by '.$this->getAuthor(); 24 | } 25 | } 26 | 27 | class BookTitleDecorator { 28 | protected $book; 29 | protected $title; 30 | public function __construct(Book $book_in) { 31 | $this->book = $book_in; 32 | $this->resetTitle(); 33 | } 34 | //doing this so original object is not altered 35 | function resetTitle() { 36 | $this->title = $this->book->getTitle(); 37 | } 38 | function showTitle() { 39 | return $this->title; 40 | } 41 | } 42 | 43 | class BookTitleExclaimDecorator extends BookTitleDecorator { 44 | private $btd; 45 | public function __construct(BookTitleDecorator $btd_in) { 46 | $this->btd = $btd_in; 47 | } 48 | function exclaimTitle() { 49 | $this->btd->title = "!" . $this->btd->title . "!"; 50 | } 51 | } 52 | 53 | class BookTitleStarDecorator extends BookTitleDecorator { 54 | private $btd; 55 | public function __construct(BookTitleDecorator $btd_in) { 56 | $this->btd = $btd_in; 57 | } 58 | function starTitle() { 59 | $this->btd->title = Str_replace(" ","*",$this->btd->title); 60 | } 61 | } 62 | 63 | writeln('BEGIN TESTING DECORATOR PATTERN'); 64 | writeln(''); 65 | 66 | $patternBook = new Book('Gamma, Helm, Johnson, and Vlissides', 'Design Patterns'); 67 | 68 | $decorator = new BookTitleDecorator($patternBook); 69 | $starDecorator = new BookTitleStarDecorator($decorator); 70 | $exclaimDecorator = new BookTitleExclaimDecorator($decorator); 71 | 72 | writeln('showing title : '); 73 | writeln($decorator->showTitle()); 74 | writeln(''); 75 | 76 | writeln('showing title after two exclaims added : '); 77 | $exclaimDecorator->exclaimTitle(); 78 | $exclaimDecorator->exclaimTitle(); 79 | writeln($decorator->showTitle()); 80 | writeln(''); 81 | 82 | writeln('showing title after star added : '); 83 | $starDecorator->starTitle(); 84 | writeln($decorator->showTitle()); 85 | writeln(''); 86 | 87 | writeln('showing title after reset: '); 88 | writeln($decorator->resetTitle()); 89 | writeln($decorator->showTitle()); 90 | writeln(''); 91 | 92 | writeln('END TESTING DECORATOR PATTERN'); 93 | 94 | function writeln($line_in) { 95 | echo $line_in."
"; 96 | } 97 | -------------------------------------------------------------------------------- /structural-patterns/facade.php: -------------------------------------------------------------------------------- 1 | author = $author_in; 8 | $this->title = $title_in; 9 | } 10 | function getAuthor() { 11 | return $this->author; 12 | } 13 | function getTitle() { 14 | return $this->title; 15 | } 16 | function getAuthorAndTitle() { 17 | return $this->getTitle().' by '.$this->getAuthor(); 18 | } 19 | } 20 | 21 | class CaseReverseFacade { 22 | public static function reverseStringCase($stringIn) { 23 | $arrayFromString = ArrayStringFunctions::stringToArray($stringIn); 24 | $reversedCaseArray = ArrayCaseReverse::reverseCase($arrayFromString); 25 | $reversedCaseString = ArrayStringFunctions::arrayToString($reversedCaseArray); 26 | return $reversedCaseString; 27 | } 28 | } 29 | 30 | class ArrayCaseReverse { 31 | private static $uppercase_array = 32 | array('A', 'B', 'C', 'D', 'E', 'F', 33 | 'G', 'H', 'I', 'J', 'K', 'L', 34 | 'M', 'N', 'O', 'P', 'Q', 'R', 35 | 'S', 'T', 'U', 'V', 'W', 'X', 36 | 'Y', 'Z'); 37 | private static $lowercase_array = 38 | array('a', 'b', 'c', 'd', 'e', 'f', 39 | 'g', 'h', 'i', 'j', 'k', 'l', 40 | 'm', 'n', 'o', 'p', 'q', 'r', 41 | 's', 't', 'u', 'v', 'w', 'x', 42 | 'y', 'z'); 43 | public static function reverseCase($arrayIn) { 44 | $array_out = array(); 45 | for ($x = 0; $x < count($arrayIn); $x++) { 46 | if (in_array($arrayIn[$x], self::$uppercase_array)) { 47 | $key = array_search($arrayIn[$x], self::$uppercase_array); 48 | $array_out[$x] = self::$lowercase_array[$key]; 49 | } elseif (in_array($arrayIn[$x], self::$lowercase_array)) { 50 | $key = array_search($arrayIn[$x], self::$lowercase_array); 51 | $array_out[$x] = self::$uppercase_array[$key]; 52 | } else { 53 | $array_out[$x] = $arrayIn[$x]; 54 | } 55 | } 56 | return $array_out; 57 | } 58 | } 59 | 60 | class ArrayStringFunctions { 61 | public static function arrayToString($arrayIn) { 62 | $string_out = NULL; 63 | foreach ($arrayIn as $oneChar) { 64 | $string_out .= $oneChar; 65 | } 66 | return $string_out; 67 | } 68 | public static function stringToArray($stringIn) { 69 | return str_split($stringIn); 70 | } 71 | } 72 | 73 | 74 | witeln('BEGIN TESTING FACADE PATTERN'); 75 | witeln(''); 76 | 77 | $book = new Book('Design Patterns', 'Gamma, Helm, Johnson, and Vlissides'); 78 | 79 | witeln('Original book title: '.$book->getTitle()); 80 | witeln(''); 81 | 82 | $bookTitleReversed = CaseReverseFacade::reverseStringCase($book->getTitle()); 83 | 84 | writeln('Reversed book title: '.$bookTitleReversed); 85 | witeln(''); 86 | 87 | writeln('END TESTING FACADE PATTERN'); 88 | 89 | function writeln($line_in) { 90 | echo $line_in."<br/>"; 91 | } 92 | -------------------------------------------------------------------------------- /structural-patterns/flyweight.php: -------------------------------------------------------------------------------- 1 | author = $author_in; 8 | $this->title = $title_in; 9 | } 10 | function getAuthor() { 11 | return $this->author; 12 | } 13 | function getTitle() { 14 | return $this->title; 15 | } 16 | } 17 | 18 | class FlyweightFactory { 19 | private $books = array(); 20 | function __construct() { 21 | $this->books[1] = NULL; 22 | $this->books[2] = NULL; 23 | $this->books[3] = NULL; 24 | } 25 | function getBook($bookKey) { 26 | if (NULL == $this->books[$bookKey]) { 27 | $makeFunction = 'makeBook'.$bookKey; 28 | $this->books[$bookKey] = $this->$makeFunction(); 29 | } 30 | return $this->books[$bookKey]; 31 | } 32 | //Sort of an long way to do this, but hopefully easy to follow. 33 | //How you really want to make flyweights would depend on what 34 | //your application needs. This, while a little clumbsy looking, 35 | //does work well. 36 | function makeBook1() { 37 | $book = new FlyweightBook('Larry Truett','PHP For Cats'); 38 | return $book; 39 | } 40 | function makeBook2() { 41 | $book = new FlyweightBook('Larry Truett','PHP For Dogs'); 42 | return $book; 43 | } 44 | function makeBook3() { 45 | $book = new FlyweightBook('Larry Truett','PHP For Parakeets'); 46 | return $book; 47 | } 48 | } 49 | 50 | class FlyweightBookShelf { 51 | private $books = array(); 52 | function addBook($book) { 53 | $this->books[] = $book; 54 | } 55 | function showBooks() { 56 | $return_string = NULL; 57 | foreach ($this->books as $book) { 58 | $return_string .= 'title: '.$book->getAuthor().' author: '.$book->getTitle(); 59 | }; 60 | return $return_string; 61 | } 62 | } 63 | 64 | writeln('BEGIN TESTING FLYWEIGHT PATTERN'); 65 | 66 | $flyweightFactory = new FlyweightFactory(); 67 | $flyweightBookShelf1 = new FlyweightBookShelf(); 68 | $flyweightBook1 = $flyweightFactory->getBook(1); 69 | $flyweightBookShelf1->addBook($flyweightBook1); 70 | $flyweightBook2 = $flyweightFactory->getBook(1); 71 | $flyweightBookShelf1->addBook($flyweightBook2); 72 | 73 | writeln('test 1 - show the two books are the same book'); 74 | if ($flyweightBook1 === $flyweightBook2) { 75 | writeln('1 and 2 are the same'); 76 | } else { 77 | writeln('1 and 2 are not the same'); 78 | } 79 | writeln(''); 80 | 81 | writeln('test 2 - with one book on one self twice'); 82 | writeln($flyweightBookShelf1->showBooks()); 83 | writeln(''); 84 | 85 | $flyweightBookShelf2 = new FlyweightBookShelf(); 86 | $flyweightBook1 = $flyweightFactory->getBook(2); 87 | $flyweightBookShelf2->addBook($flyweightBook1); 88 | $flyweightBookShelf1->addBook($flyweightBook1); 89 | 90 | writeln('test 3 - book shelf one'); 91 | writeln($flyweightBookShelf1->showBooks()); 92 | writeln(''); 93 | 94 | writeln('test 3 - book shelf two'); 95 | writeln($flyweightBookShelf2->showBooks()); 96 | writeln(''); 97 | 98 | writeln('END TESTING FLYWEIGHT PATTERN'); 99 | 100 | function writeln($line_in) { 101 | echo $line_in."
"; 102 | } 103 | -------------------------------------------------------------------------------- /structural-patterns/null_object.php: -------------------------------------------------------------------------------- 1 | bookList) { 10 | $this->makeBookList(); 11 | } 12 | return $this->bookList->getBookCount(); 13 | } 14 | function addBook($book) { 15 | if (NULL == $this->bookList) { 16 | $this->makeBookList(); 17 | } 18 | return $this->bookList->addBook($book); 19 | } 20 | function getBook($bookNum) { 21 | if (NULL == $this->bookList) { 22 | $this->makeBookList(); 23 | } 24 | return $this->bookList->getBook($bookNum); 25 | } 26 | function removeBook($book) { 27 | if (NULL == $this->bookList) { 28 | $this->makeBookList(); 29 | } 30 | return $this->bookList->removeBook($book); 31 | } 32 | //Create 33 | function makeBookList() { 34 | $this->bookList = new bookList(); 35 | } 36 | } 37 | 38 | class BookList { 39 | private $books = array(); 40 | private $bookCount = 0; 41 | public function __construct() { 42 | } 43 | public function getBookCount() { 44 | return $this->bookCount; 45 | } 46 | private function setBookCount($newCount) { 47 | $this->bookCount = $newCount; 48 | } 49 | public function getBook($bookNumberToGet) { 50 | if ( (is_numeric($bookNumberToGet)) && ($bookNumberToGet <= $this->getBookCount())) { 51 | return $this->books[$bookNumberToGet]; 52 | } else { 53 | return NULL; 54 | } 55 | } 56 | public function addBook(Book $book_in) { 57 | $this->setBookCount($this->getBookCount() + 1); 58 | $this->books[$this->getBookCount()] = $book_in; 59 | return $this->getBookCount(); 60 | } 61 | public function removeBook(Book $book_in) { 62 | $counter = 0; 63 | while (++$counter <= $this->getBookCount()) { 64 | if ($book_in->getAuthorAndTitle() == $this->books[$counter]->getAuthorAndTitle()) { 65 | for ($x = $counter; $x < $this->getBookCount(); $x++) { 66 | $this->books[$x] = $this->books[$x + 1]; 67 | } 68 | $this->setBookCount($this->getBookCount() - 1); 69 | } 70 | } 71 | return $this->getBookCount(); 72 | } 73 | } 74 | 75 | class Book { 76 | private $author; 77 | private $title; 78 | function __construct($title_in, $author_in) { 79 | $this->author = $author_in; 80 | $this->title = $title_in; 81 | } 82 | function getAuthor() { 83 | return $this->author; 84 | } 85 | function getTitle() { 86 | return $this->title; 87 | } 88 | function getAuthorAndTitle() { 89 | return $this->getTitle().' by '.$this->getAuthor(); 90 | } 91 | } 92 | 93 | writeln( 'BEGIN TESTING PROXY PATTERN'; 94 | writeln(''); 95 | 96 | $proxyBookList = new ProxyBookList(); 97 | $inBook = new Book('PHP for Cats','Larry Truett'); 98 | $proxyBookList->addBook($inBook); 99 | 100 | writeln('test 1 - show the book count after a book is added'); 101 | writeln($proxyBookList->getBookCount()); 102 | writeln(''); 103 | 104 | writeln('test 2 - show the book'); 105 | $outBook = $proxyBookList->getBook(1); 106 | writeln($outBook->getAuthorAndTitle()); 107 | writeln(''); 108 | 109 | $proxyBookList->removeBook($outBook); 110 | 111 | writeln('test 3 - show the book count after a book is removed'); 112 | writeln($proxyBookList->getBookCount()); 113 | writeln(''); 114 | 115 | writeln('END TESTING PROXY PATTERN'); 116 | 117 | function writeln($line_in) { 118 | echo $line_in."
"; 119 | } --------------------------------------------------------------------------------