Thursday, September 4, 2008

PHP Design Patterns

Design patterns are basically a general method that can be used in solving a variety of different problems. Read how Jason uses PHP to demonstrate how design patterns work.What are Design Patterns

Design Patterns are simply defined solutions to common problems. Design patterns are not created by someone who sits in a room and decides to make a design pattern instead design patterns are proven solutions that are implemented over and over again through different projects. This re-use of the solution itself becomes a pattern. Don’t be intimidated by the fancy names given to design patterns, such as façade, singleton or observer, they are exactly that just fancy names given to repeatable solutions.

What Design Patterns Are NOT

A design pattern is NOT a template rather a proposed solution that is not implementation specific. In other words you can take the same design pattern and implement it with any language, of course if the design pattern is an OO design pattern you need to implement it with an object-oriented language. More importantly the implementation itself may vary from project to project because of project restraints and requirements.

A design pattern is NOT a framework, though depending on whom you speak to, a group of design patterns maybe considered as a design framework.
Why Use Design Patterns

Most PHP developers may first ask why use Design Patterns or why design in the first place. After all PHP is a scripting language usually used for simple web development, aren’t functions are good enough?

Yes this is probably true if you work alone on small projects. But you will find Design and Design Patterns are beneficial in regards of:

Maintenance
Documentation
Readability
Easy when developing in large development teams
Developing Code to be used by other then yourself
With PHP becoming more and more mature, especially with PHP5 it is said it will be ready for the Enterprise world, see the following article http://www.theopenenterprise.com/shared/printableArticle?doc_id=TOE20021204S0001.

If this indeed is true then object-oriented development and design pattern skills are a definite asset to your resume. Most enterprise applications that succeed are because of the fact that a good methodology and development process is in place, and apart of that comes design and with design more then likely comes design patterns.

However there is a trade off with design patterns because it adds another layer/component of abstraction there maybe a loss in performance and efficiency. Granted this may not be noticeable on high-end servers, but could be problem on low-end servers.

Going off topic for moment, this is especially so when developing J2ME mobile applications, this would be prime example where coding like style would be more dominant then object-oriented coding purely for the fact that memory and heap size on mobile devices is limited.

Using Design Patterns with PHP

It is assumed you are familiar with object-oriented programming and more specifically object oriented programming with PHP, if not please refer to the DevArticle - Object Oriented Programming in PHP by Luis Argerich, http://www.devarticles.com/art/1/349.

There isn’t any point in redoing what other design pattern books completed already, nor is it possible to go over everything is to know about Design Patterns in a short article like this. For demonstration purposes I will briefly go over one of my favorite patterns in web development, validation using the Strategy Pattern.

Here is the UML diagram:


UML diagram


Diagram from phpPatterns.com by Harry Fuecks, visit phpPatterns for the full source code

For more detail explanation and complete source code for the validation using Strategy Pattern visit phpPatterns.com.

Possible code for a member sign up form would be:

if ( isset ($_POST['submit']) ) {
if ($strlen($member) > 16) {
// errormsg
}
if ($strlen($firstname) > 24) {
}
// - Check if firstname only contains charcters
// - Check firstname doesn’t contain reserved words
// like root
// - Check firstname doesn’t contain unacceptable words
// like swear words
// -
//
// ETC
}

This can get really complex and hard to maintain once you add in other required information such as country, postal code, address, primary phone, secondary phone, email, company name, … etc.

As well it isn’t uncommon to have the same validation used in many places for example email would be validated during the signup process, login process (used as member name), forgot password, change email preference, newsletter signup and referral signup. As well some data may require the same type of validation such as first name, last name, member name and address. With the above code you might end up with a lot redundant code.

Of course, it is quite possible to use functions, and then you face the problem of making unique function names. Even with functions you will still find redundant code for things like error message handling other set of nested functions that make code maintenance more difficult.

To encapsulate this logic in a more efficient and maintainable approach would be to use the Strategy Pattern. Now with the Strategy Pattern in place the actually call to the validation classes are a lot more cleaner:

