Factory Design Pattern

Recently, I was working on a project and used factory pattern to solve my design problem. I would like to share an example of how factory pattern can be helpful for developers and how it makes the code more maintainable and testable.

Basically, let me summarise the factory pattern in points

  • It is a type of creational design pattern which provide an interface for object instantiation.
  • We can delegate the responsibility of creating the object from class constructor to the method provided by the factory interface.
  • Also, sub-classes can override the base class or implement method from factory interface to return new object type.

Implementing Factory Design Pattern

Consider a case where I have to query my data warehouse in production or staging environment. Since everything comes at some cost, I also wanted to replace this call to Postgres in my local environment during development. So here factory pattern came to my rescue.

I had below following simple requirements -

  • Querying Snowflake in production or staging environment
  • Querying Postgres in my local environment

Let us first design our product interface and its classes.

Product interface

factory_client.png A product interface

This interface specifies method to be implemented by our specific database classes. For simplicity, all CRUD methods have been removed but can be specified in the above interface and then be given implementation specific details.

Product classes

Let’s create a Postgres class which would be responsible for doing necessary operations. This class would be responsible for querying all my data in development environment.

postgres_client.png A Postgres class implementing method from its interface

Also, let’s create a snowflake class which would be responsible for querying from snowflake. This class would be responsible for querying all my data in staging or production environment.

snowflake_client.png A snowflake class implementing method from the interface

After implementing the above classes, it’s time to create factories which would be responsible for creating and returning object of our above classes based of the environment I would be running my code on.

Factory Code

factory_interface.png A factory interface

The above interface returns an object which is a type of IDatabaseClient which have been implemented by our product classes.

So let’s implement the factory class which would return appropriate class based on my environment.

factory_class.png A factory implementing a factory interface

This is the factory which checks the environment at runtime and return an object of Postgres client if my environment is other than staging and production i.e. development otherwise it returns an object of Snowflake client.

Implementing Client

Anyone who consumes the code developed by other parties are generally called clients like someone calling our project API’s can be our clients. But for this post, we have our own client which just cares about the right database object based on the environment. Our client is not concerned as how database objects are created, client just wants the right object based on the environment.

client_invoking_factory.png A client asking for right database object

Also, for unit testing we can mock our specific classes and test all these classes in isolation. That’s all from this post now.

Hope this example might have helped you out, as how factory pattern helped us to make our code more maintainable and testable.

Published 15 Sep 2019

Ramblings of a Software Engineer
Deepak Sharma on Twitter