A Simple PHP Design Pattern: The Factory Method

Factory250mThe Easiest Design Pattern in the Galaxy

As part of a Boston PHP group’s PHP Percolate, we’re going through Larry Ullman’s PHP Advanced and Object-Oriented Programming (3ed) book. In his chapter on Design Patterns, Larry has a pattern he calls, The Factory Pattern. This pattern can be found in many PHP works, and the first mention of the pattern that I found was in a series of PHP design patterns in an IBM Website in 2006. The Factory pattern was given an “honorable mention” as a pattern in the Freemans’ incredible work, Head First Design Patterns (p 117), but the Freemans note that the Factory pattern is more of a programming idiom than a true design pattern. The design pattern found in the Gang of Four’s work is a Factory Method pattern that is a true design pattern.

In looking at the Factory Method pattern, you can see two key participants—the Creator and the Product. The requesting object (Client), goes through the Creator to request a product. The key element in the Creator is an abstract method, factoryMethod(). Figure 1 shows a bare bones class diagram of the Factory Method:

Figure 1: Factory Method Class Diagram

Figure 1: Factory Method Class Diagram

The Client makes a request using the desired product as an argument in the factoryMethod(). So, instead of asking for “product X,” its requests states, “Make me product X”—or “Factory, build product X for me.” This arrangement separates the requesting object (Client) from the requested product. Thus, it is a loose binding, and if changes are made in the product, the program does not crash and burn. That’s because the request is through the factory (Creator).

In the Factory pattern, the simple factory is often declared statically (as is the case in Larry Ullman’s book), but in the Factory Method pattern, the factoryMethod() method is declared as an abstract one that can be overridden. The reason for that is flexibility. In Figure 1, you can see that a single concrete creator is instantiating a single concrete product. However, you can have several different concrete factories requiring different implementations of the factoryMethod(). In Chapter 5 of Learning PHP Design Patterns, one of the examples has two factories (concrete creators); one for graphics and another for text captions.

The Shape Factory

This example has one product, graphic shapes. It includes a red triangle, a green square, and a blue circle—-the RGB trio. The client requests each shape by specifying the name of the product in a request through the Creator. Figure 2 shows the class diagram for this implementation.

Figure 2: Class diagram for the Shape Factory

Figure 2: Class diagram for the Shape Factory


This example only includes shapes. However, suppose instead of general shapes, you had images with captions. Instead of starting all over again, you could just add another set of implemented Products for captions and had another concrete factory (concrete creator) for text. What’s important, you’re not wasting a lot of time re-doing what you’ve already done. The bigger the program, the more this kind of structure is appreciated.

To get started, run the program and download the files using the buttons below:
PlayDownload

Once you download the source code (not to mention the incredibly valuable graphics), you’re all set to understand just what’s going on.

Factory First

In working with design patterns, it helps to think in terms of what the client wants. (The client is perhaps the most important and most overlooked participant in design patterns.) So if you start with what the client wants, the next step is to ask, “How does the client get what it wants?”

  1. Client wants a product.
  2. The client must must request the product through the factory method

Now that’s fairly simple. The client is separated from the product it is requesting, and changes to the product will not affect the process used for making the request. Likewise, changes in the client request will not affect the nature of the requested product.

All we need for the Creator class is a factory method that will be implemented in the concrete creator(s). I added a protected property called $createProduct that can be used by the concrete creator.

<?php
//Creator.php
abstract class Creator
{
	protected $createdProduct;
	abstract public function factoryMethod(Product $productNow);
}
?>

An optional concrete operation (method) could be added to the abstract class, but this example is bare bones to focus on the factoryMethod().

The next step is to implement the Creator into a concrete class (implementation), ConcreteCreator. We need to include all of the concrete products that might be used; so that’s been done. It would be easier to use spl_autoload_register in the Client class, but this way, you can clearly see the product (concrete product classes) available for the factory to “manufacture.””

<?php
//ConcreteCreator.php
include_once('Creator.php');
include_once('Triangle.php');
include_once('Square.php');
include_once('Circle.php');
class ConcreteCreator extends Creator
{
	public function factoryMethod(Product $productNow)
	{
		$this->createdProduct=new $productNow();
		return($this->createdProduct->provideShape());
	}
}
?>

