Modularization is the big issue in today’s programming world. Programmers all over the world trying to avoid the idea of adding code to the existing classes in order to make them support encapsulating more general information. For example, take the case of a telephone manager who manages phone numbers. Phone numbers follow a particular rule of generating code as per the area for individual countries. If at some point the application should be changed in order to support adding numbers form a new country, the code of the application would have to be changed and it would become more and more complicated. In order to prevent it, Abstract Factory Design Pattern is used.
Abstract Factory Design Pattern is another flavor of Factory Design Pattern. This pattern can be considered as a “Super Factory” or “Factory of Factories”
The purpose of abstract factory is to provide an interface for creating families of related objects, without specifying the concrete classes. It falls under the creational design pattern and provides a way to encapsulate a group of factories that have a common link without highlighting the concrete classes. This is all about an abstract factory creating various objects at run time based on user demand. The client remains completely unaware (decoupled) on which concrete products it gets from each of these individual factories and the client is only able to access a simplified interface.
So, In Abstract Factory pattern, an interface is responsible for creating a factory of related objects, without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern.
The Problem Statement
We will consider one example of Garment Factory and extend it to understand the problem statement for Abstract factory. Consider a garment Factory specialized in creating trousers and shirts. Now the parent company which is a famous retail brand is now venturing into the gadget section. They are also planning to expand their Factories having one center in US and another one in UK. The client should be completely unaware of how the objects are created.
- What is the best design pattern we can use to resolve this requirement?
- How should one go about designing applications which have to be adapted to different Look and feel standards?
Why not with Factory Design Pattern?
The above scenario cannot be resolved with Factory design pattern as this involves multiple factories and product which are related to parent company or dependent. As mentioned earlier this is the super factory. Therefore, to solve the above design problem we will use abstract factory design pattern.
Let’s have a look at one structured code example and what’s the basic difference than the Factory design pattern:-
This pattern basically works as shown in the below UML Diagram:-
The classes that participate to the Abstract factory pattern are as follows:-
Abstract factory: – declares an interface for operations that create abstract products. Concrete factory:- implements operations to create concrete products.
Abstract Product:- declares an interface for a type of product objects.
Product – defines a product to be created by the corresponding Concrete Factory; it implements the AbstractProduct interface.
Client – uses the interfaces declared by the Abstract Factory and Abstract Product classes.
The abstract Factory is the one that determines the actual type of concrete object and creates it but it returns an abstract pointer to the concrete object to just created.
The classic implementation for the abstract factory pattern is as follows:-
The Look and Feel Examples
Look and Feel Abstract Factory is the most common example. For example, a GUI Framework should support several look and feel themes, such as IBM* and HP* look. Each style defines different looks and behaviors for each type of controls: Buttons and Edit Boxes. In order to avoid hard coding for each type of control, we define an abstract class LookAndFeel. This calls will instantiate depending on a configuration parameter in the application one of the concrete factories: IBM*LookAndFeel or HP*LookAndFeel. Each request for a new object will be delegated to the instantiated concrete factory which will return the controls with the specific flavor.
Specific Problems and Implementation
The Abstract Factory pattern has both benefits and flaws:-
- On one hand it isolates the creation of objects from the client that needs them, giving the client only the possibility of accessing them through an interface, which makes the manipulation easier.
- The exchanging of product families is easier, as the class of a concrete factory appears in the code only where it is instantiated. Also if the products of a family are meant to work together, the Abstract Factory makes it easy to use the objects from only one family at a time.
- On the other hand, adding new products to the existing factories is difficult, because the Abstract Factory interface uses a fixed set of products that can be created. That is why adding a new product would mean extending the factory interface, which involves changes in the Abstract Factory class and all its subclasses.
What is Abstract Factory Design Pattern used for?
The Abstract Factory design pattern is a software design pattern used to create families of related or dependent objects without specifying their concrete classes. Its purpose is to provide an interface for creating these objects that allows for flexibility and modularity in the code.
In essence, the Abstract Factory pattern allows you to create a set of related objects that work together without specifying the exact implementation of each individual object. This makes it easy to create new families of objects simply by creating new implementations of the abstract factory interface.
For example, let’s consider a game that has different levels, each with its own set of enemies, weapons, and power-ups. Using the Abstract Factory pattern, you can define an abstract factory interface that creates these objects, and then create concrete implementations of the interface for each level. This allows you to switch between levels easily without having to worry about the specific implementation details of each object.
Overall, the Abstract Factory pattern helps to promote code reusability, modularity, and flexibility by decoupling the client code from the implementation details of the objects it uses.
Difference between Factory Pattern and Abstract Factory pattern
The main difference between the Factory Pattern and the Abstract Factory Pattern is that the Factory Pattern is used to create a single type of object, while the Abstract Factory Pattern is used to create families of related or dependent objects. The Factory Pattern provides a way to encapsulate the object creation logic in a single class, which can be reused throughout the codebase.
On the other hand, the Abstract Factory Pattern provides an interface for creating families of related objects, with each family represented by a separate concrete implementation of the abstract factory. In other words, the Abstract Factory Pattern adds an extra layer of abstraction that allows for greater flexibility and modularity in the code, at the cost of increased complexity and overhead.
When to use Abstract Factory Design Pattern?
This pattern is particularly useful in situations where you want to create objects that have a consistent interface, but may have different implementations based on the context in which they are used. For example, if you are building a game that has different levels, each with its own set of enemies, weapons, and power-ups, the Abstract Factory Pattern can be used to create a separate factory for each level.
Each factory can then create the specific set of objects needed for that level, while the client code can remain agnostic to the implementation details of each object. Ultimately, the Abstract Factory Pattern helps to promote code reusability, modularity, and flexibility, making it a valuable tool for any developer working on complex software systems.
These are the scenarios where Abstract Factory Design Patterns are a good fit:
- The system needs to be independent from the way the products it works with are created.
- The system is or should be configured to work with multiple families of products.
- A family of products is designed to work only all together.
While the pattern does a great job of hiding implementation details from the client, there is always a chance that the underlying system will need to change. We may have new attributes to our Abstract Product, or Abstract Factory, which would mean a change to the interface that the client was relying on, thus breaking the API.
With both the Factory Method and today’s pattern, the Abstract Factory, there’s one thing that annoys me – someone has to determine what type of factory the client is dealing with at run time. As you see above, this is usually done with some type of switch statement.
That said, I think it’s nice to be able to recognize a pattern when you see it, regardless what your level of experience is. It’s also good to have at least a working knowledge of how to implement patterns so that when someone is discussing design with you, you can have a common vocabulary to work with. For these reasons, the study of patterns might be relevant to all the active developers.
We end our Discussion about Design Patterns with this Blog. Stay Tuned for our next round of Blogs around the Android Technology!
Our Entire Design Pattern Series:
1. The Factory Design Pattern – The DO’s & DON’Ts of the Quintessential Creational Pattern
2. Simplifying Coding with the Decorator Design Pattern – When To & When Not to Use it!
3. The Singleton Approach – Coding like a Pro with the Right Design Patterns