Abstract Factory Design Pattern
Overview
Abstract Factory Design Pattern, as the name suggests is an abstraction over Factory design pattern. It is one of the creational design patterns. As a factory pattern allows us to create a generic factory of one or more than one type of object, extending the same behavior abstract factory design pattern allows us to create a factory of factories, one level above the abstraction in the factory design pattern.
Consider a real-life analogy, just like a factory can create products or objects, similarly, an industry can create multiple factories. So industry can be understood as the abstract factory pattern, and a single factory can be understood as the factory pattern.
When Will We Need an Abstract Factory Design pattern?
- Abstract Factory pattern is useful for creating multiple families (or factories) of related objects so that any specific object can be created at runtime from any of the concrete factory classes.
- Abstract Factory Pattern is used when we want to expose only the interface of the collection of multiple objects and not the implementation.
- Abstract Factory Pattern is used by any client to create objects without any background knowledge of the structure, composition, and architecture of the system.
How Does the Abstract Factory Pattern Work?
In Abstract Factory Pattern, we create an interface named AbstractFactory (say), which can be used as a generic structure to define a concrete factory. These concrete factories can now be used to create objects for their respective family.
For example, say we are working on a Food App, where different types of Foods can be created like Vegetarian and Non-Vegetarian. These are the 2 major categories. Among these categories there are multiple individual products or objects, say for the Vegetarian category there is a Veg Burger, Veg Pizza, Veg Noodles, Veg Biryani, Veg Cutlet, etc. Similarly, for the Non-Vegetarian category, there is Non-Veg Burger, Non-Veg Pizza, Non-Veg Noodles, Non-Veg Biryani, Non-Veg Cutlet, etc.
In the above example, we can create an AbstractFactory interface which will be implemented by a VegFactory class and a NonVegFactory class. Now for Veg and Non-Veg there will be 2 interfaces that will be implemented by specific product concrete classes. The specific factories will be consulted for any particular type of object as per the need.
Structure of Abstract Factory Design Pattern
Implementation Details
Note: Here, we are going to take an example of a Vehicle Booking System, in which we will be considering 3 types of Vehicles (Car, Auto, and Bike), unlike the structure shown above which has only 2 types of Vehicles (Car, and Bike). Also, the Car type Vehicles considered will be of 3 types (MicroCar, MiniCar, and MegaCar), unlike the above structure where only 2 types are given (MicroCar, and MegaCar). The 3 types of Vehicles will be Car, Auto, and Bike.
- A Car in itself will be available in 3 types: Micro (Small Sized Car), Mini (Medium Sized Car), and Mega (Large Sized Car).
- An Auto in itself will be available in 2 types: Personal (Available for full booking personally), and Shared (Available for just booking a single seat).
- A Bike in itself will be available in 2 types: Sports (Expensive and Luxurius Class Bike), and Normal (Economy Class Bike).
Pseudocode for Abstract Factory Design Pattern
UML diagram for this Vehicle Booking System is depicted in the Structure section for reference. Here,
- Declare a Vehicle interface, which defines a generic structure of any vehicle.
- Define 3 abstract classes named Car, Auto, and Bike, each of which implements the Vehicle interface. Provide the definition of the inherited methods named book(int distance) and calculateCostOfBooking(int distance).
- Define the specific concrete classes for the respective types of Car (MicroCar, MiniCar, and MegaCar), Auto (PersonalAuto and SharedAuto), and Bike (SportsBike and NormalBike) by extending their respective abstract classes named Car, Auto, and Bike.
And so on provide the definition for MiniCar and MegaCar.
And so on provide the definition for SharedAuto.
And so on provide the definition for NormalBike.
- In the next step define an abstract class named AbstractVehicleFactory, which is actually the factory of factories as it defines a generic structure of any factory class. This class will be used to create specific factory objects based on the requirement of the client.
- Next, define the concrete classes for CarFactory, AutoFactory, and BikeFactory by extending the abstract class named AbstractVehicleFactory, that we created earlier. These factory classes will be used to create objects of the concrete classes of MicroCar, MiniCar, MegaCar, PersonalAuto, SharedAuto, SportsBike, NormalBike, by inheriting their respective abstract classes.
- Now, create a FactoryProvider class which can be used to create a specific type of Factory class as per the requirement of the client booking request.
- Finally, define a demo class named AbstractFactoryPatternDemoClient which will handle the client-side code for booking a cab using the provided Factory interfaces and abstract classes.
Output:
Java Code
Output (Java):
C++ Code
Output (C++):
Python Code
Output (Python):
Pros and Cons
Pros:
- Abstract Factory Pattern provides a library of objects which exposes only interfaces and abstract classes rather than their actual implementations.
- Abstract Factory Pattern is used to design a system that is independent of the way its objects are created, composed, and represented.
- Abstract Factory Pattern supports loose coupling between concrete classes and the client's code.
- Abstract Factory Pattern follows the Single Responsibility Principle because single unique responsibility is being handled by every unique class.
- Abstract Factory Pattern also supports the Open / Closed Principle, because new concrete classes referring to new products can be added without breaking the existing system.
Cons:
- Code becomes highly complex, due to a lot of interfaces, abstract classes, and concrete classes involvement.
- Readability of the code decreases due to high complexity.
Difference With Other Related Design Patterns
- Factory Pattern helps you to create an object without actually specifying the class of the object, whereas an abstract factory pattern helps you to create an object from a family of objects. Abstract Factory Pattern can be considered as a factory of factories, i.e, a super-factory.
- Builder Patterns helps to construct an object without having to worry about the order of the variables to be initialized for the object. It helps to build the object step by step and at the end, it returns the newly created object. Whereas, Abstract Factory Pattern emphasizes on creation of an object from a family of objects, rather than the order of object creation.
- Singleton Pattern makes sure that at max only one instance of an object exists throughout the application. Whereas, Abstract Factory Pattern lets you produce families of related objects without specifying their concrete classes.
Equip yourself with Instagram System Design expertise through our dynamic course, tailored to accelerate your design journey.
FAQs
Q: Can Abstract Factory Design Pattern be implemented as Singleton Design Pattern?
A: Yes
Q: What are the consequences of using the Abstract Factory Design Pattern?
A:
- It isolates concrete classes by helping you to control the classes of objects which are created by the application because in an abstract factory pattern a factory encapsulates the responsibility and the process of creating product objects, it isolates clients from implementation classes details.
- It makes exchanging product families easy.
- It promotes consistency among products