DEV Community

Cover image for Factory — JavaScript Design Patterns — Part 3
Jaimal Dullat
Jaimal Dullat

Posted on

Factory — JavaScript Design Patterns — Part 3

Welcome back to our series exploring common design patterns used in JavaScript development. In Part 1, we looked at what design patterns are and why they’re useful. Then in Part 2, we dove into the Singleton pattern. Today, we’ll be discussing the Factory pattern — one of the classic creational design patterns.

Imagine you have a toy factory. Instead of making each toy by hand, you have machines that can make different types of toys for you. The “Factory Pattern” in programming is like that machine. Instead of creating objects (or “toys”) directly, you ask a “factory” to do it for you. This way, if you ever want to change how a toy is made, or introduce new types of toys, you just tweak the machine (or “factory”) and everything else continues to work smoothly.


What is a Factory Pattern?

At its core, the Factory pattern is a creational pattern that encapsulates object creation. Instead of using new to create instances of objects directly, it introduces an interface for creating objects, which can be implemented in multiple ways. This allows you to change the type of objects created without affecting the client code that uses them.

The key thing a Factory handles is determining what type of object needs to be created based on certain parameters or inputs. It encapsulates the object creation logic.

Some key properties of a Factory:

  1. Object Creator — The Factory pattern is like a specialized object creator. It’s responsible for making objects, but it hides the nitty-gritty details from the rest of your code.

  2. Rules for Creating — It sets up rules for creating objects, like which type of object to create and how to do it.

  3. Specific Factories — There are specific factories for each kind of object you want to make. These factories follow the rules set by the main Factory.

  4. Similar Products — All products made by factories have to follow a common blueprint. This makes them similar and interchangeable.

  5. Easy Changes — If you want to change the way you make objects, you can do it in one place (the Factory) without messing up the rest of your code.

  6. Handles Complexity — Factories are great when creating objects is tricky, with lots of steps or options. They keep things organized.

  7. Grows with Needs — If you need new types of objects later, you can add new factories without breaking your existing code.


Implementing the Factory Pattern in JavaScript

Let’s imagine we want to create a “car toy” factory:

// This is like our blueprint for making car toys
class CarToy {
    constructor(type) {
        this.type = type;
    }
}

// This is our toy factory machine
class ToyFactory {
    createToy(toyType) {
        if (toyType === 'racing') {
            return new CarToy('Racing Car');
        } else if (toyType === 'classic') {
            return new CarToy('Classic Car');
        } else {
            throw new Error("Don't know this toy type");
        }
    }
}

// Let's use our toy factory to make some toys
const factory = new ToyFactory();
const racingToy = factory.createToy('racing');
const classicToy = factory.createToy('classic');

console.log(racingToy); // This will show: CarToy { type: 'Racing Car' }
console.log(classicToy); // This will show: CarToy { type: 'Classic Car' }
Enter fullscreen mode Exit fullscreen mode

In this example, instead of making the toys directly, we use our ToyFactory to make them for us. This makes it easier if we want to change how a toy is made or add new toys in the future.


Common Areas Where Factory Shine

Some common use cases for the Factory Design Pattern include:

  1. Databases/websites — A Factory helps connect to different databases/APIs without extra code.

  2. Building apps — Factories make it easy to add buttons, text boxes and other screen parts without copy/paste code.

  3. Expanding programs — Plugins and addons load through a Factory so new stuff works without changes.

  4. Saving things — Factories help save objects to JSON, XML or other formats without coupling to specific formats.

  5. DI containers — Factories simplify registering and getting dependencies instead of hardcoding constructor stuff.

  6. Speeding things up — Caches and object pools improve performance by reusing expensive objects from a Factory.

  7. Updating frameworks — Factories let code work across different library versions by handling object creation changes.

  8. Testing easier — Factories allow swapping real objects for test doubles so code can be checked independent of dependencies.


When Not to Use Factory

The Factory pattern introduces additional layers of abstraction, so it shouldn’t be overused. Some cases when you may not need a Factory include:

  1. When your object creations are super simple and you only need to make one type of object. Factories add overhead that isn’t needed in simple cases.

  2. If you only have one class that will ever be created, a factory overcomplicates things. A simple constructor is sufficient.

  3. When object construction needs to happen in many disparate places in your code. Factories work best when object creation is contained in one area. Distributed creation makes factories harder to maintain.

  4. For very short-lived, throw-away objects that get recreated frequently. The benefits of factories are less relevant for objects with short lifespans.

  5. When object dependencies are unlikely to change in future. Factories provide flexibility, but add unnecessary indirection if dependencies are rock solid.

  6. If your object graph is overly complex with deep inheritance hierarchies. Factories suit shallow, loosely-coupled object models better than ones with many levels.

  7. When time or engineering constraints are tight on a project. Factories take additional upfront design effort that may not be worthwhile for smaller or faster-paced work.


Conclusion

In this post we explored the Factory pattern — a creational design pattern that helps encapsulate object creation. Factories promote loose coupling by eliminating the need to bind application code to specific implementations of objects. They also provide an alternative to construction via direct instantiation with the new operator. Factories are commonly used in JavaScript to encapsulate object instantiation based on parameters.

🔥 Wait! 🔥

Give that like button some love! And if you’re feeling extra cheeky, hit follow too!

Follow me on Instagram: Click Here

Top comments (2)

Collapse
 
decker67 profile image
decker

O yeah, I like those "if then else" lines.
Why does people still think that we should use OO Patterns in JavaScript?
We do not need them, because JavaScript can do better.

Collapse
 
manchicken profile image
Mike Stemle

Dig it!