Factory pattern in Node.js
Design patterns are incredibly useful and one of the best programming practices followed by software developers. They provide solutions to those problems that are recurrent during software development. They’re also known as GoF (Gang of Four) Design Patterns, which are divided into three software design patterns: creational, behavioral, and structural. We’ll discuss one of the creational patterns called the factory pattern.
Factory pattern
The factory pattern provides us with a superclass where we create objects of the classes, and the subclasses maintain the implementation part. We simply create a factory wrapper class that holds multiple classes, and then the object’s class is determined at runtime in the factory class. This way, the factory pattern allows us to decouple object creation from implementation, and we create objects by calling the factory method instead of the constructor.
Implementation
Consider a scenario where we have three types of vehicles: Car, Truck, and Bicycle. Each vehicle class is encapsulated in a separate module. We’ll create a factory wrapper class to create instances of these vehicles at runtime.
Let’s dig into the details step by step:
1. Create vehicle modules
Create a default
Vehicleclass that provides us with the interface.
export class Vehicle {constructor (type) {this.type = type}}
Now, create modules for three types of vehicles that will import the Vehicle class.
Create a module for the
Cartype:
import { Vehicle } from './vehicle.js'export class Car extends Vehicle {constructor (type) {super(type)}}
Create a module for the
Trucktype:
import { Vehicle } from './vehicle.js'export class Truck extends Vehicle {constructor (type) {super(type)}}
Create a module for the
Bicycletype:
import { Vehicle } from './vehicle.js'export class Bicycle extends Vehicle {constructor (type) {super(type)}}
2. Create a factory
This module contains our factory wrapper class called VehicleFactory.
import { Car } from './car.js'import { Truck } from './truck.js'import { Bicycle } from './bicycle.js'function VehicleFactory (type) {if (type.match(/\.jpe?g$/)) {return new ImageJpeg(type)} else if (type.match(/\.gif$/)) {return new ImageGif(type)} else if (type.match(/\.png$/)) {return new ImagePng(type)} else {throw new Error('Unsupported type of vehicle')}}const vehicle1 = VehicleFactory('car')const vehicle2 = VehicleFactory('truck')const vehicle3 = VehicleFactory('bicycle')console.log(vehicle1, vehicle2, vehicle3)
As we can see, the VehicleFactory factory method handles the object creation of all the classes. This helps us keep the classes hidden and prevents them from being extended or modified.
Here’s the complete implementation of the code:
import { Vehicle } from './vehicle.js'export class Bicycle extends Vehicle {constructor (type) {super(type)}}
Conclusion
The factory pattern helps to simplify code by exposing just a small surface area, to maintain encapsulation and to decouple object creation. These things make this pattern very useful for developers to write code that’s clean and resilient.
Free Resources