#native_company# #native_desc#
#native_cta#

Exploring PHP Design Patterns

By Kaushik Pal
on May 28, 2014

Overview

Design patterns have become an essential part in today’s application development, regardless of the specific technology. The same is true in the world of PHP development–commonly used design patterns are also followed in PHP.

This article will discuss the different design patterns that are used in the PHP domain with some sample applications.

 

Introduction

Design patterns provide a generic reusable solution to common problems. A design pattern is not a concrete solution that can be converted in to source code or a machine code rather it is a template which can be used to solve a problem in different situations. Design patterns help in faster development as the templates are proven and from the developer’s point, only implementation is required. Design patterns not only make software development faster but also encapsulate big ideas in a simpler way. In the PHP world, following five design patterns are used in general:

      •The Factory Pattern

      •The Singleton Pattern

      •The Observer Pattern

      •The Chain of Command Pattern

      •The Strategy Pattern

The Factory Pattern

The factory pattern provides a solution that enables loose coupling, thus helps us to get rid of tight coupling problem. As a developer we all are well aware of the changes faced while we maintain a code that is tightly coupled. Factory pattern provides a class having some methods to create objects for us at runtime. Instead of creating the instance directly we use the factory to create the objects for us. Thus, if we have to change the type of the object created, we just need to change the factory. The following code is an example of factory implementation in PHP.

Listing 1: A sample factory implementation in PHP

<?php
interface Customer
{
  function getName();
}

class Customer implements Customer
{
  public function __construct ( $id )  { }

  public function getName ()
  {
    return "PHP – Factory Pattern";
  }
}

class CustomerFactory
{
  public static function Create ( $id )
  {
    return new Customer ( $id );
  }
}

$uo = CustomerFactory::Create ( 1 );
Echo ( $uo->getName()."n" );
?>

In the example above, we have an interface called “Customer” that has the definition of the object. This interface is implemented in the class Customer. The factory class CustomerFactory creates the Customer objects. If we execute this code on the command line that has a PHP interpreter, we get the result as:

% php factorySample.php 
PHP – Factory Pattern 
%

The Singleton Pattern

As the name suggests, singleton pattern allows only one instance to be created. While developing an application, we come across many situations where we need to have just one instance of an object. This instance can be shared by different processes. E.g. a database connection objects. It is always advised to create and destroy the database connection object in order to avoid the overhead of opening and closing the connection. The following code shows how to implement Singleton in PHP.

Listing 2: Singleton implementation in PHP

<?php
require_once("DB.php");

class DatabaseConnection
{
  public static function getDBO ()
  {
    static $db = null;
    if ( $db == null )
      $db = new DatabaseConnection();
    return $db;
  }

  private $_handle = null;

  private function __construct()
  {
    $dsn = 'mysql://root:password@dbhost/dbinstance';
    $this->_handle =& DB::Connect( $dsn, array() );
  }
  
  public function handle()
  {
    return $this->_handle;
  }
}

print( "Handle = ".DatabaseConnection::get()->handle()."n" );
print( "Handle = ".DatabaseConnection::get()->handle()."n" );
?>

The code above shows how to get the db connection using the singleton approach. The private constructor in this class ensures that it can’t be called from outside the class. The static method – getDBO () is called from the caller class to get the DB connection object.

The Observer Pattern

The observer pattern is very straight forward. An object is made observable by adding a method that allows another object, the observer to get registered. If the observable object gets changed, it sends a message to the objects which are registered as observers. The following code shows how to implement the Observer pattern.

Listing 3: Observer Pattern implementation in PHP

<?php
interface Observer
{
  function onChanged( $sender, $args );
}

interface Observable
{
  function addObserver( $observer );
}

class CustomerList implements Observable
{
  private $_observers = array();

  public function addCustomer( $name )
  {
    foreach( $this->_observers as $obs )
      $obs->onChanged( $this, $name );
  }

  public function addObserver( $observer )
  {
    $this->_observers []= $observer;
  }
}