if ( $_POST['register'] ) {
require_once(’lib/Validator.php’);
// Register the subclasses to use
$v['u']=new ValidateUser($_POST['user']);
$v['p']=new ValidatePassword($_POST['pass'],$_POST['conf']);
$v['e']=new ValidateEmail($_POST['email']);
$v['p']=new ValidateFirstName($_POST[‘pass’],$_POST[‘conf’]);
// Perform each validation
// process error msg
// .. continue program
}

As you can see there are several benefits that come with using the Strategy Pattern for validation:

Reuse error message handling.

You can easily add or remove validation classes simply be adding or remove classes that inherit from Validator.

Each child validation classes encapsulates its own set of requirements for validation which makes easier for any future maintenance and reduces the necessary regression testing.

A common interface makes reusability of the same validation classes available in several parts of an application but with only one common area of maintenance.
Visit phpPatterns.com for the full source code and example.

What to Look Out For

Learning Process

Design Patterns and design are a learning process and is better approached after you have a fairly good grasp of object oriented development and the language your are using, in this case PHP. You will find a lot of the patterns are easier recognized rather then easier to learn after you’ve had experience coding. You will more then likely discover that you may have already come across the same type of problem more then once and was solved with the same type of solution.

You may have not known at the time you might have very well implemented a particular design pattern. For example, one of the first patterns you may find easy to use and understand is the Command Pattern because it replaces the commonly found code of large switch statements and/or large sets of if statements in your code.

PHP Object Model

PHP 4

As reminder the PHP object model is incomplete when compared to other OO languages, this may affect your implementation of design pattern if it requires the use of an OO characteristic PHP does not have, such as interfaces, private variables and private methods.

PHP5

The enhancements and changes in the up coming PHP 5 include changes in the object model. Rumor has it there will be support for such things as Abstract classes, interfaces and namespace.

Over Use and Over Design

Now that you understand design and more specifically the use of design patterns can be beneficial look out that you don’t fall into one or more these traps.

Usually with design a modeling language and process is applied. Be careful not to over design making everything into a class and the use of a modeling language purely as documentation is something you should avoid as well.

Try to avoid using a design that looks or seems cool; try understanding the gain and loss of using that particular design. As well just because design patterns are good doesn’t mean you have to use it.

Try to avoid reusing the same pattern over and over again just because it is the one you know.

Because PHP is not 100% object oriented and that the fact HTML page are static pages you may want to consider using more of a hybrid approach where you use design patterns where it makes sense.For example, you have a website that produces content for web browsers, PDAs, cellular devices and WebTV. It would probably be in your best interest to use a MVC design pattern. Of course, there are other technology consideration that is out of this scope for this document such as XSL and Web Services. This Front view controller is maybe the only design pattern you use in this example and where the rest of your PHP code is coded procedurally.
Though I say this with discretion, most OO software designers would frown on what I just said and normally I would have to agree but as I mentioned before it really depends on what the software requirements are and the constraints you are faced with.


You should consider prototyping your design to help you visualize the final outcome and prove that the design indeed works.
Not the Only Tool

If I have not indirectly stressed this earlier, I would like to make my point now like everything else we use in software development / engineering. OO and Design Patterns have its place, keep an open mind and use the relevant skills and technologies that satisfy the software requirements. Experience with using Design Patterns and knowing when to use them is simply an addition to your vast skills.

Various Design Patreen are:-

The factory pattern

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.

Listing 1 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.
Listing 1. Factory1.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. This relationship is shown as UML in Figure 1.
Figure 1. The factory class and its related IUser interface and user class


The factory class and its related IUser interface and user class

If you run this code on the command line using the php interpreter, you get this result:

% php factory1.php
Jack
%

The test code asks the factory for a User object and prints the result of the getName method.

A variation of the factory pattern uses factory methods. These public static methods in the class construct objects of that type. This approach is useful when creating an object of this type is nontrivial. For example, suppose you need to first create the object and then set many attributes. This version of the factory pattern encapsulates that process in a single location so that the complex initialization code isn’t copied and pasted all over the code base.

