Ten PHP Design Patterns

Design patterns can speed up the development process by providing tested, proven development paradigms. Effective software design requires considering issues that may not become visible until later in the implementation. Reusing design patterns helps to prevent subtle issues that can cause major problems, and it also improves code readability for coders and architects who are familiar with the patterns.

Design patterns were introduced to the software community in Design Patterns, by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides (colloquially known as the “gang of four”). The core concept behind design patterns, presented in the introduction, was simple. Over their years of developing software, Gamma et al found certain patterns of solid design emerging, just as architects designing houses and buildings can develop templates for where a bathroom should be located or how a kitchen should be configured. Having those templates, or design patterns, means they can design better buildings more quickly. The same applies to software.

Design patterns not only present useful ways for developing robust software faster but also provide a way of encapsulating large ideas in friendly terms. For example, you can say you’re writing a messaging system to provide for loose coupling, or you can say you’re writing an observer, which is the name of that pattern.

It’s difficult to demonstrate the value of patterns using small examples. They often look like overkill because they really come into play in large code bases. This article can’t show huge applications, so you need to think about ways to apply the principles of the example — and not necessarily this exact code — in your larger applications. That’s not to say that you shouldn’t use patterns in small applications. Most good applications start small and become big, so there is no reason not to start with solid coding practices like these.

Now that you have a sense of what design patterns are and why they’re useful, it’s time to jump into ten design patterns for PHP V5.

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

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:

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

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:

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

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.

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

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:

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

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:

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

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:

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.

The adapter pattern

Use the adapter pattern when you need to convert an object of one type to an object of another type. Typically, developers handle this process through a bunch of assignment code, as shown in Listing 1. The adapter pattern is a nice way to clean this type of code up and reuse all your assignment code in other places. Also, it hides the assignment code, which can simplify things quite a bit if you’re also doing some formatting along the way.
Listing 6. Using code to assign values between objects

This example uses an AddressDisplay object to display an address to a user. The AddressDisplay object has two parts: the type of address and a formatted address string.

After implementing the pattern (see Listing 6.1), the PHP script no longer needs to worry about exactly how the EmailAddress object is turned into the AddressDisplay object. That’s a good thing, especially if the AddressDisplay object changes or the rules that govern how an EmailAddress object is turned into an AddressDisplay object change. Remember, one of the main benefits of designing your code in a modular fashion is to take advantage of having to change as little code as possible if something in the business domain changes or you need to add a new feature to the software. Think about this even when you’re doing mundane tasks, such as assigning values from properties of one object to another.
Listing 6.1. Using the adapter pattern

Figure 6.2 shows a class diagram of the adapter pattern.

Figure 6.2. Class diagram of the adapter pattern
Class diagram of the adapter pattern

Alternate method

An alternate method of writing an adapter — and one that some prefer — is to implement an interface to adapt behavior, rather than extending an object. This is a very clean way of creating an adapter and doesn’t have the drawbacks of extending the object. One of the disadvantages of using the interface is that you need to add the implementation into the adapter class, as shown in Figure 6.2.
Figure 6.3. The adapter pattern (using an interface)
The adapter pattern (using an interface)

The iterator pattern

The iterator pattern provides a way to encapsulate looping through a collection or array of objects. It is particularly handy if you want to loop through different types of objects in the collection.

Look back at the e-mail and physical address example in Listing 6. Before adding an iterator pattern, if you’re looping through the person’s addresses, you might loop through the physical addresses and display them, then loop through the person’s e-mail addresses and display them, then loop through the person’s IM addresses and display those. That’s some messy looping!

Instead, by implementing an iterator, all you have to do is call while($itr->hasNext()) and deal with the next item $itr->next() returns. An example of one of the iterators is shown in Listing 7. An iterator is powerful because you can add new types of items through which to iterate, and you don’t have to change the code that loops through the items. In the Person example, for instance, you could add an array of IM addresses; simply by updating the iterator, you don’t have to change any code that loops through the addresses for display.
Listing 7. Using the iterator pattern to loop through objects

