Tag Archive for 'strategy design pattern'

PHP Strategy Design Pattern Part II: Add a Context

pulp Adding a Context

A few years back, a post on this blog looked at examples of PHP design patterns that had missing parts. In 2006, an IBM sponsored post introduced PHPers to design patterns in “Five common PHP design patterns.” This was an important post because it demonstrated that far from being the exclusive domain of languages like Java, design patterns were applicable to PHP as well. However, of the five patterns, (Factory [Factory Method], Singleton, Chain-of-Command [Chain-of-Responsibility] , Observer, and Strategy) two (Factory and Chain-of-Command) were misnamed and misrepresented, one (Singleton) has since been more-or-less deprecated as a pattern (by no less than Erich Gamma) and the other two were iffy in their implementation.

Like lemmings following each other over a cliff, PHPers often followed each wrong example, further perpetuating the ill-formed pattern. So, when we look at patterns, lest PHP programmers be considered rank amateurs, we need to get patterns right. One of the most common mistakes with the Strategy pattern is either ignoring or leaving out the Context class altogether. In Part I of this two-part series, we saw what a Near-Strategy pattern looks like without a Context class. In Figure 1 of that same post, you can see the class diagrams of the Near-Strategy and Strategy patterns. The example in this post is of a correctly formed Strategy pattern. Play the Strategy example and Download the files with the following two buttons:
PlayDownload

The Context Participant

To get the Context right, we need to go to the original source, Design Patterns: Elements of Reusable Object-Oriented Software. The Context participant has the following characteristics:

  • Configured with a ConcreteStrategy object
  • Maintains to reference to a Strategy object
  • May define an interface that lets Strategy access its data

At the heart of the Strategy design pattern, the Context and Strategy interact to implement the selected algorithm in the form of a concrete strategy. The key here is,

The Strategy lets the algorithm vary independly from clients that use it.

In order to do this,

A context forwards requests from its clients to its strategy. Clients usually create and pass a ConcreteStrategy object to the context; thereafter, clients interact with the context exclusively.

Figure 1 shows the path used in this implementation:

Figure 1: The path through the context to request an algorithm (concrete strategy)

Figure 1: The path through the context to request an algorithm (concrete strategy)

The path begins with the Client creating an instance of a specific concrete strategy (received from the HTML UI) and using that instance as a parameter to make the request through the context. From this point on, the client no longer is in contact with the strategy but instead the context. The context takes the instance passed from the client and makes the request through the strategy interface [algorithmInterface()]. Any client can make similar requests through the context by passing the concrete strategy through its context interface. That can be very handy when your program has more than a single client requiring a strategy.
Continue reading ‘PHP Strategy Design Pattern Part II: Add a Context’

PHP Near Strategy Design Pattern Part I: No Conditionals, Please

nearStratWhy ‘Near’ Strategy?

The Strategy design pattern is important because it is so useful, and two different posts on this blog have covered it in the past. What I would like to do with this implementation of the pattern is to do two things: 1) First, show how to create operations that require no conditional statements, and 2) Second, (in Part II) show the role of the Context participant. In this first part, I’d like to look at the HTML->PHP operations where specific objects (classes) can be called through HTML forms.

One of the nice things about the Strategy pattern is that the logic of it is very easy to understand; albeit on a foundational level. You have different tasks, and each task requires a different algorithm; so why not separate the algorithm operations into distinct objects (classes) and loosely bind them to the client? Each class will only do one thing, and that is to carry out an algorithmic operation. To do this, start off with a “Near Strategy”–a pseudo-patten: the Strategy design pattern missing the Context. Figure 1 shows the difference between a Near Strategy and true Strategy design pattern:

Figure 1: The Near Strategy design and the Strategy Design pattern

Figure 1: The Near Strategy design and the Strategy Design pattern

The HTML UI and the Client are not a part of the Strategy design pattern, but in this example, both are required for making requests. Before going on, try out the program by clicking the Play button and download all of the files.

PlayDownload

You can use the files “as-is” but you will need to change the IConnectInfo.php file so that the hostname (HOST), user name (UNAME), database name (DBNAME) and password (PW) is your actual MySql database. Also, once you create a table with a name of your choosing, be careful not to create it again if you want to keep your data entered into the table!

Using Form Names for Concrete Strategy Names

One of the coolest features of PHP is the ability to use strings to create instances of classes (aka: objects). For example,

$myVar = “MyClass”;
$myObject = new $myVar();

creates an instance of the class, MyClass. Knowing this, we can create the class names in HTML as form values. For instance:




The selected radio button value can be passed in a super-global to PHP:


$myVar = $_POST[‘callme’];
$myObject = new $myVar();

Using this, the Client doe not have to work through conditional statements to decide which request to fulfill. Like the Strategy design pattern, even the Client is free from using conditional statements as can be seen in the following listing:

< ?php
function __autoload($class_name) 
{
    include $class_name . '.php';
}
Class Client
{
    private $chooser;
    private $instance;
 
    public function __construct()
    {
        $this->chooser=$_POST['sql'];
        $object=$this->chooser;
        $this->instance=new $object();
    } 
}
$worker=new Client();
?>

As you can see the Client class is pretty simple with no conditional statements. It takes the value of the radio button send with a Post method. The radio button group is named “sql”; so whatever button is clicked is translated into an object.
Continue reading ‘PHP Near Strategy Design Pattern Part I: No Conditionals, Please’

Bedrock Strategy Pattern: The Family of Algorithms

AlgorithmFamilyOrganizing 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:
PlayDownload

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

Figure 1: File Diagram of Strategy Pattern

We begin with the Context class. It has three features (GoF 317):

  1. It is configured with a ConcreteStrategy object.
  2. It maintains a reference to a Strategy object.
  3. 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’