Organizing Algorithms
Working through Larry Ullman’s PHP Advanced and Object-Oriented Programming (3rd Ed) book with the Boston PHP Percolator group, we came to an example of the Strategy pattern, and I decided to re-write it. I was able to preserve Larry’s sort algorithms, but I took a different tact for the rest of the pattern. One of my favorite features of the Strategy pattern is that the Gang of Four note that it removes the need for conditional statements. Oh boy! No conditional statements!
You may well wonder why not having conditional statements is a good thing. Simple. Without conditional statements in a program, it’s easier to update and change it. If you’ve ever written a big program and you make changes, you have to go through all of the conditional statements and make sure that needed changes have not upset the coding apple cart. (The State design pattern is another one that has no conditional statements.) This does not mean that design patterns are anti-conditonal statements, but they can get in the way when making changes and updates. Besides, only the Strategy and State patterns are mentioned as having the advantage of no conditional statements. The client makes a request, and the pattern goes straight to requested property or operation with no if’s or switches. After all, if a client wants an algorithm, why should it have to go through a conditional series if it knows what it wants? (If the client is not sure what it needs, a Chain of Responsibility pattern, that does have conditional statements, is used. However, all the conditionals are pretty much the same and just check to see if the request has to be passed along the chain.) To get started take a look at the generated output and download the files:
Context class and Strategy interface
Larry Ullman’s idea of using different sort algorithms is a perfect example of a “family of algorithms.” So when creating this particular Strategy pattern, I kept the same algorithms, but I removed the conditionals from the concrete strategies. To get started you can take a look at the formal class diagram in the first PHP Strategy pattern placed on this blog. After taking a look at it, consider Figure 1 that shows the general files used and their relationship to one another:

Figure 1: File Diagram of Strategy Pattern
We begin with the Context class. It has three features (GoF 317):
- It is configured with a ConcreteStrategy object.
- It maintains a reference to a Strategy object.
- It may define an interface that lets Strategy access its data.
First, look at the following Context class. The first thing to note is that it is not an abstract class nor an interface. See if you can recognize the three elements the the Context participant listed above:
< ?php class Context { private $strategy; public function __construct(IStrategy $strategy) { $this->strategy = $strategy; } public function algorithm(Array $elements) { $this->strategy->algorithm($elements); } } ?> |
You can see that the constructor function calls for a ConcreteStrategy. We know that because the type hinting shows that the data type must be IStrategy. Looking ahead, you find that IStrategy is an interface; not a concrete class so you may think, “That’s wrong!” However, PHP type hinting allows the data type to be a child of the named type. (The same is true for strongly typed languages like C# and Java as well.) Further, a principle of design patterns is to program to the interface and not the implementation. Besides, you cannot create an instance of an interface or abstract class anyway, so the type would have to be a concrete implementation of the interface (IStrategy, which is the Strategy participant in this example).
Second, it maintains a reference to the Strategy object (IStrategy in the example). The private variable $strategy is assigned a Strategy instance. Again we know that because the type hinting requires an IStrategy type.
Third, the class defines an interface that gives Strategy access to its data in the algorithm() method. Note that the $strategy property is part of algorithm() method that has been instantiated through the IStrategy type hinted argument passed in constructor.
The Strategy participant in the design pattern is an interface, IStrategy. It is nothing more than a method expecting an array as an argument. The individual concrete strategy classes instantiate the method in any way they want, as long as the argument is an array.
< ?php interface IStrategy { public function algorithm(Array $elements); } ?> |
Think of the algorithm() method as a way for the Strategy to access the data.
Continue reading ‘Bedrock Strategy Pattern: The Family of Algorithms’
Recent Comments