Factory pattern

Uday Reddy
5 min readJul 25, 2020

Defines an interface to create products in superclass, but let the subclass decide the type of object.

A general thumb rule: create an interface before implementing any logic. So in factory pattern, we define an interface that specifies the superclass of the objects that’ll be created. Concrete factory decide which concrete objects to create based on the superclass.

The key take away from this pattern is to not instantiate objects in your app logic but to offload it to some class, factory in this case.

We’ll take a step back and look at why and how of a factory pattern.

Let’s make some assumptions here:
1. We are building an app that sells toys.
2. We only have two toys to sell as we are a very small toy store for now.
2. We only have toys of type Car and a Doll to sell.

Let's look at the above example where we create objects in service with an if condition. It's logical and looks clean, unless, you add a new type of toy. In that case, you have to make sure all the places have been updated. So, in order to avoid this problem, it's advisable to move such logic to a place which other code can refer to. Typically a static factory method. Looks something like this…

So this is a factory method in its simplest form, this is usually enough for the simplest of cases. Let’s look at some realtime use cases where you’d need more complex factories.

Enterprise software: By definition, organization buys software and installs it in its servers. And while installing we need to configure a couple of variables. In a recent project, we used saleor, an open-source e-commerce platform. It supported multiple payment platforms like razorpay and stripe. So we had to configure an API_KEY and SECRET and name of gateway itself. And the fun part is, my code wasn’t aware of the type of gateway. The specific gateway implementation was abstracted out and a gateway object was injected at run-time.

Let's continue with our store example and say the app did great and we opened two new franchises where one sells Soft toys and the other Remote controlled toys, basically baby toys and kid toys. And the reason for keeping them separate is the growing popularity.

In a nutshell, you’re not supposed to display/sell baby toys in an baby-toy store and remote controlled toys in kid-toy store. Even grown ass men love toys but we’ll just call it kids store for now.

To solve this problem you might be tempted to do this.

Again, nothing wrong with the above solution. Wherever you use either of InfactToyFactory or KidToyFactory your client code is aware of the factory being used. Something like below.

If you compare the very first snippet and the above example it looks like we are right where we started. We have to pollute all the places we need the factory with the if condition. Or else we’ll need to write a wrapper which accepts factoryType before creating a toy. Again, the problem is that service is aware of the type of factory and then use it. There’s absolutely no way to inject mocks and hence hard to test.

So, let’s take a step back and look at the place where we took a shortcut and kept following down the rabbit hole. It all started with the selection of STATIC FUNCTION , well the problem is not the solution but the context itself. We tried to retrofit a solution which is not suitable for our growing problem.

In most cases where you don’t have another type of factory, static functions are enough.The key is to be aware of the context and not over/under engineer your solution.

Steps to implement factory method:
1. Create an interface for a product.
2. Create an interface for creating a product, a factory.
3. Now create multiple concrete-products that implement product.
4. Implement the factory and create these products based on input parameters.

You might think even this needs to be instantiated with an if condition, certainly. In conjunction with a singleton, we create an instance of the factory while the app boots and inject in places where it’s needed. And your client code only requests for an instance of ToyFactory , and let the framework decide which object to instantiate based on factory-type setting.

Your service will look like this:

That’s pretty clean if you ask me. So all the places where you need a toyFactory just inject the instance, you’ll get the instance which you initially configured. Testing is a breeze. So if you’re building enterprise software and you need to configure a factory in a group of factories, this is a way to do it. And this is also called the Abstract Factory Pattern.

SaaS: You rent the cloud-hosted software to your clients. So all the factories need to be available at all times, in the above Enterprise software, a single instance of a factory is used. In this, the client should be able to inject the desired factory.
Let's say your software is solving some real-time problems and all the toy stores in your town want your software. But they want to be able to use both factories InfantToyFactory and KidToyFactory. Good news is our code is designed to use any factory, but the only limitation it’s configured with a single factory and to use a different factory we have to configure it at compile-time. So now, we need to inject multiple factories in the same app instance.
In order to achieve that let’s also use the Strategy pattern. Stategy pattern is a fancy word for abstracting out if conditions in your code.

Instead of injecting the factory objects itself, we get them via ToyFactoryProducer.getFactory. Depending upon the type of factory and type of product we create the objects. ToyFactoryProducer decides which factory to be used and ToyFactory will decide which object to create. So here, apart from creating objects, we are creating instances of factories.
Also, this implementation is often termed as Factory of factories pattern.

If you observe, what are we actually doing? What parts of the code are abstracted out?
1. If condition: which can grow to massive lengths.
2. Direct object instantiation: we don't want our codebase to do this.
Both of these above steps are to be abstracted for developers, else the entire codebase is bombarded with if conditions and new operators. If we want to add a new object, say PremuimToys factories come in handy.

Consequences of statics:
- They solve the problem temporarily: Static functions are there for a reason, they are typically used to serve as utils. Well before using it, ask yourself, WILL I EVER HAVE ANOTHER TYPE OF UTIL? if your answer is yes then don’t even think of using it, else, you can live with it happily.
- The reason why you can’t have another type of util is that static functions cannot be abstracted, you can’t have an interface/abstract class to implement/extend.

This is part of creational design pattern series, I’ll be posting more in the days to come.

Stay tuned.

--

--