Ready for Production
Before a product goes into full production, manufacturers design a prototype to work out the bugs and improve the design. Once the prototype is ready, it is ready for production. Then all of the production copies are based on the prototype. (Of course, if you get the prototype wrong, all of your production elements will be wrong as well.)
One of the nice things about OOP is that abstract classes and interfaces act a lot like prototypes. They provide a basic design and allow the individual implementations to make variations. Think of an automobile that has certain key elements to it based on a prototype. If you have a Ford, Toyota, Volkswagen or Saab, you get a car based on a certain prototype, but you can have different characteristics based on the prototype such as color and a choice of leather or vinyl seat covers. (Even more choices are available with the Decorator pattern!) To get started, run the sample program (Outlaws and Lawmen of the Old West) and download the files:
One of the more challenging aspects of the creating a Prototype pattern is the cloning, but as you saw in Part I of the Prototype discussion, in PHP, cloning is easy. So, now all we have to do is to take a quick look at the class diagram and then look at the code:

Figure 1: Prototype class diagram
The Prototype Interface
This example uses an abstract class for an interface. In looking at the class diagram, all we really need is an abstract __clone() function, but adding some concrete and abstract getters and setters give us a bit more to work with. At the very base, the properties include:
- A name (sobriquet)
- A photo (poster)
- Where they lived (location)
All of the functions (except one) could be abstract or all of them could be abstract, but since this is for illustration purposes, I put in some of both. I like using properties in abstract classes, and so this excludes using interfaces since they can only have abstract classes and CONSTANTS. However, if the properties ($sobriquet, $poster, and $location) were omitted, I could use an interface.
< ?php //IWestlaw.php abstract class IWestLaw { protected $sobriquet; protected $poster; protected $location; //Outlaw or Lawman abstract function setPlace($where); abstract function getPlace(); abstract function __clone(); //Sobriquet public function setSobriquet($nickname) { $this->sobriquet=$nickname; } public function getSobriquet() { return $this->sobriquet; } //Wanted Poster or Lawman Pose public function setPoster($ePic) { $this->poster="posters/" . $ePic . ".png"; } public function getPic() { return $this->poster; } } ?> |
Once implemented, the client can then use clones of the implementations. However, we first need to implement the concrete prototype classes that will be cloned.
The Outlaw and Lawmen Prototype Implementations
This example has two implementations of the IWestlaw abstract class. The only difference between the two is that the Outlaw class has a constant that identifies the outlaw as such, and it has a property, along with appropriate getter/setter methods, that identifies the outlaw’s criminal preferences.
< ?php //Outlaw.php include_once('IWestLaw.php'); class Outlaw extends IWestLaw { const LAWSIDE="Outlaw"; private $crime; public function setPlace($where) { $this->location=$where; } public function getPlace() { return $this->location; } public function setCrime($doneWrong) { $this->crime=$doneWrong; } public function getCrime() { return $this->crime; } function __clone(){} } ?> |
At the very bottom of the implementation is the __clone() implementation. Because all I’m concerned with is the capacity to clone an instance of the implementation, there’s no reason to place any content in the __clone() method. The added getter/setter for the $doneWrong (crime) property will not be part of the Lawman implementation of the IWestLaw interface (abstract class).
Continue reading ‘PHP Prototype Design Pattern Part II: From Prototype to Production’
Recent Comments