https://cutt.ly/qUp8l7m

Factory Method Pattern vs Simple Factory

Abu Jobaer

--

I have seen confusion between developers about simple factory and factory method pattern. Hence I am writing this article. I hope this article will make the confusion clear. We will see what is the difference between these two. We will see when to use the simple factory and when to use the factory method pattern?

The Client Code

We will start off using a bad example of a client code to talk about the factory method pattern vs the simple factory. We often see client code where an object is created directly using new keyword. Let’s see an example of such a client code below:

Notice the if-else conditional statements of the handle() method. There we try to create a payment gateway object based on a given argument. But doing so has some problems. It couples the object to client code. Other clients may need to create a payment gateway object. In that case, the object creation will be repetitive tasks. It is hard to test the object and more.

If you do not know them yet or need to sharpen your knowledge on the Factory Method pattern, please refer to my article on this pattern where I describe it elaborately.

Now we can imagine that creating objects in the client code is a problem. How would we solve that? Well, we have to encapsulate the object creation. To do that we will move the object creation part to another class. So that testing object creation or modification if needed happens in one place. And this is where the factory method pattern and the simple factory help us. First, we will move the object creation part using the factory method pattern, then will do the same thing using the simple factory.

Using Factory Method Pattern

The intent of the factory method pattern described by Gang of Four is as follows:

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

In short, what it says is make an interface (abstraction) for creating an object. But the job of creating an object will be done via a subclass.

To implement the factory method pattern, we need two things: an abstraction for creating an object and a subclass that follows the abstraction. Because the factory method lets the object creation happen in a subclass.

First, we will provide an interface (the abstraction) for creating a payment gateway object. The code is described below:

Notice the createPaymentGateway() abstract method. By declaring this method as an abstract method in the AbstractPaymentGateway abstract class, we ensure that creating a payment gateway object has to be done via a subclass. This method will act as a factory. This is why it is called the factory method.

Second, we need a subclass that implements the abstraction provided by the AbstractPaymentGateway abstract class. Therefore, implementing the createPaymentGateway() abstract method. Let’s do it.

The PaymentGateway class has to implement the createPaymentGateway() abstract method as it is an abstraction. The method returns a payment gateway object according to the payment type provided through the request object in our case.

Now we can use AbstractPaymentGateway abstract superclass to apply polymorphism. How? As a polymorphic parameter — another form of polymorphism. We can pass any object of a subclass of this abstract class where it has been used as a parameter. This is how polymorphism comes into play.

Now we will use the result of implementing this pattern in the client code:

Look at the handle() method of PaymentController. It does not create objects directly anymore in its body. Rather it is now telling the createPaymentGateway() method to do that. We move the object creation part to the PaymentGateway class which applies the abstraction that AbstractPaymentGateway tells it to do.

Notice the __construct() method of PaymentController. It takes a parameter which is an AbstractPaymentGatewayabstract class. From now on, it will be behaving as a polymorphic parameter.

Using Simple Factory

The intent of a simple factory is very simple. See below:

A simple factory is a class or function that creates an object.

So what it tells us is that we need a class or function that will create an object. Notice it does not tell about abstraction. We will go with a class, not with a function, for creating an object.

Let’s see an example of a simple factory class. We will try to solve the problem we have dealt with above. But, in this case, we will use a simple factory.

First of all, notice that PaymentGatewayFactory factory class does not depend on any abstraction. And it does not inherit anything from any superclass.

What this factory class does is create a payment gateway object based on a given argument. It does so by extracting the paymentType from Request object. You could have passed the paymenyType parameter directly in the createPaymentGateway() method. When to pass what totally depends on the way you design your app. Now let's use this factory class to the previous client code.

In the handle() method, we just call the createPaymentGateway() method on the PaymentGatewayFactory object to get a payment gateway object. It mitigates object creation directly in its body. And notice that PaymentGatewayFactory does not depend on any abstraction.

Look at the parameter of the __construct() method. Now, the parameter is a PaymentGatewayFactory factory class. And it is not an AbstractPaymentGateway abstract class that provides an abstraction for creating an object.

The Difference

Did you notice any difference between the factory method pattern and the simple factory? Both create objects. Both solve the problem of creating objects in client code. Both move the object creation part to a different place. Both use a separate class to handle object creation jobs.

So what is the difference?

The main difference between the factory method pattern and the simple factory lies in their intents. The intent of the factory method pattern is different from the simple factory.

The factory method pattern is a software design pattern but the simple factory is like a programming idiom.

The factory method pattern provides an abstraction/interface for creating an object. And the job must be done by a subclass. A Factory class decides an object’s instantiation in a subclass. On the other hand, the simple factory does provide a method for creating an object but it does not do that based on an abstraction.

As the factory method pattern depends on abstraction, it can apply polymorphism while the simple factory can not.

Keep in mind that the simple factory is not a design pattern does not mean you would avoid it in your code. You should just know when to use it.

When To Use Which One

Well, the question is when to use which one? It depends on the type of object. If the type of object is simple then you may use a simple factory. And if the type of object is complex then you may use the factory method pattern. For example, when you are dealing with objects that have a lot of variations.

Say, you are building a payment module from scratch for your app. You will allow Paypal and Stripe payment gateways. Both payment gateway systems support several payment method types. For example, Balance, Bank Account, or Card. You need to create a specific object when a user picks a payment type. Here is where the factory method pattern may be your friend. Applying a simple factory here will not be enough. Have a look at the code below:

This time the client code would look as same as above with an exception of the parameter type of the createPaymentGateway() method. See below:

Now a question comes up here. How to determine which one of PaypalPaymentMethod and StripePaymentMethod to use? Well, it depends on the request parameter. You can do it, where, in your app, you can meet the request object and tell your app, hey, use this one for PaymentController’s dependency.

That is it.

Note, each and every class I have used here is just for demonstration purposes. In the real world, they need to be created with more care and contracts.

Follow me here on Medium, Github, Twitter, or LinkedIn.

References

  1. Design Patterns: Elements of Reusable Object-Oriented Software
  2. Head First Design Patterns: A Brain-Friendly Guide
  3. Agile Software Development Principles, Patterns, and Practices

--

--

Abu Jobaer

Advocate Clean Code, SOLID Principles, Software Design Patterns & Principles, and TDD.