Note that the ConcreteCreator has no user constructor function (__construct); so the request from the Client will have to first create an instance of the ConcreteCreator and then call the factoryMethod() from the instance.

Products Please

The products that the factory is “building” are pretty simple. For this example, I just used URL strings to load up graphic files. However, you can create any kind of product you want, and as long as the interface is preserved, it will not affect the program adversely. In other words, the same request will just bring up the concrete product no matter how it is constructed. The first step is to create a Product interface.

<?php
//Product.php
interface Product
{
	function provideShape();
}
?>

The method, provideShape() is abstract (it has to be since it’s in an interface), and we’ll leave the implementation up to the concrete products. As long as the interface is preserved, we’re good to go. The first concrete product is the Triangle.

<?php
//Triangle.php
include_once('Product.php');
class Triangle implements Product
{
	public function provideShape()
	{
		return "products/triangle.png";
	}
}
?>

That’s pretty simple, and you could have just made a direct request from the Client for the same thing. The line,

imgLine

would handle the request. However, with a much larger program, you want to be sure that when you make a change that everything will go along with the change and not crash the program. Beside, you can re-use the same pattern and even most of the code in a wholly different project.

The Square and Circle concrete products are similar.

<?php
//Square.php
include_once('Product.php');
class Square implements Product
{
	public function provideShape()
	{
		return "products/square.png";
	}
}
?>
 
<?php
//Circle.php
include_once('Product.php');
class Circle implements Product
{
	public function provideShape()
	{
		return "products/circle.png";
	}	
}
?>

Try adding different shapes or even re-write the concrete products to something more complex, and the structure holds up just fine.

The Client

The Client class is implied in the class diagram (light gray box and text), but in the original class diagram, it is not. I added it here to show where it could possibly be included. Often, the “client” is a requesting module in a much larger program, but in this case the Client’s role is easy to see simply as a requesting participant in the design pattern.

The Client does not use include_once to make the concrete products available. It is unnecessary for even though the call to the factoryMethod() includes the name of the class (e.g., Triangle()), the actual instantiation of the concrete product is done by the Creator. So there’s no need for the Client to include any of the concrete products it requests. Now that’s loose binding!

Further, notice that the factoryMethod() names concrete products (Triangle, Square, Circle), but the code hinting calls for the Product data type. This shows one of the key Design Pattern principles:

Program to the interface and not the implementation.

Because PHP does not have strict typing, we need some way to add a data type reference, and that’s done with type hinting. So by referencing the interface (the Product interface), our binding is much looser, more flexible (it accepts any implementation of the interface) and so our code is less likely to get tied up in knots, it’s easier to make changes and debugging is a snap. In other words we can spend more time on coding the program and less time untangling sequential or procedural code.

Now that we see how requests are made, we need our requester class; namely the Client. In 9 of the GoF design patterns, the Client is participant, in 4 more it is implied (grayed out), and in most of the others, it’s either mentioned or used in an example. Unfortunately, it somehow gets left out of most explanations of PHP design patterns. So here, I just want to acknowledge the Client and emphasize its importance in understanding design patterns.

In this example, the Client will request all three shapes (concrete products) and do so through the factoryMethod(). First, it instantiates an instance of the ConcreteCreator, and then uses a variable named $display to store the returned data from factoryMethod() that calls the requested concrete class by instantiating it as an argument of the factoryMethod(). Keep in mind that the type hinting in the Creator interface expects a Product data type, and because each of the three classes called are all child classes of the Product (Triangle, Square, and Circle), they are accepted. That’s because they share the interface of the Product. Any Product implementation that might be added will work as well. That’s programming to the interface instead of the implementation.

<?php
//Client.php
include_once("ConcreteCreator.php");
class Client
{
	public function __construct()
	{
		$shapeNow=new ConcreteCreator();
		$display=$shapeNow->factoryMethod(new Triangle());
		echo "<img src=$display><p />";
		$display=$shapeNow->factoryMethod(new Square());
		echo "<img src=$display><p />";
		$display=$shapeNow->factoryMethod(new Circle());
		echo "<img src=$display><p />";
		echo "These shapes are brought to you by:<br />";
		echo "The Factory Method Design Pattern";		
	}	
}
$worker=new Client();
?>

