├── 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 .= '