A brief intro to design patterns

#1

If you have done any kind of PHP interviews recently, you’ll have heard questions like “What is a design pattern?”. Maybe you know already - maybe you don’t. I’m writing this to help provide a concise, pragmatic list to all the common ones in PHP.

Before doing this, however, it is useful to define what a design pattern is. A design pattern is a code pattern that aims to solve a common, recurring, general problem often using methods and approaches native to object-oriented programming.
If you are not familiar or rusty with PHP OOP fine details, I’d strongly recommend you bring the PHP doc up as you read this.

What patterns do:

  • They allow you to dramatically streamline your code and increase your productivity by reducing copy-pasta
  • They allow you to build cool techniques to overcome classical modular pitfalls
  • They can also, however, if used improperly, cause a lot of headaches, create a lot of hidden bugs, and generally become a living nightmare

Patterns’ best friends:

  • Unit testing. By using patterns, you’ll be naturally breaking your code down into stand-alone elements. Unit-testing is the single best way to check that your code still works.
  • Frameworks. A lot of frameworks around implement tools to get around the issues brought up by a couple of patterns.

[size=14pt]1. Types of patterns[/size]

Patterns can be creational, structural or behavioral:

  • Creational patterns deal with the creation and safe-keeping of an object. Common examples: Factory, Singleton, Prototype.
  • Structural patterns consider an object as part of a larger structure, and allows you to generate and implement interfaces for this object. Common examples: Flyweight, Adaptor, Facade
  • Behavioral patterns are solely concerned with how an object communicates with other objects, or integrates within a code-base while allowing other objects to query its state. Common examples: Observer, Pub/Sub (known as Mediator), Strategy, Iterator (this one is native within PHP), Promise (this one is not useful in PHP, but is very handy in other languages)

All the common examples noted here will be explored in this tutorial. Please note that [i]whilst this tutorial is aimed at PHP[i], ALL the patterns are universal. They can be implemented in any language that has the notion of classes.

I will structure this into multiple posts, one for each type, and will cross-link them as I type them.

#2

[size=14pt]Creational patterns[/size]

Creational patterns, as stated before, allow you to neatly wrap the creation of your objects and assist in something called composition. Composition is the act of merging (and mixing) explicitely distinct objects into one object. Let’s go over the simplest one of those:

[size=12pt]the Factory pattern[/size]
This is one of the most widely used patterns and you will no doubt come across it in third-party frameworks. The case for it is very simple:

  • You have multiple objects respecting the same interface , which perform the same purpose, and
  • You want to instantiate the objects referred to in point 1 without having to explicitely know the class names for them

The best use for them is to implement database drivers. Suppose you have two drivers, MySQL and MSSQL, which both implement the following interface:
[php]<?php
interface DBDriver {
public function query($q, stdClass $params);
public function connect(stdClass $config);
}[/php]

As both of your elements (DBMySQL implements DBDriver, DBMSSQL implements DBDriver) implement the same interface, you know that you can use the same methods on them. The only branching point in your code is the class name.
An if statement could work. However, this requires hard-coding, which is not necessarily the best way forward. A much better way would be this:
[php]
class DBFactory {
public static function getConnector($type) {
$t = “DB”.$type;
return new $t();
}
}[/php]

This assumes that you are using SPLAutoLoad to lazy-load your database drivers. In practice, you’ll want to keep a list of the drivers somewhere - ideally, in your config. Once you have the connector, you can use the methods implemented by the interface without fear of the object not being correct.

What this implements:

  • Directory object lookup based on implementation of an interface
  • Object creation without up-front knowledge of the explicit class name

Problems that this create:

  • The need to use SPLAutoLoad or a list of objects
  • One static method (optional)

Cool things to mix it with:

  • Singleton
  • Observer
  • Memento
#3

[size=12pt]the Singleton pattern[/size]

The Singleton is arguably the most widely used pattern and aims to solve the simple problem of “What if I don’t want more than one instance of an object?”.

Sometimes, you want to limit your object instantiation to a maximum of one instance. This may be because the constructor of those is computationally-intensive, requires you to do something that you only want to do once, because you cannot have concurrent connections to a third-party service or maybe simply because you don’t want to. This is where this pattern comes into play.

It relies on a trick: you can set the constructor of a class to private, and this prevents the class from being instantiated outside itself. In other words, you ban the new keyword by doing this.

The pattern itself is as follows:
[php]<?php
class Singleton {
private static $instance;
private function __construct() {
}
public static function getInstance() {
if (!isset(static::$instance)) static::$instance = new self();
return static::$instance;
}
}[/php]

The pattern is trivial to understand: you set the constructor to private, which prevents members outside the scope of the class to instantiate it (thus banning the new keyword). You then define a static method “getInstance” whose sole purpose is to keep track of a single instance of the object, stored in static::$instance. If it exists, it is returned. If it doesn’t, it is instantiated (inside the class!) and then returned.