Given all of the work that the factoryMethod() does in this implementation of the Factory Method pattern, it’s little wonder that it’s called The Factory Method and not The Factory pattern.

This was a simple example, and I hope it illustrates design pattern concepts that might be useful. Naturally, I’m very grateful to the Boston PHP group for running the Percolator program and those who have taken the time to be involved.

Share

Creative Commons License
A Simple PHP Design Pattern: The Factory Method by William Sanders, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.

4 Responses to “A Simple PHP Design Pattern: The Factory Method”


  • Hi William,

    I’ve got two questions:

    1. In your example – shouldn’t be better to replace the line

    “$this->createdProduct=new $productNow();”

    in ConcreteCreator by this

    “$this->createdProduct = $productNow;

    Because of I already know that $productNow must contains instance of class which implements Product interface. So I can easily assign it to “createdProduct”, don’t I?

    2. Isn’t it better to pass parameter (e.g. string name of required class) into factory method and here will have some switch to choose appropriate class?

    Sorry for bad formatted snippets, I don’t know how to push them into structured block.

    Thank you for your reply.
    George

  • Hi George,

    Both are good points.

    #1. As soon as the factoryMethod() is called from the Client, it creates a new instance of a concrete Product (Triangle, Square or Circle). Each is instantiated as an instance of the Product child; so why “re-instantiate” it? It can be done either way, but I like your way better.

    #2.I tend to avoid using switch statements in design patterns unless absolutely necessary. Those who are used to sequential and procedural programming tend to use the minimum number of objects and classes when they program. As a result, a class is often given several things to do, like sorting out choices using conditional statements. That kind of programming works fine, but when it comes time to make changes, they have to check all of their conditional statements to make sure none conflict with the changes. Remember this OOP rule;

    A class should only have a single responsibility.

    So while using a conditional may be a good procedural or sequential practice, it’s not so much a good one in OOP or design patterns. Take a look at the Strategy pattern.

    Try this for two weeks. Pretend that PHP has no conditional statements. All objects (classes) should only have a single responsibility. Try thinking OOP and let me know what happens.

    Kindest regards,
    Bill

  • Hi Bill,

    What are core differences between ‘Factory pattern’ and ‘Factory method pattern’, except the ones you mentioned above, or are those all?

    I started working with design patterns not so long ago, and found few patterns that look (almost) the same, but differ in some small aspects (that later turn to be not so small)

    *newbie to oop here

    p.s. loved the article!

  • Hi Kira,

    It’s not the case that a Simple Factory is “evil” and the Factory Method pattern is “goodness incarnate,” but something far more subtle. Suppose you have a “WebDev” program based on a Simple Factory. The client requests a “Holiday” Web site, and the factory gets a “Holiday” Web site through the Product interface. Then the client requests a “Online Store” Web site, and the factory gets an online store site from the Product interface again. Both products are children of the abstract Product parent. The factory is a concrete class; however, and so it can only ask for a product in a certain way.

    Now suppose, you realize that you’d better start creating sites for mobile as well as desktop viewing. You decide that jQuery Mobile and PHP play nicely in the sandbox together, and that you want both a web site for mobile devices AND for desktop. However, your factory is a concrete one that doesn’t have a clue how to ask for a mobile site. So it’s back to the drawing board to create a new Simple Factory.

    On the other hand, if you have a Factory Method design, the Factory is abstract — an interface or abstract class. Now, when you request a “Holiday” you can go through an interface where the abstract factory method is implemented . So instead of just asking for the factory to construct a “Holiday” site, you can let the concrete factory that is a child of the Factory interface decide “construct a site for the desktop” or “construct a site for mobile.”

    The difference between a Simple Factory and a Factory Method design pattern lies in the flexibility and better loose binding found in the Factory Method.

    Kindest regards,
    Bill

Leave a Reply