DEV Community

Cover image for JavaScript Design Patterns - Factory Pattern
KristijanFištrek
KristijanFištrek

Posted on

JavaScript Design Patterns - Factory Pattern

Welcome to my new development series where I try my best to explain design patterns by using JavaScript!

What is a design pattern?

In software engineering in general, a design pattern is a reusable solution, or better yet a blueprint or a template, that we can use in different situations and programming languages in order to solve every day development problems.
They are formalized best practices which developers can follow when designing and developing a software application.
Design patterns can speed up the development process by providing tested and proven development paradigms.

There are different types of design patterns out there.

Some of the main categories are :

  1. Creational patterns
  2. Structural patterns
  3. Behavioral patterns

Today we will be discussing the factory patterns which falls under the creational category.

Why should we use the factory pattern?

Factory pattern is often times used in situations where you need to deal with potential problems which occur when creating objects.
Especially in situations where you need to create many different types of many different objects.

In that case, factory pattern enables you to call a factory method - specified in an interface or implemented in a base class - which handles the creation of objects instead of a constructor.
By calling a factory method you avoid reallocating memory for each object you create, instead a factory method does that only once when it's called.

To put it simply, our factory method is a centralized place or better yet, a factory that manufactures different types of objects.

How can I use a factory pattern?

Disclaimer - In this situation, you are free to use any of the design patterns you like and develop you own solution. I do not explicitly claim you should only use the factory pattern if you encounter a situation like this.

Let's imagine a following scenario.

You have been hired to develop an application for a car shop. The owner of the car shop wants an easy to navigate interface with the ability to document all the types of vehicles that he fixes in his shop. On a daily basis, through his and his employers hands pass around dozen different types of vehicles. You need to find a clean and concise way to insert all those types of cars into your database.

For this example, and since I've learning more about it in the past few months, we will be using JavaScript.
Important thing to notice is that these kind of patterns are not language specific, you can use them with any language you like.

  1. First of, let's assume that our mechanic works only with trucks and cars. Even though there's a lot of different types of trucks and cars, let's limit ourselves, for the purposes of this tutorial, to only this 1st class hierarchy of our vehicles.

So with that in mind, let's create our two classes for those two categories of vehicles.


function Car(name, type) {

  this.name = name;
  this.type = type;

}

function Truck(name, type) {

  this.name = name;
  this.type = type;

}

This seems pretty primitive and basic, there are better ways of doing this with the class keyword implemented in ECMA2015, but keep up with me.
With these foundations structured, let's create our factory method.


function VehiclesFactoryMethod() {

  this.create = function(name, type) {
      switch(type) {
         case "Car":
           return new Car(name, type);
         case "Truck":
           return new Truck(name, type);
         default;
      }
  }

}

With our factory method in place, we are ready to use it for our object creation!
Let's test that out.


// Let's instantiate our factory method object.
const VehiclesFactoryMethod = new VehiclesFactoryMethod();

// This array will simulate our Database for the purposes of this tutorial
const vehicles = [];

// Let's fill our array with some vehicles!
vehicles.push(VehiclesFactoryMethod.create("BMW", "Car"));
vehicles.push(VehiclesFactoryMethod.create("MAN", "Truck"));

Let's test this out!
For further testing purposes, let's create a display function.


// This function will output the inserted vehicles in a more stylized context 
function print() {
   console.log("Database of our vehicles : ");
   console.log("Name: " + this.name);
   console.log("Type: " + this.type);
}

// Let's loop through our array of vehicles 
// And call **showVehicles*** method to print them out.
vehicles.forEach( vehicle => {
   print.call(vehicle);
});

// If we have done everything correctly, this will be our console log output 
// Database of our vehicles : 
// Name: BMW
// Type: Car

// Database of our vehicles : 
// Name: MAN
// Type: Truck

With this setup, every time we want to create a new object of either a Car or Truck class, all we need to do is call our VehiclesFactoryMethod, pass the needed attributes and the factory method will take care of all memory allocations and object creation you need.

Conclusion

  1. Use the Factory Method when you don’t know beforehand the exact types and dependencies of the objects your code should work with.

  2. Use the Factory Method when you want to save system resources by reusing existing objects instead of rebuilding them each time. You often experience this need when dealing with large, resource-intensive objects such as database connections, file systems, and network resources.

Pros :

  • You avoid tight coupling between the creator and the concrete products.
  • Single Responsibility Principle. You can move the product creation code into one place in the program, making the code easier to support.
  • Open/Closed Principle. You can introduce new types of products into the program without breaking existing client code.
  • Memory preservation and greater control over your objects

Cons :

  • As far as my experiences go with the factory method, the only con I've fond so far is that the code may become more complicated since you need to introduce a lot of new subclasses to implement the pattern. The best case scenario is when you’re introducing the pattern into an existing hierarchy of creator classes.

Should you use a factory method?

Absolutely yes!

It depends on you where and how you will use it.
I have found it extremely useful in many cases.

If you have known about the factory pattern before this article, comment down below where and how are you using it.
I'd like to know more about it and discuss about potential improvements.

See you next Sunday when we will go through another design pattern!

Top comments (6)

Collapse
 
macsikora profile image
Pragmatic Maciej • Edited

Hello Kristijan.
Want to add some things here. You are very much setting a context of this pattern in class based environment. Also implementation use Class with one method. The reality is - factory is just a function, and it simplify data structure creation.

const makeVehicle = (name, type) => ({name, type});
const makeCar = (name) => makeVehicle(name, 'car');
const makeTruck = (name) => makeVehicle(name, 'truck');

// end even more concise by point free
const makeVehicle = (type) => (name) => ({name, type});
const makeCar = makeVehicle('car');
const makeTruck = makeVehicle('truck');

Enter fullscreen mode Exit fullscreen mode

Let me repeat again, factory is just a function which allows in centralized way to create structures in proper shape, thanks to that we are sure that the created object has proper structure and somebody did not missed some fields or done some typo (very often in JS world)

Its simple thing. There is no reason to complicate it.

Collapse
 
kristijanfistrek profile image
KristijanFištrek

I agree!
And damn, that code looks nice and neat 😁

Being a backend developer, I am still adjusting to this whole JS.
Would you say I completely missed mark with this or am I on a good path of applying a factory pattern into the JS structure?
Any advice is warm welcomed!

Collapse
 
macsikora profile image
Pragmatic Maciej

It depends what language are you used to. Looking on the example, looks like something very OOP like Java or C#. Not like what you are writing is wrong. Just you need to take into consideration that every time you don't need to use this probably you don't need a class. Keep up with a good work!

Thread Thread
 
kristijanfistrek profile image
KristijanFištrek

Thank you! \m/

Collapse
 
milburngomes profile image
MilburnGomes

Great Article! Design Patterns are very essentials to apply in today's world. A must book to read for design patterns is 'Erich Gamma, Richard Helm, Ralph Johnson, John M. Vlissides - Design Patterns Elements of Reusable Object-Oriented Software'
Thanks for sharing!

Collapse
 
kristijanfistrek profile image
KristijanFištrek

I agree! As I am building more and more robust applications, design patterns are saving the day 😁

Haven't read that one! I shall take a look. Thanks for the recommendation! 🤘