Listing 2 shows an example of using factory methods.
Listing 2. Factory2.php

interface IUser
{
function getName();
}

class User implements IUser
{
public static function Load( $id )
{
return new User( $id );
}

public static function Create( )
{
return new User( null );
}

public function __construct( $id ) { }

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

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

This code is much simpler. It has only one interface, IUser, and one class called User that implements the interface. The User class has two static methods that create the object. This relationship is shown in UML in Figure 2.
Figure 2. The IUser interface and the user class with factory methods


The IUser interface and the user class with factory methods

Running the script on the command line yields the same result as the code in Listing 1, as shown here:

% php factory2.php
Jack
%

As stated, sometimes such patterns can seem like overkill in small situations. Nevertheless, it’s still good to learn solid coding forms like these for use in any size of project.

The singleton pattern

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 in Listing 3 shows a database connection singleton in PHP V5.
Listing 3. Singleton.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 UML for this code is shown in Figure 3.
Figure 3. The database connection singleton


The database connection singleton

The proof in the pudding is that the database handle returned by the handle method is the same between two calls. You can see this by running the code on the command line.

% php singleton.php
Handle = Object id #3
Handle = Object id #3
%

The two handles returned are the same object. If you use the database connection singleton across the application, you reuse the same handle everywhere.

You could use a global variable to store the database handle, but that approach only works for small applications. In larger applications, avoid globals, and go with objects and methods to get access to resources.

The observer pattern

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 in Listing 4 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.
Listing 4. Observer.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. This is shown in the UML in Figure 4.
Figure 4. The observable user list and the user list event logger


The observable user list and the user list event logger

If you run this on the command line, you see this output:

% php observer.php
'Jack' added to user list
%

The test code creates a UserList and adds the UserListLogger observer to it. Then the code adds a customer, and the UserListLogger is notified of that change.

It’s critical to realize that the UserList doesn’t know what the logger is going to do. There could be one or more listeners that do other things. For example, you may have an observer that sends a message to the new user, welcoming him to the system. The value of this approach is that the UserList is ignorant of all the objects depending on it; it focuses on its job of maintaining the user list and sending out messages when the list changes.

This pattern isn’t limited to objects in memory. It’s the underpinning of the database-driven message queuing systems used in larger applications.

The chain-of-command pattern

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. Listing 5 shows an example of this pattern.
Listing 5. Chain.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 shows in Figure 5.
Figure 5. The command chain and its related commands


The command chain and its related commands

If you run the script, which contains some test code, you see the following output:

% php chain.php
UserCommand handling 'addUser'
MailCommand handling 'mail'
%

The code first creates a CommandChain object and adds instances of the two command objects to it. It then runs two commands to see who responds to those commands. If the name of the command matches either UserCommand or MailCommand, the code falls through and nothing happens.

The chain-of-command pattern can be valuable in creating an extensible architecture for processing requests, which can be applied to many problems.

The strategy pattern

The last design pattern we will cover is the strategy pattern. In this 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, Listing 6 shows a user list class that provides a method for finding a set of users based on a plug-and-play set of strategies.
Listing 6. Strategy.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 UML for this code is shown in Figure 6.
Figure 6. The user list and the strategies for selecting users


The user list and the strategies for selecting users

The UserList class is a wrapper around an array of names. It implements a find method that takes one of several strategies for selecting a subset of those names. Those strategies are defined by the IStrategy interface, which has two implementations: One chooses users randomly and the other chooses all the names after a specified name. When you run the test code, you get the following output:

% php strategy.php
Array
(
[0] => Jack
[1] => Lori
[2] => Megan
)
Array
(
[0] => Andy
[1] => Megan
)
%

The test code runs the same user lists against two strategies and shows the results. In the first case, the strategy looks for any name that sorts after J, so you get Jack, Lori, and Megan. The second strategy picks names randomly and yields different results every time. In this case, the results are Andy and Megan.

The strategy pattern is great for complex data-management systems or data-processing systems that need a lot of flexibility in how data is filtered, searched, or processed.


for more information visit:- webexpert.wordpress.com

No comments: