Chapter 6. Prototype Design Pattern

Originality is nothing but judicious imitation. The most original writers borrowed one from another.

We forfeit three-quarters of ourselves in order to be like other people.

Act that your principle of action might safely be made a law for the whole world.

The Prototype design pattern is interesting in its use of a cloning technique to replicate instantiated objects. New objects are created by copying prototypical instances. In this context, instances refer to instantiated concrete classes. The purpose is to reduce the cost of instantiating objects by using cloning. Rather than instantiating new objects from a class, a clone of an existing instance can be used instead. Figure 6-1 shows the Prototype class diagram.

Note that the Client class is an integral part of the Prototype design pattern. The client creates an instance of a concrete prototype through the Prototype interface that includes a clone method of some sort. Fortunately, PHP has a built-in clone() method that can be used within the design pattern. As you will see, the basics of the design are quite simple.

The Prototype pattern should be used in any application where your project requires that you create several instances of a prototypical object. For example, in research on evolutionary development, scientists often use fruit flies. They reproduce quickly and have a greater probability of generating a mutation, the fundamental evolutionary change event. For example, a typical study may use 15 million fruit flies, and because females may be laying eggs almost as soon as they emerge (within hours), the chance of finding and recording mutations is much greater than with other creatures, such as elephants, which have a 22-month gestation period. In recording mutations, the male and female prototypes serve as a base, and mutations are a clone of any male or female instance. Thus, from two instantiations (one male and one female), you can clone as many mutations as required with no further need to create another instance from the concrete classes.

The Prototype pattern has also been used to create an organizational structure where a finite number of positions can be created and filled based on the actual organization. Prototypes have been used where a drawing object has been created using composition and then cloned for different versions. A final example could be in game development where a prototype warrior could be cloned to add numbers and types to an army.

The key to working with the Prototype design pattern in PHP is understanding how to use the built-in function, __clone(). While somewhat odd in relation to what you’ve probably done in PHP programming, it’s very easy. In order to see how to use the method, look at the following little program. (You really don’t need to extend an abstract class that contains an abstract __clone() method, but the examples all show an abstract class including a __clone() method, and so this might prove useful in the further Prototype examples in this book.)

<?php
//CloneMe.php
abstract class CloneMe
{
    public $name;
    public $picture;
    abstract function __clone();
}

class Person extends CloneMe
{
    public function __construct()
    {
        $this->picture="cloneMan.png";
        $this->name ="Original";
    }

    public function display()
    {
        echo "<img src='$this->picture'>";
        echo "<br />$this->name <p />";
    }

    function __clone() {}
}
$worker=new Person();
$worker->display();

$slacker = clone $worker;
$slacker->name="Cloned";
$slacker->display();
?>

The concrete class Person is an extension of the CloneMe abstract class. In the example, an instance of Person is instantiated by $worker. So now, $worker is a Person object. Next, a second instance variable, $slacker, clones the $worker instance of Person. It has access to the same properties as $worker and can change them just as a direct instance of the Person class would be able to do. Figure 6-2 shows the results.

The __clone() method cannot be accessed directly. Rather, if a __clone() method has been included in a class definition, using the following format:

$anotherInstance = clone $someInstance;

the clone keyword instantiates another instance of the same class as that of the cloned instance. The PHP documentation notes:

In discussing unit testing, Miško Hevery, who develops coding guidelines for Google, points out that a constructor should do no real work (http://bit.ly/1a9MWr). The comment was made in the context of unit testing (testing parts of a program), but it certainly may apply to design patterns. Hevery’s main point is that when a class instantiates and initializes its collaborators, the result tends to be an inflexible and prematurely coupled design. In the same vein, when a constructor function outputs anything, it provides no options for the client other than to shoot out what the constructor sends, even if it does not want it—or at least does not want it at a given time.

Hevery’s point does not mean that a constructor function cannot assign values to properties when needed. Likewise, the client’s constructor can be a good deal different from the other participants of a pattern because it is making requests of the participants.

One way to deal with the concept that constructors should do no real work is to omit constructor functions in pattern classes unless you have a good reason to include them. Otherwise, allow operations to be called when needed and let the client take care of instantiation and cloning chores. So, while we can find limitations in using the __clone() function, those limitations may aid in better OOP programs.

In this first example, consider an experiment using fruit flies. The goal of the research is to set up a prototype fruit fly and then, whenever a mutation occurs, build the mutation. With 50 million flies, you’ll get a lot of mutations, but you’re interested only in the fly’s eye color, the number of wing beats per second, and the number of unit eyes since the fruit fly eye contains hundreds of light-sensing units, each with its own lens and set of light receptor cells, and they may vary based on gender and reproduction. Other mutations are possible, but this study examines only those three variables.

The reason for selecting the Prototype for a fruit fly study is that it provides a starting point from which to measure mutation. The concrete classes set up a baseline for standard values for fruit flies, and mutations can be measured as deviations from the baseline. An abstract class provides the baseline variables (all of them are public for ease of the example use).

The two concrete class implementations of the prototype (IPrototype) represent the fly genders, the variable (gender), and gender behaviors (mating and producing eggs). The abstract class also includes an abstract method based on the __clone() method.

<?php
//IPrototype.php
abstract class IPrototype
{
    public $eyeColor;
    public $wingBeat;
    public $unitEyes;

    abstract function __clone();
}
?>

The two implementations of IPrototype differentiate between gender using constants labeling one MALE and the other FEMALE. The male has a $mated Boolean variable set to true after the male has mated and the female has a $fecundity variable containing a numeric value representing how capable the fly is at reproducing (its number of remaining eggs):

<?php
//MaleProto.php
include_once('IPrototype.php');
class MaleProto extends IPrototype
{
    const gender="MALE";
    public $mated;

    public function __construct()
    {
        $this->eyeColor="red";
        $this->wingBeat="220";
        $this->unitEyes="760 ";
    }
    function __clone(){}
}
?>

Importantly, both concrete implementations of IPrototype have an implemented __clone() method even though the implementation is nothing more than adding two curly braces to the statement. The __clone() method is built into PHP with encapsulated code that will do the required work for this particular design pattern; so an “implementation” can be nothing more than adding the signature of a function:

<?php
//FemaleProto.php
include_once('IPrototype.php');
class FemaleProto extends IPrototype
{
    const gender="FEMALE";
    public $fecundity;

    public function __construct()
    {
        $this->eyeColor="red";
        $this->wingBeat="220";
        $this->unitEyes="760 ";
    }
    function __clone(){}
}
?>

Both implementations include literals (actual numbers, strings, or Booleans) for the assigned values. In this way, the mutations can be measured as a deviation from these values.

While not rare in design patterns, the Client class is included as an integral participant in the Prototype design pattern. The reason for this is that while the concrete implementations of the child classes serve as templates for the instances, the work of actually cloning the instances using the same template is carried out by the Client class.

The two concrete implementations of the prototype are very simple and use direct value assignments to the shared variables of eyeColor, wingBeat, and unitEyes; they don’t even have getter/setter methods. For now, that’s fine because the focus is on seeing how those properties are used by the cloned implementations of the classes’ instances; $fly1 and $fly2 are instantiated from the concrete classes and $c1Fly, $c2Fly, and $updatedCloneFly are all clones of one or the other of the two class instances.

<?php
//Client.php
function __autoload($class_name)
{
    include $class_name . '.php';
}
class Client
{
    //For direct instantiation
    private $fly1;
    private $fly2;

    //For cloning
    private $c1Fly;
    private $c2Fly;
    private $updatedCloneFly;

    public function __construct()
    {
        //Instantiate
        $this->fly1=new MaleProto();
        $this->fly2=new FemaleProto();

        //Clone
        $this->c1Fly = clone $this->fly1;

        $this->c2Fly = clone $this->fly2;
        $this->updatedCloneFly = clone $this->fly2;

        //update clones
        $this->c1Fly->mated="true";
        $this->c2Fly->fecundity="186";

        $this->updatedCloneFly->eyeColor="purple";
        $this->updatedCloneFly->wingBeat="220";
        $this->updatedCloneFly->unitEyes="750";
        $this->updatedCloneFly->fecundity="92";

        //Send through type hinting method
        $this->showFly($this->c1Fly);
        $this->showFly($this->c2Fly);
        $this->showFly($this->updatedCloneFly);
    }

    private function showFly(IPrototype $fly)
    {
        echo "Eye color: " . $fly->eyeColor . "<br/>";
        echo "Wing Beats/second: " . $fly->wingBeat . "<br/>";
        echo "Eye units: " . $fly->unitEyes . "<br/>";
        $genderNow=$fly::gender;
        echo "Gender: " . $genderNow . "<br/>";
        if($genderNow=="FEMALE")
        {
            echo "Number of eggs: " . $fly->fecundity . "<p/>";
        }
        else
        {
            echo "Mated: " . $fly->mated . "<p/>";
        }
    }
}
$worker=new Client();
?>

With multiple class references, it’s easier to use the PHP __autoload() method than the include_once method. In this way, no matter how many participants or helper classes the Client class references, all classes are automatically included. The downside of using __autoload() while learning design patterns is that the include_once method shows all of the classes in use. Throughout the rest of the book, one or the other of the techniques for including classes in external files is employed depending on how useful a specific class referenced class name is to understanding the program. (Filenames are based on class names.)

The following output shows two unchanged clones of the male and female concrete classes (the “template” classes) and the third is the output of a “mutated” clone indicated by purple eyes and a different number of eye units. The number of eggs is within a standard deviation and is not considered a mutation.

Eye color: red
Wing Beats/second: 220
Eye units: 760
Gender: MALE
Mated: true

Eye color: red
Wing Beats/second: 220
Eye units: 760
Gender: FEMALE
Number of eggs: 186

Eye color: purple
Wing Beats/second: 220
Eye units: 750
Gender: FEMALE
Number of eggs: 92

The Prototype depends on the Client to use the concrete prototypes through a cloning process. The Client is the participant in the design that performs the cloning, and because cloning is the key element in the Prototype design, that makes the Client a fundamental participant and not simply a requesting class.

The minimalist example focuses on the relationships between the participants and the outcome. To keep the amount of code to the minimum to “see” the structure, the classes were not built with the kind of encapsulation we expect from an OOP application. In other words, the participants in the pattern implementation are fairly skeletal so that the relationship between the classes is easier to see. For instance, in the minimal implementation of the Prototype, the Client is able to change prototype property values directly—that is, by simple assignment. For example, the client changed the mutant eye color using the following code:

$this->updatedCloneFly->eyeColor="purple";

No method in the abstract or concrete prototype classes included getter/setter methods or some other structure to better encapsulate the properties.

The first thing that this Prototype implementation does is add OOP to the program’s interface—an abstract class. Like all Prototype interfaces, this one includes an abstract cloning operation. However, it also includes both abstract and concrete getters and setters. The abstract getter/setter pair leaves the specific implementation up to the three concrete prototype implementations. The other getter/setter methods are more generally applicable to such things as employee names, ID codes, and photos. Not that all of the properties are protected, so even though the concrete getters and setters have public visibility, the protected visibility of the properties used in the operations affords a degree of encapsulation:

<?php
//IAcmePrototype.php
abstract class IAcmePrototype
{
    protected $name;
    protected $id;
    protected $employeePic;
    protected $dept;

    //Dept
    abstract function setDept($orgCode);
    abstract function getDept();

    //Name
    public function setName($emName)
    {
        $this->name=$emName;
    }

    public function getName()
    {
        return $this->name;
    }
    //ID
    public function setId($emId)
    {
        $this->id=$emId;
    }

    public function getId()
    {
        return $this->id;
    }

    //Employee Picture

    public function setPic($ePic)
    {
        $this->employeePic=$ePic;
    }

    public function getPic()
    {
        return $this->employeePic;
    }

abstract function __clone();
}

?>

With the getter/setter methods set, the values for any of the properties are through inherited protected variables. With this arrangement, the extended classes and their instances are better encapsulated.

Each of the three IAcmePrototype child classes must implement the “dept” (department) abstract methods along with the __clone() method. Likewise, each concrete prototype class includes a constant, UNIT, with an assigned value that can be used by instances, whether implemented directly or a clone, for identification. Begin by looking at how the Marketing class has been structured:

<?php
//Marketing.php
include_once('IAcmePrototype.php');
class Marketing extends IAcmePrototype
{
    const UNIT="Marketing";
    private $sales="sales";
    private $promotion="promotion";
    private $strategic="strategic planning";

    public function setDept($orgCode)
    {
        switch($orgCode)
        {
            case 101:
            $this->dept=$this->sales;
            break;

            case 102:
            $this->dept=$this->promotion;
            break;

            case 103:
            $this->dept=$this->strategic;
            break;

            default:
            $this->dept="Unrecognized Marketing ";
        }
    }

    public function getDept()
    {
        return $this->dept;
    }

    function __clone(){}
}
?>

The setDept() method is implemented using a single parameter. Instead of directly entering the name of the department within the marketing unit, the method expects a numeric code. If it were expecting an object derived from a class, the method could be built using a type hint for an object/interface type, but type hinting does not allow scalar types such as int. Using a switch/case statement with the argument as a comparative variable, the class enforces one of three acceptable cases or defaults to “Unrecognized Marketing.” Once a match is made, the operation uses a private variable that has an assigned value. Again, this helps to encapsulate both the class and setter method. The getter method (getDept()) uses the same private variables.

The other two prototype implementations are similar, but note that each has different departments stored in private variables. Likewise, each has a different value for the constant, UNIT:

<?php
//Management.php
include_once('IAcmePrototype.php');
class Management extends IAcmePrototype
{
    const UNIT="Management";
    private $research="research";
    private $plan="planning";
    private $operations="operations";

    public function setDept($orgCode)
    {
        switch($orgCode)
        {
            case 201:
            $this->dept=$this->research;
            break;

            case 202:
            $this->dept=$this->plan;
            break;

            case 203:
            $this->dept=$this->operations;
            break;

            default:
            $this->dept="Unrecognized Management";
        }
    }

    public function getDept()
    {
        return $this->dept;
    }
    function __clone(){}
}
?>

The values expected in the switch/case statement are different in all three concrete prototype implementations. Likewise, the name and values of the private properties are different as well:

<?php
//Engineering.php
include_once('IAcmePrototype.php');
class Engineering extends IAcmePrototype
{
    const UNIT="Engineering";
    private $development="programming";
    private $design="digital artwork";
    private $sysAd="system administration";

    public function setDept($orgCode)
    {
        switch($orgCode)
        {
            case 301:
            $this->dept=$this->development;
            break;

            case 302:
            $this->dept=$this->design;
            break;

            case 303:
            $this->dept=$this->sysAd;
            break;

            default:
            $this->dept="Unrecognized Engineering";
        }
    }

    public function getDept()
    {
        return $this->dept;
    }
    function __clone(){}

}
?>

With all three concrete prototype implementations, each unique for its use but respecting the interface, a single instance of each can be created and then cloned by as many instances as needed. The Client class will fill this last role.

The basic setup for the Client is very simple. The plan is to create a single instance of each concrete prototype and then clone each one as the following outline shows:

Only the clones will be used. The information for each unique case is to be assigned to the clones using the getter/setter methods. The following code for the client shows this implementation:

<?php
//Client.php
function __autoload($class_name)
{
    include $class_name . '.php';
}

class Client
{
    private $market;
    private $manage;
    private $engineer;

    public function __construct()
    {
        $this->makeConProto();

        $Tess=clone $this->market;
        $this->setEmployee($Tess,"Tess Smith",101,"ts101-1234","tess.png");
        $this->showEmployee($Tess);

        $Jacob=clone $this->market;
        $this->setEmployee($Jacob,"Jacob Jones",102,"jj101-2234","jacob.png");
        $this->showEmployee($Jacob);

        $Ricky=clone $this->manage;
        $this->setEmployee($Ricky,"Ricky Rodriguez",203,"rr203-5634","ricky.png");
        $this->showEmployee($Ricky);

        $Olivia=clone $this->engineer;
        $this->setEmployee($Olivia,"Olivia Perez",302,"op301-1278","olivia.png");
        $this->showEmployee($Olivia);

        $John=clone $this->engineer;
        $this->setEmployee($John,"John Jackson",301,"jj302-1454","john.png");
        $this->showEmployee($John);
    }

    private function makeConProto()
    {
        $this->market=new Marketing();
        $this->manage=new Management();
        $this->engineer=new Engineering();
    }

    private function showEmployee(IAcmePrototype $employeeNow)
    {
        $px=$employeeNow->getPic();
        echo "<img src=$px width='150' height='150'><br/>";
        echo $employeeNow->getName() . "<br/>";
        echo $employeeNow->getDept() . ": " . $employeeNow::UNIT . "<br/>";
        echo $employeeNow->getID() . "<p/>";
    }

    private function setEmployee(IAcmePrototype $employeeNow,$nm,$dp,$id,$px)
    {
        $employeeNow->setName($nm);
        $employeeNow->setDept($dp);
        $employeeNow->setID($id);
        $employeeNow->setPic("pix/$px");
    }
}
$worker = new Client();
?>

The client’s constructor class holds three private properties to be used to instantiate one each of the three concrete prototype classes. The makeConProto() method generates the necessary instances.

Next, an “employee” instance is created using the clone technique. The cloned instance then sends unique instance information to a setter method (setEmployee()) that uses type hinting for the IAcmePrototype interface. However, note that it employs type hinting only for the first parameter. None of the other parameters have type hinting, and they do not have to be derived from the IAcmePrototype interface. All of the setter methods from the IAcmePrototype abstract class as well as the implemented setDept() methods from the concrete prototype classes are used by the cloned “employee.”

In order to use the data for each employee, the Client class uses the inherited getter methods. Figure 6-4 shows a simple output for each of the five employee clones.

You can add as many clones as required, and all you will ever need is a single instantiation of one of the concrete prototype classes. Instead of having several instances of the concrete classes, you have a single class instantiation and several clones.

The important point, perhaps the fundamental point, to keep in mind is that design patterns allow the developer to add and change a program without having to start all over. For example, suppose that the president of the company decides that a new division should be added to the company—Research, for instance. Would that be difficult to do? Not at all. A Research class could extend the IAcmePrototype abstract class and implement the abstract getter/setter methods to reflect the division’s organization. Note that the getter/setter methods in the Client class use code hinting to the interface and not a concrete implementation of the abstract class. So, as long as the added unit implements the interface correctly, it will slip into the application without making a wave or requiring refactoring of the other participants in the program.

In addition to adding more concrete classes, making changes within each class is just as easy and undisruptive. For example, suppose the marketing division of the organization decides that they need a special online marketing division apart from the current departments they have. The switch/case operation would need a single new case and a new private property (variable) to describe the added department. This change would not affect the other participants, encapsulated in their classes. The bigger the application, the more important it is that the change does not cause disruption, and as you can see, the Prototype design pattern allows for both consistency and change.

In looking at the Client class, you may be thinking that with a real organization, you’d have a lot more employees, and hardcoding them in a client doesn’t seem to be a very smart way of dealing with the problem. That’s absolutely true, and so we need to consider how to dynamically create clones from data stored in a database, an XML file, or somewhere other than a line of code in a client.

When you use a record from a database, you can pass that data to a PHP program to handle it. However, the data are not stored as instances of a concrete class but instead as numeric or string data of some kind. Take, for example, the following bit of data from the Client class:

$Tess=clone $this->mar;
$this->setEmployee($Tess,"Tess Smith",101,"ts101-1234","tess.png");
$this->showEmployee($Tess);

The data in the setEmployee() method arguments would normally come from a database and feed into the Client. The first parameter expects an object with the IAcmePrototype interface. So, the question is, how do you dynamically create (clone) an object based on data coming from a database?

PHP seems to be one of the most considerate languages around when it comes to dynamic creation. The process to take a variable and instantiate a class in PHP is quite simple. The following code creates an instance of a class from a value in a variable:

//Class name = MyClass
$myVar = "MyClass";
$myObj =new $myVar;

That’s it. The variable $myObj has just instantiated an instance of MyClass.

The code is equivalent to the following:

$myObj = new MyClass();

Using these techniques, you can dynamically create and clone objects from data coming from a database, array, or anywhere else you program gets it data.

In the following example, imagine that instead of an array, the data are coming from a database. The same principles apply. Note also that it employs an interface instead of an abstract class:

<?php
interface IPrototype
{
    const PROTO="IPrototype";
    function __clone();
}
class DynamicObjectNaming implements IPrototype
{
    const CONCRETE=" [Concrete] DynamicObjectNaming";

    public function __construct()
    {
        echo "This was dynamically created.<br/>";
    }

    public function doWork()
    {
        echo "<br/>This is the assigned task.<br/>";
    }

    function __clone() {}
}

$employeeData = array('DynamicObjectNaming','Tess','mar', 'John',
  'eng', 'Olivia','man' );
$don=$employeeData[0];
$employeeData[6]=new $don;
echo $employeeData[6]::CONCRETE;
$employeeData[6]->doWork();

$employeeName=$employeeData[5];
$employeeName = clone $employeeData[6];
echo $employeeName->doWork();
echo "This is a clone of " . $employeeName::CONCRETE . "<br/>";
echo "Child of: " . $employeeName::PROTO;
?>

When you run the program, you will see the following output:

This was dynamically created.
[Concrete] DynamicObjectNaming
This is the assigned task.

This is the assigned task.
This is a clone of [Concrete]
DynamicObjectNaming
Child of: IPrototype

Notice that in the initial instantiation, the constructor printed, “This was dynamically created.” That’s because the instantiation launched the operations in the constructor. However, in the cloning process, the cloned object did not launch the constructor. Nevertheless, the clone could use any assigned values generated from the initial instantiation of the class that was passed to the cloned object.

Because PHP is a server-side language and is a key tool for interacting with a MySQL database, the Prototype design pattern is an especially good option. Instead of having to create new objects for every element in a database, PHP can use the Prototype to create single instances of a concrete class and then clone the rest of the cases (records) from the database.

After looking at the cloning process compared with direct instantiation of an object from a class, you may well ask yourself, “What’s the difference?” In other words: Why do clones use fewer resources than objects instantiated directly from a class? The big difference is in what you do not see. When an object creates an instance through cloning, it does not fire the constructor. In the DynamicObjectNaming class application, you saw an example of where the direct instantiation fired off the constructor and the clone did not. The clone had all of the properties of the original class and even parent interface, but it also inherited any values that had been passed to the instantiated object. Any values generated by the constructor function and stored in the object properties become a part of the object. So there is no need to rerun the constructor. If you find that your clones do need access to values generated by the constructor function but cannot access them, it’s time to refactor your class so that instantiated instances have everything they need and can pass that on to the clone.

Overall, the Prototype can be applied in several different kinds of PHP projects where a problem solution calls for a creational pattern. This chapter has provided a couple of different examples, but now that you have a better idea of what the Prototype pattern does and how to use it, keep an eye open for opportunities to employ it. If you do, you can expect to save development time and improve your design for changes that may occur.