class CustomerListLogger implements Observer
{
  public function onChanged( $sender, $args )
  {
    echo( "'$args' Customer has been added to the list n" );
  }
}

$ul = new UserList();
$ul->addObserver( new CustomerListLogger() );
$ul->addCustomer( "Jack" );
?>

The code above defines two interfaces and their respective implementation classes.

The Chain of Command Pattern

The chain of command pattern is another pattern that is based on the concept of loose coupling. Here each handler decides whether it can handle the request or not. If it can, the request is handled and the process is stopped. If not, the request is then passed to the next handler and so on. The following code is a sample implementation of this pattern.

Listing 4: Sample code implementing Chain of Command Pattern

<?php
interface Command
{
  function onCommand( $name, $args );
}

class CommandChain
{
  private $_commands = array();

  public function addCommand( $cmd )
  {
    $this->_commands []= $cmd;
  }

  public function runCommand( $name, $args )
  {
    foreach( $this->_commands as $cmd )
    {
      if ( $cmd->onCommand( $name, $args ) )
        return;
    }
  }
}

class CustCommand implements Command
{
  public function onCommand( $name, $args )
  {
    if ( $name != 'addCustomer' ) return false;
    echo( "This is CustomerCommand handling 'addCustomer'n" );
    return true;
  }
}

class MailCommand implements Command
{
  public function onCommand( $name, $args )
  {
    if ( $name != 'mail' ) return false;
    echo( "This is MailCommand handling 'mail'n" );
    return true;
  }
}

$cc = new CommandChain();
$cc->addCommand( new CustCommand() );
$cc->addCommand( new MailCommand() );
$cc->runCommand( 'addCustomer', null );
$cc->runCommand( 'mail', null );
?>

The Strategy Pattern

The strategy pattern is based on algorithms. The complex algorithms are extracted from the classes so that they can be replaced easily. Strategy pattern is based on the plug and play theory. A common implementation of strategy pattern occurs if we want to change the way in which the pages are ranked in search result page. A sample implementation is shown below.

Listing 5: Sample implementation of Strategy pattern

<?php
interface Strategy
{
  function filter( $record );
}

class FindAfter implements Strategy
{
  private $_name;

  public function __construct( $name )
  {
    $this->_name = $name;
  }

  public function filter( $record )
  {
    return strcmp( $this->_name, $record ) <= 0;
  }
}

class FindRandom implements Strategy
{
  public function filter( $record )
  {
    return rand( 0, 1 ) >= 0.5;
  }
}

class CustomerList
{
  private $_list = array();

  public function __construct( $names )
  {
    if ( $names != null )
    {
      foreach( $names as $name )
      {
        $this->_list []= $name;
      }
    }
  }

  public function add( $name )
  {
    $this->_list []= $name;
  }

  public function find( $filter )
  {
    $recs = array();
    foreach( $this->_list as $user )
    {
      if ( $filter->filter( $user ) )
        $recs []= $user;
    }
    return $recs;
  }
}

$ul = new CustomerList( array( "Dan Joe", "Ric Anderson", "Nick Paul", "Megan Pit" ) );
$f1 = $ul->find( new FindAfter( "J" ) );
print_r( $f1 );

$f2 = $ul->find( new FindRandom());
print_r( $f2 );
?>

Here, the CustomerList class is a wrapper that has an array of some names. This class implements a find method that takes one of several strategies for selecting a subset of those names. The strategies are defined by the Strategy interface, which has two implementations: The first one chooses the customers randomly while the other chooses all the names after a specified name.

Summary

Design patterns are great ideas that can be used in any programming language, including PHP. We have discussed the most common design patterns used in PHP applications.

      •Design patterns are used in every technology to help developers follow a common reusable solution approach for common problems.

      •Design Patterns are not concrete but are conceptual.

      •Like other languages, PHP also uses the common design patterns, some of which are explained above.

About the Author

Kaushik Pal is a technical architect with 15 years of experience in enterprise application and product development. He has expertise in web technologies, architecture/design, java/j2ee, Open source and big data technologies. You can find more of his work at www.techalpine.com and you can email him here.