If the Person object is modified to return an implementation of the AddressIterator interface, the application code that uses the iterator doesn’t need to be modified if the implementation is extended to loop through additional objects. You can use a compound iterator that wraps the iterators that loop through each type of address like the one listed in Listing 7. An example of this is available (see Download).

Figure 7 shows a class diagram of the iterator pattern.
Figure 7. Class diagram of the iterator pattern
Class diagram of the iterator pattern

The decorator pattern

Consider the code sample in Listing 8. The purpose of this code is to add a bunch of features onto a car for a Build Your Own Car site. Each car model has more features and an associated cost. With only two models, it would be fairly trivial to add these features with if then statements. However, if a new model came along, you’d have to go back through the code and make sure the statements worked for the new model.
Listing 8. Using the decorator pattern to add features

Enter the decorator pattern, which allows you to add this functionality onto the AutomobileModel in a nice, clean class. Each class remains concerned only about its price and options and how they’re added to the base model.

Figure 8 shows a class diagram for the decorator pattern.
Figure 8. Class diagram of the decorator pattern
Class diagram of the decorator pattern
An advantage of the decorator pattern is that you can easily tack on more than one decorator to the base at a time.

If you’ve done much work with stream objects, you have used a decorator. Most stream constructs, such as an output stream, are decorators that take a base input stream, then decorate it by adding additional functionality — like one that inputs streams from files, one that inputs streams from buffers, etc.

The delegate pattern

The delegate pattern provides a way of delegating behavior based on different criteria. Consider the code in Listing 9. This code contains several conditions. Based on the condition, the code selects the appropriate type of object to handle the request.
Listing 9. Using conditional statements to route shipping requests

With a delegate pattern, an object internalizes this routing process by setting an internal reference to the appropriate object when a method is called, like useRail() in Listing 10. This is especially handy if the criteria change for handling various packages or if a new type of shipping becomes available.
Listing 10. Using the delegate pattern to route shipping requests

The delegate provides the advantage that behavior can change dynamically by calling the useRail() or useTruck() method to switch which class handles the work.

Figure 10 shows a class diagram of the delegate pattern.
Figure 10. Class diagram of the delegate pattern
Class diagram of the delegate pattern

The state pattern

The state pattern is a similar to the command pattern, but the intent is quite different. Consider the code below.
Listing 11. Using code to build a robot

In this listing, the PHP code represents the operating system for a powerful robot that turns into a car. The robot can power up, power down, turn into a robot when it’s a vehicle, and turn into a vehicle when it’s a robot. The code is OK now, but you see that it can become complex if any of the rules change or if another state comes into the picture.

Now look at Listing 12, which has the same logic for handling the robot’s states, but this time puts the logic into the state pattern. The code in Listing 12 does the same thing as the original code, but the logic for handling states has been put into one object for each state. To illustrate the advantages of using the design pattern, imagine that after a while, these robots have discovered that they shouldn’t power down while being in robot mode. In fact, if they power down, they must change to vehicle mode first. If they’re already in vehicle mode, the robot just powers down. With the state pattern, the changes are pretty trivial.
Listing 12. Using the state pattern to handle the robot’s state

Listing 13. Small changes to one of the state objects

Something that doesn’t appear obvious when looking at Figure 9 is that each object in the state pattern has a reference to the context object (the robot), so each object can advance the state onto the appropriate one.
Figure 14. Class diagram of the state pattern
Class diagram of the state pattern


Using design patterns in your PHP code is one way to make your code more readable and maintainable. By using established patterns, you benefit from common design constructs that allow other developers on a team to understand your code’s purpose. It also allows you to benefit from the work done by other designers, so you don’t have to learn the hard lessons of design ideas that don’t work out. Taken from IBM developerworks

Please post your experiences with these design patterns. If you like this post kindly subscribe to our RSS for free updates and articles delivered to you.

0 I like it
0 I don't like it