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
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 -
Let us first design our product interface and its classes.
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.
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.
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.
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.
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.
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.
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.
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.