Chapter 3. Basic Design Pattern Concepts

Large organization is loose organization. Nay, it would be almost as true to say that organization is always disorganization.

If you only have a hammer, you tend to see every problem as a nail.

Because things are the way they are, things will not stay the way they are.

Way back in the 1970s when user interfaces (UIs) were fairly primitive, a programmer decided to separate key elements of what was required in a graphical user interface (GUI). Each of the parts was given a specific task, and each part communicated with the other parts. The parts were grouped into domain objects and presentation objects. The domain objects were for modeling what perception the user was given of the real world, and the presentation objects were what was viewed on the screen. The parts were divided into a model, a view, and a controller, and the Model-View-Control (MVC) design pattern came into being.

The domain element in the MVC is the model. The model is responsible for what is variously called the data, business, or application logic. For example, take a thermostat. Within the thermostat is a value that represents a temperature, either the actual ambient temperature or a value where a heater is turned Off or On. Somewhere in that thermostat you have a set of data that can be envisioned as set into variables:

$a = current temperature
$b = turn off heater
$c = turn on heater

At a given time, the actual values may be:

$a=65;
$b=67;
$c=64;

Those values are generated by the controller settings and a thermometer that reads the ambient temperature. It doesn’t matter where or how the values are generated; that’s the business of the model.

The presentation part of the MVC has two elements: the view and controller. The view, in the thermostat example, is a window that shows the temperature and settings to the viewer. The model provides the ambient temperature, and the controller provides the on/off temperature sent to the view for display. The controller is the device that adjusts the on/off values. (The view displays the controller, however.) Figure 3-1 illustrates the MVC in a thermostat.

A thermostat hanging on the wall and a virtual one represented in a computer program are different in that the view communicates to the controller how the user input is to be handled. Remember that in a computer display, the UI is actually part of the view in that the user can see it for making changes. The view then communicates changes by the user to the controller, which in turn sends the information to the model. Figure 3-2 shows the same object in a class diagram.

The MVC seems to have as many variations as there are implementations. Because of its simplicity and utility, it has been used and misused a good deal. However, the point remains that it stands as a structure that provides loose coupling between its parts. For example, suppose you want to change the view from an analog view to a digital view. That’s easy to do because the model and controller are self-contained entities and really don’t care what the view displays. Likewise, the controller can change from settings in Fahrenheit to Celsius, and as long as the model is sent the information, it doesn’t care what temperature format is used.

The importance of the MVC lies more in the demonstration of loose coupling than in direct functionality. By separating out the different elements (or participants) in accomplishing a task, the MVC added a good deal of flexibility required in large programs. The larger the program, the more the program required the modular flexibility in the MVC.

While the MVC is an important point in the development of design patterns, it is only a starting point. The use, misuse, and overuse of the MVC in programming are well documented. When overemployed, it is not unlike building a house with a single tool—a hammer—to take care of all sawing, measurement, and drilling tasks.

In the landmark publication Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (best known as The Gang of Four or simply GoF), the MVC is used to begin a discussion of the many tools that make up design patterns. The MVC is credited with decoupling views and models by establishing a subscribe/notify protocol between them. However, GoF go on to show that many different and fundamental design patterns not only make up the MVC, but there is also a far greater range of common patterns for the kinds of work that computer programmers do, wholly apart from MVC. So, rather than looking at design patterns tied in some way to MVC, we need to examine design patterns apart from the MVC. We need instead to examine the principles of design patterns in general and each design pattern in its own right.

This first principle is a tricky one for PHP: program to an interface, not an implementation. In the simplest form, programming to an interface instead of an implementation means to set your variable as an instance of an abstract class or interface data type instead of a concrete implementation. By programming to an interface, you decouple the design from the implementation in such a way that you could (for example) easily replace a complex database implementation with a much simpler mock implementation for testing purposes. In languages that include data typing in variable declarations, you simply name the interface as the data type instead of the concrete class the variable instantiates. For example, in a strongly typed language, you may have the following:

You cannot declare a variable to be of an abstract parent (abstract class or interface) data type in PHP because you cannot declare a data type without instantiating an instance of a class. Further, you cannot instantiate an object from an abstract class. A variable can “get” a data type by instantiating a concrete object using the following format:

$useAlpha = new AlphaA();

The variable named $useAlpha is an instance of the class AlphaA and is considered to be of that data type. So $useAlpha is of the data type AlphaA, a concrete implementation of a concrete class. At the same time, however, while an instance is the data type of a concrete class, it is also of the data type of the concrete class’ parent. That bears repeating:

An object instance is the data type of the object it instantiates and the data type of the object’s parent.

How can that be done without strong typing? In PHP, you can program to an interface using code hinting.

In Chapter 2, the section Type Hinting: Almost Data Typing showed an example of using code hinting with the interface IProduct. Two different classes, FruitStore and CitrusStore, both implemented the same interface. Using code hinting, both were able to operate as arguments where a method with a code hinting parameter of IProduct was in force. That code hint specified the IProduct data type as a requirement for the argument. By closely examining a segment of that code, you can see how the operations were coding to an interface. Figure 3-3 shows the first step in a PHP operation programming to an interface: instantiating objects to be instances of interface implementations (see Type Hinting: Almost Data Typing for the full program).

Figure 3-3 instantiations show exactly the opposite of what the principle of programming to an interface suggests: the variables are instantiated as instances of concrete implementations instead of the interface they share. What you cannot see in PHP because of weak data typing is that the concrete implementations are data types of the interface as well.

When type hinting is used, the programmer must include an object of the specified type hint. If that type hint is an interface, then the program will work exactly as though you are typing to an interface. Figure 3-4 shows the details of that process.

In looking at 3-3 and 3-4, you can see that the key method is doInterface(). It contains the type hint. When either the concrete instances of the two concrete implementations (FruitStore or CitrusStore) are used as arguments in the doInterface() method, the output is predictable. As long as any other implementation of the interface maintains the IProduct interface (including return data types), it won’t matter how complex the program becomes. Your changes and additions will work the way you expect them to work, and they will not damage some other part of the program.

To help clarify the principle of programming to an interface instead of an implementation, the examples employ interfaces created using the keyword interface. Before continuing, though, understand that the concept of interface refers to the methods and their signatures, not necessarily the keyword, interface. Every class has an interface made up of its methods’ signatures. Because most design patterns seldom include an extension from a concrete class, you need to understand that an extension from an abstract class is similar to the implementation of an interface.

In this next example, a simple abstract class is extended by two simple implementations. Then, a client class using type hinting shows how you can program to the interface using an abstract class. Comments in the code help to enforce the expected return values.

First, the abstract class IAbstract has a protected property ($valueNow), two protected abstract methods (giveCost and giveCity), and a public function that is not abstract, displayShow:

<?php
abstract class IAbstract
{
    //Property available to all implementations
    protected $valueNow;

    /*All implementations must include the following 2 methods: */
    //Must return decimal value
    abstract protected function giveCost();
    //Must return string value
    abstract protected function giveCity();

    //This concrete function is available to all
    //class implementations without overriding
    //the contents

    public function displayShow()
    {
        $stringCost =$this->giveCost();
        $stringCost = (string)$stringCost;
        $allTogether=("Cost: $" . $stringCost . " for " . $this->giveCity());
        return $allTogether;
    }
}
?>

Next, two different extensions of the abstract class have different implementations of the abstract methods:

//NorthRegion.php
<?php
include_once('IAbstract.php');

class NorthRegion extends IAbstract
{
    //Must return decimal value
    protected function giveCost()
    {
        return 210.54;
    }
    //Must return string value
    protected function giveCity()
    {
        return "Moose Breath";
    }
}
?>

//WestRegion.php
<?php
include_once('IAbstract.php');

class WestRegion extends IAbstract
{
    //Must return decimal value
    protected function giveCost()
    {
        $solarSavings=2;
        $this->valueNow=210.54/$solarSavings;
        return $this->valueNow;
    }
    //Must return string value
    protected function giveCity()
    {
        return "Rattlesnake Gulch";
    }
}
?>

With two different implementations of an abstract class, you can see that programming to an interface in this context really means the interface of the class and not an interface structure as used with the keyword interface. Finally, the Client class sets up a method that includes code hinting that specifies the abstract class as the interface:

<?php
include_once('NorthRegion.php');
include_once('WestRegion.php');

class Client
{
    public function __construct()
    {
        $north=new NorthRegion();
        $west= new WestRegion();
        $this->showInterface($north);
        $this->showInterface($west);
    }

    private function showInterface(IAbstract $region)
    {
        echo $region->displayShow() . "<br/>";
    }
}
$worker=new Client();
?>

The output shows the following:

Cost: $210.54 for Moose Breath
Cost: $105.27 for Rattlesnake Gulch

The amounts are different for the different regions because the abstract methods are implemented differently by the two concrete classes NorthRegion and WestRegion. If an incorrect data type is used (a string, for example), you will see the following kind of error message:

Catchable fatal error: Argument 1 passed to Client::showInterface() 
must be an instance of IAbstract, string given, called in /Library/

So, in its own way, type hinting can help your programs move toward programming to an interface instead of an implementation.

To see how useful this style of programming is, add SouthRegion and EastRegion implementations of the IAbstract abstract class. Remember to use a decimal value for the giveCost() method and a string value for the giveCity(). Likewise, maintain the rest of the interface for both, and add them to the Client class. You should see how easy it is to make additions and changes as long as you maintain the interface.

To see the difference between using inheritance and composition, a simple example illustrates using a parent and child class (inheritance) and two separate classes (composition). Before looking at the code, Figure 3-5 shows a general idea of the difference between using inheritance and composition.

Using inheritance, the client can make a single instantiation for the math and text functionality. With composition, the client uses two different instances to gain access to the functionality of both classes. Composition within a design pattern typically refers to composition within a participant in the pattern.

First, look at the code using inheritance. The first class (parent class) is a simple one that has methods for addition and division:

<?php
//DoMath.php
class DoMath
{
    private $sum;
    private $quotient;

    public function simpleAdd($first,$second)
    {
        $this->sum=($first + $second);
        return $this->sum;
    }

    public function simpleDivide($dividend, $divisor)
    {
        $this->quotient=($dividend/$divisor);
        return $this->quotient;
    }
}
?>

The second class is for adding text functionality. One method converts numbers to strings and the other sets up a formatted output. It inherits all of the DoMath functionality through extension:

<?php
//InheritMath.php
include_once('DoMath.php');
class InheritMath extends DoMath
{
    private $textOut;
    private $fullFace;

    public function numToText($num)
    {
        $this->textOut=(string)$num;
        return $this->textOut;
    }

    public function addFace($face, $msg)
    {
        $this->fullFace= "<strong>" . $face . "</strong>: " . $msg;
        return $this->fullFace;
    }
}
?>

The Client class instantiates the InheritMath class and is able to use all of the functionality inherited from the DoMath class as well as the included classes for text work:

<?php
//ClientInherit
include_once('InheritMath.php');

class ClientInherit
{
    private $added;
    private $divided;
    private $textNum;
    private $output;

    public function __construct()
    {
        $family=new InheritMath();
        $this->added=$family->simpleAdd(40,60);
        $this->divided=$family->simpleDivide($this->added,25);
        $this->textNum=$family->numToText($this->divided);
        $this->output=$family->addFace("Your results",$this->textNum);
        echo $this->output;
    }
}
$worker=new ClientInherit();
?>

The output is a formatted calculated value:

    Your results: 4

That output used four different methods, two of which were inherited from a parent class.

Turning to composition, the Client class uses two separate classes, each containing two methods. The DoMath class is identical to the parent class in the inheritance example, so begin by examining the DoText class:

<?php
//DoText.php
class DoText
{
    private $textOut;
    private $fullFace;

    public function numToText($num)
    {
        $this->textOut=(string)$num;
        return $this->textOut;
    }

    public function addFace($face, $msg)
    {
        $this->fullFace= "<strong>" . $face . "</strong>: " . $msg;
        return $this->fullFace;
    }
}
?>

The DoText class looks a lot like the InheritMath class, and it is. However, it does not inherit the DoMath class.

In using composition in this example, the client uses both of the separate classes, and the results are identical. However, the client must instantiate two objects instead of one. Otherwise, the client used in composition is very similar to the one used with inheritance:

<?php
//ClientCompose.php
include_once('DoMath.php');
include_once('DoText.php');

class ClientCompose
{
    private $added;
    private $divided;
    private $textNum;
    private $output;

    public function __construct()
    {
        $useMath=new DoMath();
        $useText=new DoText();
        $this->added=$useMath->simpleAdd(40,60);
        $this->divided=$useMath->simpleDivide($this->added,25);
        $this->textNum=$useText->numToText($this->divided);
        $this->output=$useText->addFace("Your results",$this->textNum);
        echo $this->output;
    }
}
$worker=new ClientCompose();
?>

The results are the same, but the Client class has to include multiple classes. That may seem like an argument to favor inheritance, but composition in larger programs avoids the problem of maintaining each child class with multiple levels of inheritance and the possible errors that can occur. For instance, a change in the parent class can ripple down to the child implementation that interferes with an algorithm used by the child class.

When working out when and how to use delegation, how much inheritance should be included, and how to ensure reuse in OOP programming, design patterns can be seen as a big cheat sheet. You can quickly look up the general designs that use class diagrams to display where inheritance and composition are employed. Using a Unified Modeling Language (UML), you can learn to look at a class diagram and quickly see the different parts (called participants). (Chapter 4 covers the details of using UMLs to work with design patterns with PHP.)

This book follows the organization of design patterns laid out by the Gang of Four. In the most general sense, design patterns are organized by purpose and scope. Design pattern purpose has been organized into three classifications:

This classification is a general view of patterns in terms of what goal they are designed to accomplish. Scope has two categories:

This section looks at these ordering categories and explains how they can be handy in selecting and understanding design patterns.

Part of learning design patterns is learning to select the most appropriate one. Keep in mind that design patterns are not templates. They are general strategies that deal with general problems that crop up in object-oriented programming. This book includes one design pattern from each of the three purpose categories and the two scope categories. In addition, it includes three chapters (Chapter 12 through Chapter 14) that tackle common uses of PHP with MySQL where design patterns will come in handy. The three patterns discussed in these final chapters are all of the object scope and behavioral purpose type, the largest category in the GoF catalog.

One thing to consider in choosing a design pattern is what will vary in a design. Instead of looking at the cause of redesign, this approach looks at what you want to be able to change without redesign. As you will see, the focus switches to encapsulating the concept that varies. Table 3-1 shows the nine design patterns this book explains divided into purpose, scope, and aspects of the pattern that can vary.

Each of the patterns has a general use. The variation must be understood in context, and as we look at each pattern, the variation becomes clearer.