Getting the Director Right
Part I of the Builder two-part series explains the Builder pattern and provides a simple example. Back in early 2009, I had used a similar example in ActionScript 2.0 that performed a similar task; namely building different Web pages from a single Builder pattern. (If you experienced déjà vu, it may be that you came across that earlier post.) At the time I added all of the necessary participants, but I really was not too concerned with certain details because the goal focused more on getting the participants to perform their tasks correctly than on some of the details. In Part I, the PHP example paid closer attention to details, but again, the focus was on exposition more than detailed features.
Figure 1: Director details in Builder class diagram.
Figure 1 shows that portion of the original Gang of Four class diagram illustrating the role of the
Director. Significantly is the pseudocode notation
indicating some kind of loop through an object fires off the concrete Builder parts. In
Part I, the Director simply runs all of the methods attached to a concrete builder. Most of the examples that I found of the Director, ranging from PHP to Java, use the same general approach.
Upon closer examination of the examples shown in the original Design Patterns: Elements of Reusable Object-Oriented Software, I realized that two different examples illustrated the Builder. The first one is an RTF Reader and the second is based on a Maze example from an earlier chapter. I had been digging through the code in the maze example without much luck. In the pseudocode notation of the RTF Reader, however, it shows a while loop used in conjunction with a switch statement. I tried writing similar code in PHP, and it worked like a champ, but it was not very reusable. (I rarely imply that GoF might have done something less than perfect!) So I went to work using the more abstract pseudocode notation in the structural class diagram. However, before getting into that, go ahead and test the application with the Play buttons and download all of the code.



Iterating Through an Object in PHP
All I needed to do was to create a simple loop that would iterate through an object. Originally, I thought that I’d need to use an object created by implementing a concrete Builder. However, in looking closely at the Builder class diagram, you can see that the Builder interface does not include a getResult() method. That method is only in the concrete Builder to get the assembled Product. Also, I found that I got a constructor function (__construct()) if I used a concrete Builder as a target object. So why not use the interface as the object? Figure 2 shows the general method for finding the methods in a class, and it works for interfaces as well.
Figure 2: Getting methods from classes and interfaces
So far so good. Now I have an object with all of the method names in string format. As you may know, PHP allows you to use strings to create variables, but you can also dynamically generate usable methods using variable functions. Figure 3 shows the format with an example of how to do it with a string stored in a PHP variable.
Figure 3: Using a string value to call a class method
The trickiest part for me was remembering to place a ‘$’ in front of the method. However, once I got used to that idea, the rest was a matter of iterating through the object containing the methods and placing them on a concrete Builder instance. As you can see in the following listing the Director class is now much more re-usable:
< ?php
//Director.php
class Director
{
private $builder;
private $builder_methods;
public function doBuild(IBuilder $buildNow)
{
$this->builder=$buildNow;
$this->builder_methods=get_class_methods('IBuilder');
foreach($this->builder_methods as $part)
{
$this->builder->$part();
}
}
}
?>
|
Given this format, you can use the identical Director for any PHP Builder application you might create. The only change would be the name of the interface from IBuilder to whatever name you want to use. It pulls out all of the abstract method names from the interface and then assigns then to whatever concrete Builder instance is passed to it. It does not matter how they’re implemented as long as they adhere to the structure. However, you may also create different Directors using the same Builder interface by ordering the building blocks in a different way. (More on this later.)
Continue reading ‘PHP Builder Design Pattern Part II: Iterating through an Interface’
Recent Comments