The Whens and Whys for PHP Design Patterns

The Whens and Whys for PHP Design Patterns

Tutorial Details
    • Difficulty: Beginner
    • Completion Time: 1 Hour

There are plenty of articles that explain what design patterns are, and how to implement them; the web doesn’t need yet another one of those articles! Instead, in this article, we will more discuss the when and why, rather than the which and how.

I’ll present different situations and use-cases for patterns, and will also provide short definitions to help those of you who are not so familiar with these specific patterns. Let’s get started.

Republished Tutorial

Every few weeks, we revisit some of our reader's favorite posts from throughout the history of the site. This tutorial was first published in October, 2012.

This article covers some of the various Agile Design Patterns, documented in Robert C. Martin’s books. These patterns are modern adaptations of the original design patterns defined and documented by The Gang of Four in 1994. Martin’s patterns present a much more recent take on the GoF’s patterns, and they work better with modern programming techniques and problems. In fact, about 15% of the original patterns were replaced with newer patterns, and the remaining patterns were slightly modernized.


Let’s Start by Creating Some Objects

Use a Factory Pattern

The factory pattern was invented to help programmers organize the information related to object creation. Objects sometimes have lot of constructor parameters; other times, they must be populated with default information immediately after their creation. These objects should be created in factories, keeping all the information regarding their creation and initialization contained within a single place.

When Use a Factory Pattern when you find yourself writing code to gather information necessary to create objects.

Why: Factories help to contain the logic of object creation in a single place. They can also break dependencies to facilitate loose coupling and dependency injection to allow for better testing.


Finding the Data We Need

There are two frequently used patterns to retrieve information from a persistence layer or external data source.

The Gateway Pattern

This pattern defines a communication channel between a persistence solution and the business logic. For simpler applications, it can retrieve or recreate whole objects by itself, but object creation is the responsibility of factories in most complex applications. Gateways simply retrieve and persist raw data.

When: When you need to retrieve or persist information.

Why: It offers a simple public interface for complicated persistence operations. It also encapsulates persistence knowledge and decouples business logic from persistence logic.

In fact, the gateway pattern is just a particular implementation of another design pattern that we’ll discuss shortly: the adapter pattern.

Go with the Proxy

There are times when you can not (or do not want to) expose the knowledge of the persistence layer to your business classes. The proxy pattern is a good way to fool your business classes into thinking they are using already existing objects.

When: You have to retrieve information from a persistence layer or external source, but don’t want your business logic to know this.

Why: To offer a non-intrusive approach to creating objects behind the scenes. It also opens the possibility to retrieve these object on the fly, lazily, and from different sources.

A proxy effectively implements the same interface as a real object and mimics its functionality. The business logic simply uses it as if it were a real object, but in fact, the proxy creates the object if one doesn’t exist.

The active object pattern also played a part in early multi-tasking systems.

Okay, okay. That great and all, but how can we find the objects that we need to create?

Ask a Repository

The repository pattern is very useful for implementing search methods and mini-query languages. It takes these queries and uses a gateway to obtain the data for a factory to produce the objects you need.

The repository pattern is different from the other patterns; it exists as part of Domain Driven Design (DDD), and is not included as part of Robert C. Martin’s book.

When: You need to create multiple objects based on search criteria, or when you need to save multiple objects to the persistence layer.

Why: To let clients that need specific objects to work with a common and well isolated query and persistence language. It removes even more creation-related code from the business logic.

But what if the repository cannot find the objects? One option would be to return a NULL value, but doing so has two side effects:

  • It throws a refused bequest if you try to call a method on such an object.
  • It forces you to include numerous null checks (if(is_null($param)) return;) in your code.

A better approach is to return a null object.

The Null Object Pattern

A null object implements the same interface of your other objects, but the object’s members return a neutral value. For example, a method that returns a string would return an empty string; another member returning a numeric value would return zero. This forces you to implement methods that do not return meaningful data, but you can use these objects without worrying about refused bequest or littering your code with null checks.

When: You frequently check for null or you have refused bequests.

Why: It can add clarity to your code and forces you to think more about the behavior of your objects.

It’s not unusual to call many methods on an object before it can do its job. There are situations when you must prepare an object after its creation before you can truly use it. This leads to code duplication when creating those objects in different places.

You Need the Command Pattern

When: When you have to perform many operations to prepare objects for use.

Why: To move complexity from the consuming code to the creating code.

This sounds good, doesn’t it? In fact, it is quite useful in many situations. The command pattern is widely used for implementing transactions. If you add a simple undo() method to a command object, it can track all the undo transactions it performed and reverse them if necessary.

So now you have ten (or more) command objects, and you want them running concurrently. You can gather them into an active object.

The Active Object

The simple and interesting active object has only one responsibility: keep a list of command objects and run them.

When: Several similar objects have to execute with a single command.

Why: It forces clients to perform a single task and affect multiple objects.

An active object removes each command from its list after the command’s execution; meaning, you can execute the command only once. Some real world examples of an active object are:

Design patterns are here to solve problems.

  • Shopping Cart – Executing a buy() command on each product removes them from the cart.
  • Financial Transactions – Grouping transactions into a single list and executing them with a simple call to the list manager’s active object would remove the transactions from the queue.

The active object pattern also played a part in early multi-tasking systems. Each object inside an active object would keep a reference to the active object. They would execute a portion of their jobs and then put themselves back into the queue. Even in today’s systems, you can use an active object to let other objects work while you wait for a response from another application.


Reusability

I am positive that you’ve heard the big promise of object oriented programming: code reuse. Early adopters of OOP envisioned using universal libraries and classes in millions of different projects. Well, it never happened.

Make Some Template Methods Instead

This pattern allows for the partial reuse of code. It’s practical with multiple algorithms which only slightly differ from one another.

When: Eliminate duplication in a simple way.

Why: There is duplication and flexibility is not a problem.

But flexibility is nice. What if I really need it?

It’s Time For a Strategy

When: Flexibility and reusability is more important than simplicity.

Why: Use it to implement big, interchangeable chunks of complicated logic, while keeping a common algorithm signature.

For example, you can create a generic Calculator and then use different ComputationStrategy objects to perform the calculations. This is a moderately used pattern, and it is most powerful when you have to define many conditional behaviors.


Discover-ability

As projects grow, it becomes increasingly difficult for external users to access our application. That’s one reason to offer a well-defined entry point to the application or module in question. Other such reasons may include the desire to conceal the module’s internal workings and structure.

Present a Facade

A facade is essentially an API – a nice and client-facing interface. When a client calls one of these nice methods, the facade delegates a series of calls to the classes it hides in order to provide the client with the required information or desired result.

When: To simplify your API or intentionally conceal inner business logic.

Why: You can control the API and the real implementations and logic independently.

Control is good, and many times you need to perform a task when something changes. Users have to be notified, red LEDs have to blink, an alarm has to sound… you get the idea.

The popular Laravel framework makes excellent use of the Facade Pattern.

Subscribe to an Observer

A null object implements the same interface as your other objects.

The observer pattern offers an easy way to monitor objects and take actions when conditions change. There are two types of observer implementations:

  • Polling – Objects accept subscribers. Subscribers observe the object and are notified on specific events. Subscribers ask the observed objects for more information in order to take an action.
  • Push – Like the polling method, objects accept subscribers, and subscribers are notified when an event occurs. But when a notification happens, the observer also receives a hint that the observer can act on.

When: To provide a notification system inside your business logic or to the outside world.

Why: The pattern offers a way to communicate events to any number of different objects.

Use cases for this pattern are email notifications, logging daemons, or messaging systems. Of course, in real life, there are countless other ways to use it.

Coordinate The Effects

The observer pattern can be extended with a mediator pattern. This pattern takes two objects as parameters. The mediator subscribes itself to the first parameter, and when a change happens to the observed object, the mediator decides what to do on the second object.

When: The affected objects can not know about the observed objects.

Why: To offer a hidden mechanism of affecting other objects in the system when one object changes.


Singularity

Sometimes, you need special objects that are unique in your application, and you want to ensure that all consumers can see any change made to these objects. You also want to prevent creating multiple instances of such objects for certain reasons, like long initialization time or problems with concurrent actions to some third party libraries.

Use a Singleton

A singleton is an object having a private constructor and a public getInstance() method. This method ensures that only one instance of the object exists.

When: You need to achieve singularity and want a cross platform, lazily evaluated solution which also offers the possibility of creation through derivation.

Why: To offer a single point of access when needed.

Or Write a Monostate Object

Another approach to singularity is the monostate design pattern. This solution uses a trick offered by object oriented programming languages. It has dynamic public methods which get or set the values of static private variables. This, in turn, ensures that all instances of such classes share the same values.

When: Transparency, derivabitility, and polymorphism are preferred together with singularity.

Why: To hide from the users/clients the fact that the object offers singularity.

Pay special attention to singularity. It pollutes the global namespace and, in most cases, can be replaced with something better suited for that particular situation.


Controlling Different Objects

The repository pattern is quite useful for implementing search methods…

So you have a switch and a light. The switch can turn the light on and off, but, now, you’ve purchased a fan and want to use your old switch with it. That’s easy to accomplish in the physical world; take the switch, connect the wires, and viola.

Unfortunately, it’s not so easy in the programming world. You have a Switch class and a Light class. If your Switch uses the Light, how could it use the Fan?

Easy! Copy and paste the Switch, and change it to use the Fan. But that’s code duplication; it’s the equivalent of buying another switch for the fan. You could extend Switch to FanSwitch, and use that object instead. But what if you want to use a Button or RemoteControl, instead of a Switch?

The Abstract Server Pattern

This is the simplest pattern ever invented. It only uses an interface. That’s it, but there are several different implementations.

When: You need to connect objects and maintain flexibility.

Why: Because it is the simplest way to achieve flexibility, while respecting both the dependency inversion principle and the open close principle.

PHP is dynamically typed. This means that you can omit interfaces and use different objects in the same context – risking a refused bequest. However, PHP also allows for the definition of interfaces, and I recommend you use this great functionality to provide clarity to the intent of your source code.

But you already have a bunch of classes you want to talk to? Yes, of course. There are many libraries, third-party APIs, and other modules that one has to talk to, but this does not mean that our business logic has to know the details of such things.

Plug in an Adapter

The adapter pattern simply creates a correspondence between the business logic and something else. We have already seen such a pattern in action: the gateway pattern.

When: You need to create a connection with a pre-existing and potentially changing module, library, or API.

Why: To allow your business logic to rely only on the public methods the adapter offers, and permit changing the other side of the adapter easily.

If either of the above patterns don’t fit with your situation, then you could use…

The Bridge Pattern

This is a very complicated pattern. I personally do not like it because it is usually easier to take a different approach. But for those special cases, when other solutions fail, you can consider the bridge pattern.

When: The adapter pattern is not enough, and you change classes on both sides of the pipe.

Why: To offer increased flexibility at the cost of significant complexity.


The Composite Pattern

Consider that you have a script with similar commands, and you want make a single call to run them. Wait! Didn’t we already see something like this earlier? The active object pattern?

Yes, yes we did. But this one is a bit different. It’s the composite pattern, and like the active object pattern, it keeps a list of objects. But calling a method on a composite object calls the same method on all of its objects without removing them from the list. The clients calling a method are thinking they are talking to a single object of that particular type, but in fact, their actions are applied to many, many objects of the same type.

When: You have to apply an action to several similar objects.

Why: To reduce duplication and simplify how similar objects are called.

Here’s an example: you have an application that is capable of creating and placing Orders. Assume you have three orders: $order1, $order2 and $order3. You could call place() on each of them, or you could contain those orders in a $compositeOrder object, and call its place() method. This, in turn, calls the place() method on all the contained Order objects.


The State Pattern

Gateways only retrieve and persist raw data.

A finite state machine (FSM) is a model that has a finite number of discreet states. Implementing a FSM can be difficult, and the easiest way to do so involves the trusty switch statement. Each case statement represents a current state in the machine, and it knows how to activate the next state.

But we all know that switch...case statements are less desirable because they produce an unwanted high fan-out on our objects. So forget the switch...case statement, and instead consider the state pattern. The state pattern is composed of several objects: an object to coordinate things, an interface representing an abstract state, and then several implementations – one for each state. Each state knows which state comes after it, and the state can notify the coordinating object to set its new state to the next in line.

When: FSM-like logic is required to be implemented.

Why: To eliminate the problems of a switch...case statement, and to better encapsulate the meaning of each individual state.

A food dispenser could have a main class that has a reference to a state class. Possible state classes might be something like: WaitingForCoin, InsertedCoin, SelectedProduct, WaitingForConfirmation, DeliveringProduct, ReturningChange. Each state performs its job and creates the next state object to send to the coordinator class.


Decorate with the Decorator Pattern

There are times when you deploy classes or modules throughout an application, and you can’t modify them without radically affecting the system. But, at the same time, you need to add new functionality that your users require.

The decorator pattern can aid in these situations. It is very simple: take existing functionality and add to it. This is accomplished by extending the original class and providing new functionality at run-time. Old clients continue to use the new object as they would an old one, and new clients will use both the old and new functionality.

When: You can’t change old classes, but you have to implement new behavior or state.

Why: It offers an unintrusive way of adding new functionality.

A simple example is printing data. You print some information to the user as plain text, but you also want to provide the ability to print in HTML. The decorator pattern is one such solution that lets you keep both functionality.

Or, Accept a Visitor

If your problem of extending functionality is different – say, you have a complex tree-like structure of objects, and you want to add functionality to many nodes at once – a simple iteration is not possible, but a visitor might be a viable solution. The downside, however, is that a visitor pattern implementation requires modification to the old class if it wasn’t designed to accept a visitor.

When: A decorator is not appropriate and some extra complexity is acceptable.

Why: To allow and organized approach to defining functionality for several objects but at the price of higher complexity.


Conclusion

Use design patterns to solve your problems, but only if they fit.

Design patterns help solve problems. As an implementation recommendation, never name your classes after the patterns. Instead, find the right names for the right abstractions. This helps you to better discern when you really need a pattern as opposed to just implementing one because you can.

Some may say that if you don’t name your class with the pattern’s name in it, then other developers will have a difficult time understanding your code. If it’s hard to recognize a pattern, then the problem is in the pattern’s implementation.

Use design patterns to solve your problems, but only if they fit. Do not abuse them. You’ll find that a more simple solution befits a little problem; whereas, you’ll discover that you need a pattern only after you implement a few other solutions.

If you’re new to design patterns, I hope that this article has given you some idea as to how patterns can be helpful in your applications. Thanks for reading!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.facebook.com/profile.php?id=100000994324447 Allan Jikamu

    I hope you added some sample code for each design pattern

    • Md Rashidul Islam

      Yep, Example is better than precept :| A picture (sample code) worth than a thousand words

      • Christopher Moore

        Def. I concur.

      • Cris Mcl

        I concur as well. I def. wish this had code…

      • http://twitter.com/leggettsteven Steven Leggett

        yes, talking about programming without code examples is the same as talking about art without images.

      • http://www.facebook.com/robin.johansson.900 Robin Johansson

        I agree lads, it would be quite usable with a code example. Like a sir.

      • Fratyr

        Bring us some examples pls

      • http://twitter.com/jirffey Jirffey Gabuya

        spot on, mate!

      • Baba Alimou Barry

        yeah great but pliz some examples. thank you!!

      • mem

        I don’t agree with any of those assumptions. – Abstraction should not only be a OOP concept.

    • Maciej Kołek

      Yeah, there should be a code examples.

    • Patkos Csaba
      Author

      Hmm. It is interesting that so many of you want code… There are so many examples of design patterns all over the web, why do you think that another would be more interesting than this article? As I wrote in the first paragraph I intended this article to explain why and when to use a design pattern and not how to implement one.

      • Tim

        While that may have been your intent, you need to understand that not everyone learns the same way. Having visual representation helps to illustrate your points. Pictures are worth a thousand words. We’re not asking for code because we’re too lazy to look it up ourselves. We’re asking for code because we want specific examples that pertain to this article. Leaving people to their own devices to look things up leaves room for confusion and miscommunication. As someone who is trying to educate you want to minimize confusion and miscommunication.

      • Patkos Csaba
        Author

        So, how would a UML schema or a random code help you better understand when and why to use a design pattern. There is a comment comparing this to talking about art… So, should one talking about Mona Lisa teach you hot to mix colors and use a paintbrush?

      • http://www.facebook.com/gottier Brian Gottier

        The problem for me is that I don’t want to have to go anywhere else to get code examples that you could have provided. I just come here to relax, read, and perhaps learn. The comparison to art is not a good one. Rather, I’d compare this article to a programmers guide that has no code samples. Would you buy a book like that? Of course not! I know this is free, and thanks for that. I’m done complaining.

      • Maciej Kołek

        I would not change a word in your answer, Brian. Thanks Patkos for your post, but there is no point to look for code examples while reading this article on iPad, travelling to work or sth.

      • tom

        no they should show a picture of the mona lisa

      • http://twitter.com/tamachan87 Richard Simms

        Imagine teaching English as a foreign language to someone without using English. Try explaining sentence/paragraph patterns or word structure without using any examples.

      • Phutureproof

        In all fairness all the other articles you mention already provide code samples and reasons for use, you have done nothing here. I must say this is a very weak article. Don’t take me the wrong way I appreciate your effort, it just turned out crap.

    • Lamis

      I wish there was a code too….just I enjoy reading but when I cant see a code it doesnt feel right

    • HongKilDong

      Some sort of php for some of described here patterns https://speakerdeck.com/ezimuel/design-patterns-bootcamp

    • http://twitter.com/apathetic012 ‘David Cyrus

      I thought I was the only one looking for sample codes.

  • Daniel Heath

    I doubt there is a need for code examples, especially when the point of the article was stated. There are millions of other articles showing code examples of how to implement design patterns, even in php. I found this article very valuable in explaining something that only few others have done, and would be a valuable resource for anyone getting into design patterns.

    • Fabricio Sodano

      Perhaps at least a link to an example of each pattern?

  • shamim

    Super post and thanks to share…

  • hasan

    That is really a fantastic blog and thanks to share…

  • chumkiu81

    Great article and great job. Thank you… however It’s like to explain art without pictures. Remember it in the next post :-)

  • vnk

    There are some misconceptions on the subject of design patterns. And most of them derive from the fact that people simply don’t understand what a design pattern actually is.

    First of all, design patterns are *not* solutions. They are the sum of both the problem and the solution. You don’t “apply a pattern”: you reach a situation or problem, recognize it as part of a pattern and apply the pattern’s solution.

    And second, design patterns are *not* solutions. Again. They offer a *generic* idea or approach on how to manage the problem, but they do not focus on a particular code or implementation of the solution.

    (There’s also a third part to design patterns -besides problem and solution- which is environment and which people so often forget that it’s not even funny anymore)

    • expediteA

      I’ve re-read this article over and over and still haven’t a clue what it’s talking about. If it’s about spotting patterns and altering your code in some way then having a before and after set of code would really help!

  • orange county web designer

    Very interesting article. Thanks for sharing.

  • JH

    no code examples? is this article for real or are we being trolled?

  • Uncle Fred

    Not bad at all. Want code examples go here http://sourcemaking.com/design_patterns

  • http://stvplus.com/ viperfx

    This is interesting, but please add code samples! It is difficult to grasp the concept without some examples. Then you can update this title to be Whens, Whys and How :)

  • Kevin

    I started writing example/reference PHP design patterns a while ago and updated them recently. Someone may find them useful. http://goo.gl/evTVl

  • waveydavey

    I disagree with some of the above comments – this article seems to me to be explicitly about the why and when. Personally, sometimes the code is a distraction – I can read a hundred examples of these patters, and still not graps why we are using them.

  • pissedOffElmo

    This reads like the contents to an article that wasn’t actually written. Did you write this for people to read or for Google / SEO puposes?

  • Goran

    OMG guys… why can’t you accept that this article is targeted for people already knowing something about patterns. If you want to learn what patterns are – look farther. For others, who already know something about patterns, but just want refreshment, just search wikipedia – ultimate pattern reference.

    Thanks Patkos and keep up the good work

    • MPinteractiv

      If you already know about patterns you dont need that article , since you know when to use them. This article is not very interesting to say the least.

  • http://ursulahays.wordpress.com/2012/11/09/use-some-free-open-source-tools-to-successfully-develop-net-program-applications/ AuroraHogan

    I like the way you create. Your design is very sleek and I appreciate studying your content. I¡¯m advancing to the dental professional but will be returning later

  • http://www.facebook.com/michael.graf Michael Graf

    my two cents, how does this apply to PHP? if you just were discussing design patterns, great, good job…. but as the article name implies, you’re relating design patterns and how/when to use with PHP. I’ll have to agree with many other commenters that without providing code examples, this article, which merited a good grade for sure, loses a full grade due to misdirection, or perhaps it’s just “Incomplete” Thanks for taking the time to put it together, now please put together a version II that matches your title ;)

  • Mr. soktaP abasC

    Mr. @google-dfa06b20297d7fddd2fa5c4a1d4990dd:disqus
    some examples please ?

  • http://www.amazines.com/article_detail.cfm/5235731?articleid=5235731 Igor Andrews

    These objects should be created in factories, keeping all the
    information regarding their creation and initialization contained within
    a single place.

  • Pedro Suarez.

    Hi Mr. Patkos Csaba. I see you have a premium course about this very same topic but in audio/visual format. I would like to pay a one-month subscription but I’m still not sure how that course differs from this post. Are there sample files to download for each video? Many thanks.

    • Patkos Csaba
      Author

      In the course each design pattern is implemented step-by-step. Each lesson is for one design pattern. Yes, there is code, a lot of it.

  • sumanadasa

    nice one

  • deb0rian

    Now would be still nice if you attach a few code examples to each of those and that would be a brilliant design patterns tut

  • http://www.facebook.com/jesus.bejarano.948 Jesus Bejarano

    Is just coincidence that i just start reading O’Reilley.Learn.PHP.Design.Patterns the same day that am reading this article?

    • Patkos Csaba
      Author

      Yes, it is :)

  • http://cubicleninjas.com/ Tyler Etters

    I love how this is presented: if ($you_need_this) { $then = $do_this }; :)

  • jesperseurin

    Examples please. Though its still a great post!

  • Guest

    Republished Tutorial

    Every few weeks, we revisit some of our reader’s favorite posts from throughout the history of the site. This tutorial was first published in October, 2012.

    huh I don’t c this one as favorite after reading comments below. NetTuts, I rely on u but unfortunately u’r judge very poor this time

  • Pham Ngoc Sinh

    Yep, I need some more example with code or example frame is using patterns

  • http://twitter.com/jeff_pz_cr Jeffrey Briceno

    A Republished Tutorial and still no sample code.
    It’s a shame because it is a topic that many who want to improve our skills would have helped a lot more with sample code, and not to mention those who do not have English as the native language

  • http://www.facebook.com/profile.php?id=12406303 Robert Kyanberu

    Coming to this article as someone unfamiliar with design patterns I’m confused why it is marked as ‘beginner’. The entire article is written as though a definition of the pattern is enough to instill complete knowledge of when/where/why/how to use the pattern, or how the pattern should look/operate.

    As others have mentioned, there are no practical examples and the author has provided no tangible explanation for why, with the exception that these examples exist in multitude in the articles and instructions of other people. That sounds like a great testimony then to read THEIR articles instead.

    Ultimately; I’ve read this… and feel I haven’t gained anything from it. I do not feel comfortable in my knowledge of design patterns having read this article. I’m left with more questions than answers based on the way that take in and digest information. And finally, I’m left completely perplexed as to why something so abstract is labeled specific to PHP. This goes back to code though…

  • Daikaads

    PHP Design Pattern is most welcomed by the clients since it makes the website look good. I have a doubt.
    Can we use this in Ecommerce Website Design?

  • http://twitter.com/8bitmore 8bitmore

    This is retarded. What worth is any of this without code?

  • http://twitter.com/LeibowitzCandle Leibowitz’s Candle

    Badly written articles like this are why I stopped coming here and now why I’m unsubscribing from your email list.

  • rjgamer

    Amen, great post!

  • http://www.facebook.com/people/Maksym-Minenko/100002815636882 Maksym Minenko

    It’s just ridiculous without examples, LOL.

    • garcia_IS_shill

      I know it feels like reading a book on philosophy of PHP design patterns rather than the normal Nettuts style meaty wholesomeness.

      • mem

        And behind this reasoning is something weird: “normal” is best then “book on philosophy of PHP” – why is this? We will never know.