The Factory Design Pattern
In its most simplest definition, a factory is an object that creates other objects. The purpose is to create objects without exposing the logic to the client and to use an interface to refer to the newly created object. If you find yourself having a lot of types, it will most likely benefit you to implement a factory pattern — one of the most commonly used design pattern in Java. In many ways, I found myself one step away from implementing this design pattern.
As previously mentioned, I’ve been working on a web server in Java. There were so many opportunities to implement (as I now understand!). Often, it makes sense to have an interface with concrete classes that implement the interface (again, if you have a lot of something). I created an Action
interface, which has a run
method, and is implemented by several subclasses (e.g. IndexAction
or CreateOrUpdateAction
) depending on the type of request sent by the client. Those subclasses will share the methods of that interface, but each class will have a unique way of implementing it. My Router
class is responsible for instantiating the correct Action
for a given request. The factory pattern allows you to define a base class type (e.g. interface) with any number of subclasses that implement the contract defined by the base class.
Imagine a method called setup
, whose sole purpose is to store a String
(key) and a custom type called Action
(value) to a Hashtable
. This would look like this:
However, rather than expose the innards of the method and path and their corresponding Action
, I could’ve hidden this information in a deeper layer. For instance, I could’ve created an ActionFactory
that takes in a methodAndPath
and then return an Action
. Something along the lines of the following:
class ActionFactory { public static Action getAction(String methodAndPath) {
if (methodAndPath.equals("GET /") {
return new IndexAction();
else if (methodAndPath.equals("PUT /") {
return new CreateOrUpdateAction();
...
...
}
}
}
Notice that the signature of the factory method is a class of type Action
, meaning it is returning something that implements the Action
interface. This gives us the freedom to add, modify, and delete Action
subclasses as we please without having to worry about changing the code in other places. Also, we’re giving the decision-making responsibility (of which type of Action
is returned) to the factory. Should this be exposed or occur elsewhere, it may violate Single Responsibility Principle or be at the wrong level of abstraction.
Just some food for thought. 🤔