The Factory Design Pattern is a creational design pattern that provides a way to create objects without specifying the exact class of the object that will be created. It involves creating a factory method that decides which class to instantiate based on the input or configuration. It is used when all the object creation and its business logic we need to keep at one place.
The main advantage factory design pattern is its ability to decouple the creation of an object from one particular implementation.
It allows to create object whose class is determined at runtime.
Factory allows us to expose a "surface area" that is much smaller than that of a class, class can be extended, manipulated, while factory being just a function offers fewer options to the user, making it more robust.
Hence factory can also be used to enforce encapsulation by leveraging closures.
In Javascript, one of the main ways to enforce encapsulation is through functions scopes and closures.
A factory can also be used as an encapsulation mechanism.
Encapsulation refers to controlling the access to some internal details of the component by preventing external code from manipulating them directly. The interaction with the component happen only through its public interface, isolating external code from the changes in the implementation details of the component.
Closures allow you to create private variables and methods that are not accessible from outside the factory, thereby enforcing encapsulation and hiding the internal details of object creation and implementation.
Invoking a factory, instead of directly creating new object from a class using the new operator or Object.create(), is so much more convenient and flexible in several respects.
Factory allows us to separate the creation of an object from the implementation. A factory wraps the creation of a new instance, giving us more flexibility and control in a way we do it. Inside the factory we choose to create a new instance of a class using the new operator, or leverage closures to dynamically build a stateful object literal, or even return a different object type based on a particular condition. The consumer of factory is totally unaware of how the creation of instance is carried out.
Let's take small example to understand why we need factory design pattern
function createImg(name) { return new Image(name); } const image = createImg('photo.jpg');
You could have said why to write this extra line of code , when we can directly write:
const image = new Image(name);
So the idea behind using a factory function (createImg) is to abstract away the process of creating an object.
Single Point of Change: By using a factory function, you centralize the object creation process. Refactoring or extending logic requires changes in one place rather than throughout the codebase.
Simplifies Client Code: Client code that consumes the factory function remains unchanged, even as the complexity of the object creation process increases.
Encapsulation: The factory function encapsulates any additional logic (e.g., caching, default parameters, or new object types). This prevents duplication of logic in multiple places and reduces the risk of errors during refactoring.
Maintainability: As your code grows, maintaining a factory function becomes much easier than refactoring direct instantiation. With a factory function, you can introduce new features, make optimizations, or fix bugs without affecting the rest of the code.
Here’s a basic example of implementing the Factory Design Pattern in JavaScript:
Scenario: A factory for creating different types of vehicles (Car, Bike, Truck), depending on the input.
// Vehicle constructor functions class Car { constructor(brand, model) { this.vehicleType = 'Car'; this.brand = brand; this.model = model; } drive() { return `Driving a ${this.brand} ${this.model} car.`; } } class Bike { constructor(brand, model) { this.vehicleType = 'Bike'; this.brand = brand; this.model = model; } ride() { return `Riding a ${this.brand} ${this.model} bike.`; } } class Truck { constructor(brand, model) { this.vehicleType = 'Truck'; this.brand = brand; this.model = model; } haul() { return `Hauling with a ${this.brand} ${this.model} truck.`; } } // Vehicle factory that creates vehicles based on type class VehicleFactory { static createVehicle(type, brand, model) { switch (type) { case 'car': return new Car(brand, model); case 'bike': return new Bike(brand, model); case 'truck': return new Truck(brand, model); default: throw new Error('Vehicle type not supported.'); } } } // Using the factory to create vehicles const myCar = VehicleFactory.createVehicle('car', 'Tesla', 'Model 3'); console.log(myCar.drive()); // Output: Driving a Tesla Model 3 car. const myBike = VehicleFactory.createVehicle('bike', 'Yamaha', 'MT-15'); console.log(myBike.ride()); // Output: Riding a Yamaha MT-15 bike. const myTruck = VehicleFactory.createVehicle('truck', 'Ford', 'F-150'); console.log(myTruck.haul()); // Output: Hauling with a Ford F-150 truck.
How It Works:
Ps: In the Factory Design Pattern examples above, classes like Car, Bike, and Truck are instantiated using the new keyword inside the factory method (VehicleFactory.createVehicle)
The Factory Pattern abstracts object creation, meaning the client doesn't have to use the new keyword themselves. They rely on the factory method to return the correct instance.
Reference Book : NodeJs Design pattern by Mario Casciaro
As we've explored, design patterns play a crucial role in solving common software design challenges efficiently. Whether you're just beginning like I am, or looking to deepen your understanding, the insights shared here can help you build more adaptable and scalable systems.
The journey to mastering design patterns may feel overwhelming at first, but by starting small, experimenting, and applying these concepts in real-world projects, you'll strengthen your skills as a developer. Now it's your turn! How will you apply these ideas to your work? Share your thoughts or questions in the comments below—I’d love to hear from you.
Thank you for joining me on this learning journey!
✨✨✨✨✨✨
The above is the detailed content of Factory Design Pattern in JavaScript. For more information, please follow other related articles on the PHP Chinese website!