Showing posts with label design patterns. Show all posts
Showing posts with label design patterns. Show all posts

Monday, July 20, 2009

Build seven good object-oriented habits in PHP

With PHP's object-oriented (OO) language features, if you aren't already creating your applications with OO principles in mind, these seven habits will help you get started in the transition between procedural programming and OO programming.
In the early days of PHP programming, PHP code was limited to being procedural in nature. Procedural code is characterized by the use of procedures for the building blocks of the application. Procedures offer a certain level of reuse by allowing procedures to be called by other procedures.

However, without object-oriented language constructs, a programmer can still introduce OO characteristics into PHP code. It's a tad more difficult and can make the code more difficult to read because it's mixing paradigms (procedural language with pseudo-OO design). OO constructs in PHP code - such as the ability to define and use classes, the ability to build relationships between classes that use inheritance, and the ability to define interfaces - make it much easier to build code that adheres to good OO practices.

While purely procedural designs without much modularity run just fine, the advantages of OO design show up in the maintenance. Because a typical application will spend the bulk of its lifetime in maintenance, code maintenance is a large expense over the lifetime of an application. It can also be easily forgotten during development. If you're in a race to get your application developed and deployed, long-term maintainability can take a back seat to getting something to work.

Modularity - one of the key characteristics of good OO design - helps with this maintenance. Modularity helps encapsulate change, which will make it easier to extend and modify the application over time.
While there are more than seven habits to building OO software overall, the seven habits here are what you need to make your code fit basic OO design criteria. They give you a firm foundation upon which you can add more OO habits and build software that is easily maintained and extended. These habits target a couple of the key characteristics of modularity.
The seven good PHP OO habits are:
  1. 1. Be modest.
  2. 2. Be a good neighbor.
  3. 3. Avoid looking at Medusa.
  4. 4. Embrace the weakest link.
  5. 5. You're rubber; I'm glue.
  6. 6. Keep it in the family.
  7. 7. Think in patterns.

Saturday, May 23, 2009

The chain-of-command pattern using PHP

Building on the loose-coupling theme, the chain-of-command pattern routes a message, command, request, or whatever you like through a set of handlers. Each handler decides for itself whether it can handle the request. If it can, the request is handled, and the process stops. You can add or remove handlers from the system without influencing other handlers. Chain.php shows an example of this pattern.

Chain.php

<?php
interface ICommand {
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 UserCommand implements ICommand {
public function onCommand($name, $args) {
if ($name != 'addUser') return false;
echo( "UserCommand handling 'addUser'\n" );
return true;
}
}

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

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


This code defines a CommandChain class that maintains a list of ICommand objects. Two classes implement the ICommand interface -- one that responds to requests for mail and another that responds to adding users. The UML is shown in the figure.

The strategy pattern using PHP

In the strategy pattern, algorithms are extracted from complex classes so they can be replaced easily. For example, the strategy pattern is an option if you want to change the way pages are ranked in a search engine. Think about a search engine in several parts -- one that iterates through the pages, one that ranks each page, and another that orders the results based on the rank. In a complex example, all those parts would be in the same class. Using the strategy pattern, you take the ranking portion and put it into another class so you can change how pages are ranked without interfering with the rest of the search engine code.
As a simpler example, Strategy.php shows a user list class that provides a method for finding a set of users based on a plug-and-play set of strategies.

Strategy.php



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

class FindAfterStrategy implements IStrategy {
private $_name;

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

public function filter($record) {
return strcmp($this->_name, $record) <= 0;     } }  class RandomStrategy implements IStrategy {     public function filter($record) {         return rand(0, 1) >= 0.5;
}
}

class UserList {
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 UserList(array("Andy", "Jack", "Lori", "Megan"));
$f1 = $ul->find( new FindAfterStrategy("J") );
print_r($f1);

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

The observer pattern using PHP

The observer pattern gives you another way to avoid tight coupling between components. This pattern is simple: One object makes itself observable by adding a method that allows another object, the observer, to register itself. When the observable object changes, it sends a message to the registered observers. What those observers do with that information isn't relevant or important to the observable object. The result is a way for objects to talk with each other without necessarily understanding why.
A simple example is a list of users in a system. The code below shows a user list that sends out a message when users are added. This list is watched by a logging observer that puts out a message when a user is added.

Observer.php

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

interface IObservable {
function addObserver($observer);
}

class UserList implements IObservable {
private $_observers = array();

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

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

class UserListLogger implements IObserver {
public function onChanged( $sender, $args ) {
echo( "'$args' added to user list\n" );
}
}

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


This code defines four elements: two interfaces and two classes. The IObservable interface defines an object that can be observed, and the UserList implements that interface to register itself as observable. The IObserver list defines what it takes to be an observer, and the UserListLogger implements that IObserver interface.

The singleton pattern using PHP

Some application resources are exclusive in that there is one and only one of this type of resource. For example, the connection to a database through the database handle is exclusive. You want to share the database handle in an application because it's an overhead to keep opening and closing connections, particularly during a single page fetch.
The singleton pattern covers this need. An object is a singleton if the application can include one and only one of that object at a time. The code below shows a database connection singleton in PHP5.

Singleton.php

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

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

private $_handle = null;

private function __construct() {
$dsn = 'mysql://root:password@localhost/photos';
$this->_handle =& DB::Connect($dsn, array());
}

public function handle() {
return $this->_handle;
}
}

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


This code shows a single class called DatabaseConnection. You can't create your own DatabaseConnection because the constructor is private. But you can get the one and only one DatabaseConnection object using the static get method.

The factory pattern using PHP

Many of the design patterns in the original Design Patterns book encourage loose coupling. To understand this concept, it's easiest to talk about a struggle that many developers go through in large systems. The problem occurs when you change one piece of code and watch as a cascade of breakage happens in other parts of the system -- parts you thought were completely unrelated.
The problem is tight coupling. Functions and classes in one part of the system rely too heavily on behaviors and structures in other functions and classes in other parts of the system. You need a set of patterns that lets these classes talk with each other, but you don't want to tie them together so heavily that they become interlocked.
In large systems, lots of code relies on a few key classes. Difficulties can arise when you need to change those classes. For example, suppose you have a User class that reads from a file. You want to change it to a different class that reads from the database, but all the code references the original class that reads from a file. This is where the factory pattern comes in handy.

The factory pattern is a class that has some methods that create objects for you. Instead of using new directly, you use the factory class to create objects. That way, if you want to change the types of objects created, you can change just the factory. All the code that uses the factory changes automatically.
Factory1.php shows an example of a factory class. The server side of the equation comes in two pieces: the database, and a set of PHP pages that let you add feeds, request the list of feeds, and get the article associated with a particular feed.

Factory1.php

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

class User implements IUser {
public function __construct( $id ) { }

public function getName() {
return "Jack";
}
}

class UserFactory {
public static function Create( $id ) {
return new User( $id );
}
}

$uo = UserFactory::Create( 1 );
echo( $uo->getName()."\n" );
?>






An interface called IUser defines what a user object should do. The implementation of IUser is called User, and a factory class called UserFactory creates IUser objects.