Organizing code is going to save us from a lot of pain. Using the features of Object Oriented programming, we can employ certain design patterns to achieve better readability, reduce redundancy and create abstractions, if needed. One such pattern is the factory pattern.
The factory pattern is a type of Object Oriented pattern which follows the DRY methodology. As the name suggests, object instances are created by using a factory to make the required object for us.
Let’s have a look at a very simple example of using the factory pattern to assemble an alligator
object. To do that we first need to make factories that create the alligator
parts for us:
class TailFactory {
constructor(props) {
this.tailLength = props.tailLength;
}
};
class TorsoFactory {
constructor(props) {
this.color = props.color;
}
};
class HeadFactory {
constructor(props) {
this.snoutLenth = props.snoutLenth;
}
};
Now, we create a class that acts as an intermediary between the actual factories classes and the user. Let’s call this the ReptilePartFactory
:
class ReptilePartFactory {
constructor(type, props) {
if(type === "tail")
return new TailFactory(props);
if(type === "torso")
return new TorsoFactory(props);
if(type === "head")
return new HeadFactory(props);
}
};
Let’s go ahead and assemble the actual alligator now and use the ReptilePartFactory
to get the required parts for us:
let alligator = {};
let alligatorProps = {
tailLength : 2.5,
color: "green",
snoutLenth: 1
};
//gets a tail from the tail factory
alligator.tail = new ReptilePartFactory("tail", alligatorProps);
//gets a torso from the torso factory
alligator.torso = new ReptilePartFactory("torso", alligatorProps);
//gets a head from the head factory
alligator.head = new ReptilePartFactory("head", alligatorProps);
Take at the look the pattern above, it seems like we could use the same ReptilePartFactory
to create parts for alligator-like objects. The factories in the background would never have to know about the nature of the final object.
Thus, using the factory pattern gives us certain advantages:
Now that we have some understanding of the factory pattern, let’s explore a little bit on writing better factory pattern code.
The example above uses an if-ladder to find out which factory to call based on user input. This is a simple implementation, intuitive and not very open to changes. If we have new parts to add later, then we’d have to disturb the ReptilePartFactory
. This is a violation of SOLID principles, which states “Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”.
How about we store the factory classes in an object and call the required part factory by using the part we want as the key? First we’d have to register the factories, it’d be as simple as:
let registeredPartFactories = {};
registeredPartFactories['tail'] = class TailFactory{
...
};
registeredPartFactories['torso'] = class TorsoFactory {
...
};
registeredPartFactories['head'] = class HeadFactory {
...
};
And now, the abstract layer can call the factories like this:
class ReptilePartFactory {
constructor(type, props) {
return new registeredPartFactories[type](props);
}
};
This approach is much cleaner and allows to expand our factories without affecting code in the ReptilePartFactory
.
There are several other object oriented patterns which also increase readability and quality. So before using the factory pattern, check if there is a real requirement for it. If you’re going to create similar types of objects repeatedly and also need a layer to create new instances using these objects while providing some level of abstraction to the creation logic, then yes - the factory pattern is a good option.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!