It comes at a heavy cost, however:

  • You need to know the exact class name to invoke a singleton. This is a much bigger cost than you may think, as it prevents you from mocking your objects for unit testing. You can get around this one by using a Service Locator (featured at: http://www.devshed.com/c/a/PHP/Building-a-service-Locator-in-PHP/ and not covered in this) or dependency injection/Inversion of Control.
  • The static field is only one step better than a global variable, in that it prevents a user from accidentally overwriting it

Cool things to mix it with:

  • Memento
  • Any kind of database connector!
#4

[size=12pt]The Prototype pattern[/size]

This one can be skipped if necessary, as it is not very interesting or important. It is quite simply a way to keep track of the default state of an object by creating them using clone rather than new. You start with an object, and each time you want to create a new one, you clone the first.

The good points:

  • It allows you to keep the internal state of an object along with its references across all objects that are cloned

The bad points:

  • Mostly pointless except in specific circumstances: ORM model instances.
#5

[size=14pt]Structural patterns[/size]

Structural patterns allow you to make your code integrate within other stuff, and allows you to patch objects to generate something called standard interfaces in order to cut down on edge cases in your code. They are less fundamental than the creational patterns, but equally (if not more) important. Their purpose, however, may not be evident at first.

[size=12pt]The Flyweight pattern[/size]

A flyweight is a small weight. The flyweight pattern allows you to deal with lots of little objects which all share a similar internal state. Think of it as a collection of objects that are related to each other in their type, and possess properties linked to it.

The best example of this is actually found in videogames like Advance Wars. All the little soldiers in the same type have the same sprite, max health and attack range. Their current health is the only thing that differs. A common thing to combine it with is a collection to keep all the Flyweights of a given type in.

Everyone has a different way to do Flyweights. I personally work on them in this fashion:
[php]<?php
class FlyweightInstance {
public static $type;
public function __construct(FlyweightDefinition $type, stdClass $properties) {
self::$type = $type;
foreach ($properties as $k => $v) {
$this->$k = $v;
}
}
public function getProperty($name) {
if (isset($this->$name)) return $this->$name;
if (isset(self::$type[$name])) return self::$type[$name];
return null;
}
}
class FlyweightDefinition {
}[/php]

In addition to working seamlessly, this also allows me to blur the definition between shared properties and extrinsic properties when doing lookups, which allows me to override certain properties if I want to.
Each flyweight element takes a minimum of 32 bytes of memory + additional per overridden property. This makes them extremely good to deal with in large numbers.

This works particularly well with:

  • Iterators, to iterate on the collection.
  • Observers, to track and broadcast their state.
#6

[size=12pt]The Adaptor pattern[/size]

This design pattern comes in handy when dealing with third-party code and allows you to quite literally wrap an object with incompatible methods into a form that you can use with other interfaces seamlessly. In other words, instead of doing this:

[php]

<?php if ($myObject instanceof IncompatibleClass) { // Do stuff } else { // Do stuff }[/php] You start off by defining an abstract class to require the implementation of certain methods. You then cause all your objects of this type to extend the adaptor, which forces them to implement those... thus getting rid of the if statement. The best example of this is actually in PHP itself - it's called PDO. The underlying DB connector libraries actually have wildly different interfaces and exposed methods. PDO itself is a combination of the [b]factory[/b] and [b]adaptor[/b] patterns as a result. A userland case would be as follows: [php]<? class DBAdaptorInterface { abstract public function query($queryString); abstract public function connect(stdClass $settings); }[/php] You can then define your objects as extending [b]DBAdaptorInterface[/b], which guarantees that they will have to implement both [b]query[/b] and [b]connect[/b]. If you have an object which does not support it, you then do this: [php]<?php class DBAdaptor extends DBAdaptorInterface { private $stateObject; public function __construct() { $this->stateObject = new myIncompatibleDBConnector(); } public function query($queryString) { return $this->stateObject->runMyQueryInASillyIncompatibleWay($queryString); } public function connect(stdClass $settings) { return $this->stateObject->fakeConnect(); } }[/php] From there, defining this allows you to knock out all your if/else statements as you can now consider all your DB connectors as fulfilling the same interface promise: they will all have query, and they will all have connect. The cost of doing this is a slight overhead in your code, offset by less logic on every query. [b]What this teams up really well with[/b]: - Factory method. The link should be obvious - Builder (not explained in this) - Strategy [b]Want another epic example of Adaptor?[/b] jQuery is one.
#7

[size=12pt]The Facade pattern[/size]

If you have used any MVC approach, you’ve used this one. It’s the C part of MVC. The approach is simple: instead of allowing direct access to all your components, you funnel the client through a simplified, one-object interface. The client then only needs to learn how to do stuff with that object without having to rely on the underlying fine details of the system.

This funneling process defines a new set of methods on the facade: a new interface. It binds together components of a subsystem and allows a user to use methods such as insert(), that are effectively shorthand methods connecting various bits together.

This one comes with caveats:

  • The system does NOT know about the facade. The facade is transparent to the system, but opaque to the user.
  • A Facade is NOT an Adaptor. A facade creates a new interface, an adaptor merely allows you to make incompatible objects follow the same interface. However, they’re both wrappers… One just applies to lots of objects

A typical example:
[php]<?php
Class MySystemFacade {
public function sendBlogItem($title, $content) {
$item = $this->blog->create_item($title,$content);
$this->blog_pingbacks->ping($item);
return $item;
}
// More methods here. $this->blog and $this->blog_pingbacks are usually dependency-injected and set to private; The user cannot access them directly
}[/php]

This pattern kicks serious ass when combined with the Singleton pattern, as you only need one facade per subsystem!

#8

[size=14pt]Behavioral patterns[/size]

Behavioral patterns deal with the common problems that arise with modular code: how modules interact with each other. This has been a teething issue ever since people started writing code to extend third-party code without having to actually modify third-party source.

A lot of the concepts have been in code for a long while, and a lot of the concepts will most likely rarely go away. They are of key importance, and failure to use them inevitably leads to bulky, unextensible code.

[size=12pt]The Observer pattern[/size]

This is the simplest behavioral pattern, and anyone using the DOMContentLoaded event in JS has already used it. Its premise is simple: binding callbacks on objects, and teaching your objects to use these callbacks to notify other parts of the codebase of state changes.

The simplest implementation would be something like this:
[php]<?php
class MyObject {
private $callbacks = array();
public function observe(Callable $cb) {
$this->callbacks[] = $cb;
}
protected function fireCallbacks() {
$ct = count($this->callbacks);
for ($i = 0; $i < $ct; $i++) {
$this->callbacks$i;
}
}
public function SomeRandomTask() {
$this->fireCallbacks();
}
}[/php]

It is useful to note that this pattern has a PHP native interface (http://php.net/manual/en/class.splobserver.php). The actual PHP implementation is a bit more complex than my example in that it allows multiple subjects - consider them event types.

#9

[size=12pt]The Mediator Pattern[/size]

The Mediator pattern allows objects to relate together using a single common point without having to directly relate together. In effect, it takes the Observer pattern and wraps it inside out. This is the basis of most event systems around.

Instead of binding observers to subjects, you bind observers to communication channels on a mediator. You then have your subjects broadcast on the channel.

A simple example:
[php]<?php
class Mediator {
private $callbacks = array();
public function listenOn($channel,$cb) {
if (!isset($this->callbacks[$channel])) $this->callbacks[$channel] = array();
$this->callbacks[$channel][] = $cb;
}
public function broadcast($channel,$data) {
if (!isset($this->callbacks[$channel])) return true;
foreach ($this->callbacks[$channel] as $v) {
$v($data);
}
}
}[/php]

This pattern allows you to decouple your code in a way that is quite important: it does not require you to know the reference to objects or their exact names. It is therefore incredibly useful and most modern frameworks implement it in one way or another (even Wordpress has it, and WP is old.).

#10

[size=12pt]The Strategy pattern[/size]

Sometimes, you have a piece of code that can run along different paths to provide a certain piece of data. This is mostly the case when dealing with algorithms or when trying to solve graphing problems. The Strategy pattern aims at providing a run-time patching and branching mechanism so that your class can, based on a user input, change the algorithm it uses.

A good example of this is a Google Maps analogy. Suppose you are building a GMaps solver to get from point A to point B. However, to do so, you can use a wide variety of paths with a wide variety of rules: cars, which can only follow roads. Pedestrians (foot transport), which can take paths. Airplanes, which fly straight over. Ideally, you want to be able to compute the time taken by just specifying “plane” and letting the object do the work.

A Strategy is a wrapper for a collection of objects, same as the Flyweight, Facade, Decorator etc. However, unlike all those, it only abstracts away a method from a class. Effectively, it allows your code to run without the user knowing the exact name of the class implementing the algorithm you’re after.

A Strategy implementation often takes the following form:
[php]<?php
class MyStrategyImpl {
function __construct($type) {
switch ($type) {
case “case1”:
$this->strategy = new case1impl();
break;
case “case2”:
$this->strategy = new case2impl();
}
}
function getInfo() {
return $this->strategy->getDistance();
}
}[/php]

It is very similar to an Adaptor. The only difference is that the Adaptor retrofits - a Strategy offers a choice.

#11

[size=12pt]The Iterator pattern[/size]

This one actually is built into PHP since PHP 5.1. It effectively provides an interface which allows you to loop over objects that may not be objects. So, instead of having an array holding your objects, you create an Iterator, which then fits neatly into a foreach using the Iterator family of interfaces.

More info here: http://www.php.net/manual/en/class.iteratoriterator.php

#12

[size=12pt]The Promise pattern[/size]

The Promise pattern is not widely used in PHP due to its single-threaded nature. However, there are uses for it, and one of them is the checks performed on curl_multi_exec(), which is an asynchronous process.

A Promise pattern is a special case of an Observer pattern. Instead of firing multiple events, it fires to its callbacks when it is done. It will be possible to do this in PHP 5.5, but until then…this pattern is limited to JS.

Effectively, one can completely describe the Promise pattern as an Observer pattern with a special “complete” channel.

#13

Great info, very detailed. Thanks! :slight_smile: