Understanding the Factory Method Design Pattern

Building things can be tough when you can’t anticipate what type of objects you’ll need to create or how to create them. Take for example a factory which manufactures a large number of products. Each product can be made up of any number of components in their inventory. The workers know what’s in the inventory but don’t necessarily know beforehand what kind of products they will be making. The Factory Method design pattern can be applied to similar situations in programming where you have a set of component classes but won’t know exactly which one you’ll need to instantiate until runtime. In this article I’ll show you how the Factory Method pattern can be used to create different objects, without knowing beforehand what sort of objects it needs to create or how the object is created.

The Factory Method

The Factory Method pattern is a design pattern used to define a runtime interface for creating an object. It’s called a factory because it creates various types of objects without necessarily knowing what kind of object it creates or how to create it.

Here’s an example of how the Factory Pattern works. Assume you have a ProductFactory class which creates a new type of product:

<?php
class ProductFactory
{
    public static function build($type) {
        // assumes the use of an autoloader
        $product = "Product_" . $type;
        if (class_exists($product)) {
            return new $product();
        }
        else {
            throw new Exception("Invalid product type given.");
        }
    } 
}

By defining build() as a factory method, you now have an interface through which you can create different products on the fly.

<?php
// build a new Product_Computer type
$myComputer = ProductFactory::build("Computer");
// build a new Product_Tablet type
$myTablet = ProductFactory::build("Tablet");

The Factory Method pattern is generally used in the following situations:

  • A class cannot anticipate the type of objects it needs to create beforehand.
  • A class requires its subclasses to specify the objects it creates.
  • You want to localize the logic to instantiate a complex object.

The Factory Method pattern is useful when you need to abstract the creation of an object away from its actual implementation. Let’s say the factory will be building a “MobileDevice” product type. A mobile device could be made up of any number of components, some of which can and will change later, depending on advances in technology.

<?php
class Product_MobileDevice
{
    private $components;

    public function __construct() {
        // this device uses a 7" LCD
        $this->addComponent(ProductFactory::build("LCD", 7));
        // and features an 1GHz ARM processor  
        $this->addComponent(ProductFactory::build("CPU_ARM", 1));
    }
...
}

// build a new Product_MobileDevice type
$myDevice = ProductFactory::build("MobileDevice");
$myDevice->use();

The logic to create a Product_MobileDevice object has been encapsulated into the class itself. If you want to exchange the 7″ LCD screen with a 10″ Touch_Screen later, you can make the isolated change in the MobileDevice class without affecting the rest of your application.

Factories Using Other Factories

Because the instantiation of an object is encapsulated, it could also use factories itself. To further expand on the idea of abstract object creation, let’s use a non-software engineering analogy. An automotive factory manufactures vehicles of a specific make, model, and color, but it may not produce all the necessary parts itself that are required to build the vehicle. In other words, it delegates the production of these parts out to other factories which it then uses to build new vehicles.

Under this scenario, a vehicle factory might look like this:

<?php
class VehicleFactory
{
    public static function build($make, $model, $color) {
        $vehicle = new Vehicle;

        // vehicle needs a chassis which is produced by another factory
        $vehicle->addPart(VehicleChassisFactory::build($make, $model));
        // needs an engine built by someone else
        $vehicle->addPart(VehicleEngineFactory::build($make, $model));
        // it needs a bodykit made by another factory
        $vehicle->addPart(VehicleBodyFactory::build($make, $model, $color));
        // and interiors are made by... you guessed it, someone else 
        $vehicle->addPart(VehicleInteriorFactory::build($make, $model, $color));

        // ...add more parts

        return $vehicle;
    }
}

// build a new white VW Amarok
$myCar = VehicleFactory::build("Volkswagon", "Amarok", "white");
$myCar->drive();

Voilà! A shiny new car. The VehicleFactory class produces a vehicle of a specified make, model and color, but acquired the various parts produced by other factory methods.

Summary

In this article you’ve learned how the Factory Method pattern can be used to localize the construction of different objects and to allow you to create objects without knowing specifically what type you’ll need beforehand. You also saw also factory methods can use other factory methods to create objects objects and define what objects they produce.

Image via yuminglin / Shutterstock

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Bryce

    I’m getting ready to work on a project next week that this will work perfect for. I do have one question though, is there a standard way to manage the inclusion of class files? Am I required to just include every possible class file? Or can I somehow integrate a require_once statement prior to the factory class checking on the object.

    • http://www.madesignuk.com Matt

      @bryce you can avoid having to manually include each class by using the __autoload() function. Creating this function at the top of each page (such as in a configuration file) will make sure the correct class is included only when you need it – http://php.net/manual/en/language.oop5.autoload.php

    • Dusan

      Check autoloading in PHP.

    • http://devcu.be Craig

      Check out PSR-0, it is a standard that is being used for autoloading classes based on file structure. If you have 5.3 the standard works for namespacing too. This will allow other people to use your code, and for you to easily include other libraries in your own.

  • Dusan

    Hi, just to let you know (readers and author) that this is not The Factory Method.
    Generally this is purely written article. Seems as explanation of the php code on Wikipedia in article on The Factory Method. That code is wrong as well.
    Both are Simple Factory idiom (you could find it regarded as that around) examples, not design pattern (but could be, pattern).

    In general poorly written article. I hope that you will rise the bar for the quality of the content. I like the subject, but realisation is poor.

    Regards,
    Dusan
    PS On Wikipedia Java example is correct; check it out.

    • Mike

      @Dusan What pattern is this then?

      • Dusan

        This is Simple Factory, as I said it in my first post.

    • http://matthewturland.com Matthew Turland

      @Dusan This is consistent with every other factory example I’ve seen in PHP, including the one on the Wikipedia page for the Factory method pattern. Additionally, the Wikipedia page for the book “Design Patterns: Elements of Reusable Object-Oriented Software” states that the Factory method pattern “creates objects without specifying the exact class to create.” Both examples on the Wikipedia page for the Factory method pattern and the ones shown in this article by its author fulfill this requirement and, in my opinion, both are equally valid examples of this pattern.

      • George Palmer

        Dusan is right, this is a simple factory. I found this nice set of UML diagrams showing the different factory patterns – http://stackoverflow.com/questions/4209791/design-patterns-abstract-factory-vs-factory-method

      • Dusan

        Good thing when it comes to patterns is that they are more about idea, not concrete implementation/coding. Once you get idea implementation is easy. The point is that checking concepts in other languages is recommended, because PHP examples in this particular case are bad all over the web (at least what you saw, and me as well).
        If you check this article ( http://www.oodesign.com/factory-method-pattern.html ) you will see UML diagram which says, by itself, that this example is wrong.
        Don’t get me wrong, pattern (idiom) shown in article is useful and it will help you decouple your app to some extend. I am implying that this is just not The Factory Method.
        PHP community is looked down on in software engineering world and articles like this one backs that point of view. This is supposed to be base/root knowledge and we are not getting it properly.
        That’s all and just my opinion.

        • Dusan

          In GoF book as well The Factory Method is first explained with abstract class with abstract factory method left to concrete subclasses to implement it. That one IMO should be explained if part of the story was to be explained.
          My whole point is that PHP Master (as Sitepoint’s website and with such a bombastic name) should rise the bar when it comes to quality of the articles. Those should be for advanced users and thorough in my opinion. Sitepoint has more then enough articles and books for beginners/intermediate developers.
          I like Sitepoint (have a whole lot of SP books and few Kits and SP was holding my hand for years) and that is why I’ve spent a lot of time commenting this and leaving feedback on PHP Master Facebook page on this article and one about Git trying to give it back (maybe not that skillful and moderate at times, but will get better I promise :)).

          • http://zaemis.blogspot.com Timothy Boronczyk

            @Dusan

            I’m sorry you find the quality of PHPMaster’s content lacking, but may I ask if your criticism is for this article in particular or the site as a whole? You noted that you’ve learned a lot from SitePoint and its products, and as managing editor I try to balance the article submissions so others can do so as well… I try to have something for everyone regardless of their current skill level.

            For novices, I’ve had some excellent beginner-level articles submitted by Iain Tench (Variables in PHP), J Armando Jeronymo (Introduction to PHP Arrays), and Amanda Steigerwalt (Using the Ternary Operator). Such articles are important because many developers don’t come to PHP with a background in Computer Science as those working with other languages might. Often times they’re self-taught, having been thrown into it at work. I now have a degree and hold a Zend Certification, but 10 years ago I entered the PHP world like so many others, as if it were the next step from HTML. I want to ensure the next generation of such programmers have the opportunity to gain a solid foundation in an accessible manner as they start out on their own journey to PHP masterhood.

            Some great intermediate articles you might find more suitable to your own skill level is Lukas White’s Targeted Geolocation with Geonames, Sean Hudgston’s Introduction to Git, and Dustin Runnell’s Understanding OAuth – Tweeting from Scratch. These articles assume you already know the basics of PHP programming and start to address more specific tasks and demonstrate underlying concepts of the tools and libraries many of us use on a daily basis.

            PHPMaster has only been live for less than six months. Over time you’ll continue to see new beginner and intermediate articles, but also advanced ones. I’m especially excited about tomorrow’s article PHP’s Quest for Performance: From C to hhvm by Matt Turland, and next month’s articles ClamAV as a Validation Filter in Zend Framework by Matthew Setter and REST: Do More than Spell It by David Shirey. I hope you’ll stick around for them!

            I also want to invite you to write some advanced articles for PHP Master if you have the time available. I am always looking for competent authors passionate about sharing their knowledge and experiences. It’s an excellent and constructive way to “pay it forward” and give back to the community that helped you grow in your own journey as a programmer. Feel free to send me an email (listed on the Write for PHPMaster page) and we can brainstorm some advanced topics.

          • RLa

            Dusan, I think here we have simpler version of Factory without base class/interface for the Factory class itself. The one with base class is called Abstract Factory because you can “plug in” different implementations of Factory. Sometimes it is not needed, and by the way, concrete Factory already has ability to return different objects based on Factory configuration. Having base class for Factory that has or will have only single implmentation makes code more complex than it has to be.

          • Dusan

            @Timothy Boronczyk
            I was actually thinking about writing for PHPMaster (or some other mag). Thank you.
            @RLa
            No, no I didn’t mixed them up. The Abstract Factory is “the third factory pattern”. You could check it on the page George Palmer pasted – http://stackoverflow.com/questions/4209791/design-patterns-abstract-factory-vs-factory-method

  • Shadow Caster

    How would you pass arguments to the constructor of a factory-created object?

    • GaryJ

      Shadow,
      Using the first example code block above, you’d need to pass a variable (an array of constructor args would be a simple choice) to the build method on line 4, and these could then be passed through to the constructor via the new call in line 8. All of your product class could accept one optional array.

  • SparK

    I have used this pattern before, I have a Video class, an Embedable interface and two classes that implement it, YouTubeVideo and VimeoVideo, the classes are just API translation toys. When I need a video and I know the url and/or id I just call Video::create($id); and recieve a video class, the vendor independent interface ensures everything works.

  • Alex Gervasio

    Nice and concise post, Ignatius. Even though, I’d like to point out a few details regarding the implementation of the pattern, which are relevant in terms of flexibility and testability: while your examples in general stick to the GoF outlines (which indeed is a good thing), keep in mind that some theoretical concepts should be updated to more efficient and modern OO programming approaches.

    First and foremost, static factories (yes, the ones implementing the “classic” static factory method) are pres see pretty inflexible and hard to test in isolation, as the only way to extend them is via Inheritance. Plus, because of their static and globally accessible nature (a big NO even in shared-nothing architectures like PHP’s), there’s no way to take advantage of the benefits brought by Polymorphism, hence they can’t be injected (read Composition or Aggregation) into the internals of other objects, or passed them around.

    For obvious reason, this introduces a lot of coupling. A glaring example of this common flaw is your Product_MobileDevice class. In this case, it’s clear to see that any object spawned from it will expose a strong dependency with the factory, hence making impossible to mock it up without having the factory at hand. This is, in practical terms, a typical violation of the Law of Demeter (http://en.wikipedia.org/wiki/Law_of_Demeter), and I’m not just being a blind worshiper of a bunch of purist principles.

    To summarize: in most cases (even in simplistic ones) it’s preferable to implement an abstract factory, rather than a static one. The process typically requires to define an interface with a contract containing a single “create()” method (or whatever you like to name it), and build concrete, instantiable implementers, which are responsible for creating specific objects. At a glance, this might sound overkill, but it’s not, believe me.

    Keep up the good work.

  • http://meta-blogger.com/ Michael

    Wow i thought this was a very good explanation and felt like i had actually learned something useful being rather new to OOP. Then i realized that there are quite a few flaws that others pointed out. I have searched hi and low for PHP specific tutorials on OOP PHP but can never find any that don’t have errors or that has been explained in an easy to understand way.

    Can any of you guys point me to a good online tutorial or book on PHP OOP, i tried head first design patterns but that seemed to be too java based for me to understand.

    Or better yet perhaps you guys can work together and create a php oop series of articles as i’d really love to learn it, i have used it once or twice but only on small projects that really didn’t need it but i really liked working with objects over procedural coding.

    @Timothy Boronczyk, it’s really a shame that sitepoint hasn’t put out a book specifically on oop php as i’d buy it in a heartbeat to go with every other book i already own from sitepoint, as well as the live courses, and the new monthly membership. One thing i’d like to see added to this site since it only about php is a few categories so i can click beginner, intermediate or advanced to view them by difficulty level like they do over at switchonthecode.com

    i really want to learn oop php and killerphp has a nice intro but it does not go into more advanced topics, i think this is something that is sorely lacking for php coders and i’ve been coding php and javascript for about 12 years.

  • Anand Singh

    Really very good article on design patter.