HomePHP Page 3 - PHP: View Object Collections and the Composite View Design
Adding and removing view objects - PHP
In this second part of a series, I demonstrate how to create a concrete composite view class, capable of rendering single and multiple view templates via the same “render()” method. The definition of this brand new class not only shows the logic that drives the Composite View pattern, but reveals how the pattern takes advantage of the benefits offered by Composition.
One of the most appealing -- yet confusing -- aspects of the Composite pattern, including the Composite View, is that it allows you to handle single objects and collections of them via Composition. Of course, the best way to understand how this can be achieved is by looking at an example. In keeping with this I suggest you look at the definition of the brand new class listed below. It implements the “addView()” and “removeView()” abstract methods declared by the previous “AbstractView” parent. Check it out:
(View.php)
<?php
class View extends AbstractView { protected $_views = array();
// factory method (chainable) public static function factory($view, array $data = array()) { return new self($viewfile, $data); }
// add a new view object public function addView(AbstractView $view) { if (!in_array($view, $this->_views, TRUE)) { $this->_views[] = $view; } return $this; }
// remove an existing view object public function removeView(AbstractView $view) { if (in_array($view, $this->_views, TRUE)) { $views = array(); foreach ($this->_views as $_view) { if ($_view !== $view) { $views[] = $_view; } } $this->_views = $views; } return $this; } }
As I expressed before, the above “View” class is nothing but a refined implementation of its abstract parent, in this case responsible for adding functionality to the corresponding “addView()” and “removeView()” methods. But why are these methods so useful in the implementation of a Composite View schema? Well, as you can see, they allow you to aggregate (and remove) different view objects, which are stored in a protected array. Therefore, by calling the “render()” method of each of the stored objects (be it just one or many), it would be possible to render their associated templates in one go!
This means that the “View” class would permit you to handle single and multiple view objects indiscriminately, which is exactly the function of a Composite class. Considering that this functionality must be implemented through the same interface, the last thing we need to do is add an enhanced “render()” method to the class. This method will be capable of rendering its own template and the ones corresponding to the injected view objects.
The definition of the aforementioned method will be shown in the upcoming section. So hurry up and read the following lines.