Composite Pattern in PHP

In the Composite pattern an individual object or a group of that object will have similar behaviors.

In this example, the OneBook class is the individual object. The SeveralBooks class is a group of zero or more OneBook objects.

Both the OneBook and SeveralBooks can return information about the books title and author. OneBook can only return this information about one single book, while SeveralBooks will return this information one at a time about as many OneBooks as it holds.

While both classes have addBook and removeBook functions, they are only functional on SeveralBooks. OneBook will merely return FALSE when these functions are called.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
 abstract class OnTheBookShelf
 {
     abstract function getBookInfo($previousBook);
     abstract function getBookCount();
     abstract function setBookCount($new_count);
     abstract function addBook($oneBook);
     abstract function removeBook($oneBook);
 }

 class OneBook extends OnTheBookShelf
 {
     private $title;
     private $author;

     public function __construct($title, $author)
     {
         $this->title = $title;
         $this->author = $author;
     }

     public function getBookInfo($bookToGet)
     {
         if (1 == $bookToGet) {
             return $this->title." by ".$this->author;
         } else {
             return false;
         }
     }

     public function getBookCount()
     {
         return 1;
     }

     public function setBookCount($newCount)
     {
         return false;
     }

     public function addBook($oneBook)
     {
         return false;
     }

     public function removeBook($oneBook)
     {
         return false;
     }
 }

 class SeveralBooks extends OnTheBookShelf
 {
     private $oneBooks = array();
     private $bookCount;

     public function __construct()
     {
         $this->setBookCount(0);
     }

     public function getBookCount()
     {
         return $this->bookCount;
     }

     public function setBookCount($newCount)
     {
         $this->bookCount = $newCount;
     }

     public function getBookInfo($bookToGet)
     {
         if ($bookToGet <= $this->bookCount) {
             return $this->oneBooks[$bookToGet]->getBookInfo(1);
         } else {
             return false;
         }
     }

     public function addBook($oneBook)
     {
         $this->setBookCount($this->getBookCount() + 1);
         $this->oneBooks[$this->getBookCount()] = $oneBook;
         return $this->getBookCount();
     }

     public function removeBook($oneBook)
     {
         $counter = 0;
         while (++$counter <= $this->getBookCount()) {
             if ($oneBook->getBookInfo(1) ==
                 $this->oneBooks[$counter]->getBookInfo(1)) {
                 for ($x = $counter; $x < $this->getBookCount(); $x++) {
                     $this->oneBooks[$x] = $this->oneBooks[$x + 1];
                 }
                 $this->setBookCount($this->getBookCount() - 1);
             }
         }
         return $this->getBookCount();
     }
 }

 writeln("BEGIN TESTING COMPOSITE PATTERN");
 writeln('');

 $firstBook = new OneBook('Core PHP Programming, Third Edition', 'Atkinson and Suraski');
 writeln('(after creating first book) oneBook info: ');
 writeln($firstBook->getBookInfo(1));
 writeln('');

 $secondBook = new OneBook('PHP Bible', 'Converse and Park');
 writeln('(after creating second book) oneBook info: ');
 writeln($secondBook->getBookInfo(1));
 writeln('');

 $thirdBook = new OneBook('Design Patterns', 'Gamma, Helm, Johnson, and Vlissides');
 writeln('(after creating third book) oneBook info: ');
 writeln($thirdBook->getBookInfo(1));
 writeln('');

 $books = new SeveralBooks();

 $booksCount = $books->addBook($firstBook);
 writeln('(after adding firstBook to books) SeveralBooks info : ');
 writeln($books->getBookInfo($booksCount));
 writeln('');

 $booksCount = $books->addBook($secondBook);
 writeln('(after adding secondBook to books) SeveralBooks info : ');
 writeln($books->getBookInfo($booksCount));
 writeln('');

 $booksCount = $books->addBook($thirdBook);
 writeln('(after adding thirdBook to books) SeveralBooks info : ');
 writeln($books->getBookInfo($booksCount));
 writeln('');

 $booksCount = $books->removeBook($firstBook);
 writeln('(after removing firstBook from books) SeveralBooks count : ');
 writeln($books->getBookCount());
 writeln('');

 writeln('(after removing firstBook from books) SeveralBooks info 1 : ');
 writeln($books->getBookInfo(1));
 writeln('');

 writeln('(after removing firstBook from books) SeveralBooks info 2 : ');
 writeln($books->getBookInfo(2));
 writeln('');

 writeln('END TESTING COMPOSITE PATTERN');

 function writeln($line_in)
 {
     echo $line_in."<br/>";
 }
BEGIN TESTING COMPOSITE PATTERN

(after creating first book) oneBook info:
Core PHP Programming, Third Edition by Atkinson and Suraski

(after creating second book) oneBook info:
PHP Bible by Converse and Park

(after creating third book) oneBook info:
Design Patterns by Gamma, Helm, Johnson, and Vlissides

(after adding firstBook to books) SeveralBooks info :
Core PHP Programming, Third Edition by Atkinson and Suraski

(after adding secondBook to books) SeveralBooks info :
PHP Bible by Converse and Park

(after adding thirdBook to books) SeveralBooks info :
Design Patterns by Gamma, Helm, Johnson, and Vlissides

(after removing firstBook from books) SeveralBooks count : 2

(after removing firstBook from books) SeveralBooks info 1 :
PHP Bible by Converse and Park

(after removing firstBook from books) SeveralBooks info 2 :
Design Patterns by Gamma, Helm, Johnson, and Vlissides

END TESTING COMPOSITE PATTERN