Grokking Design Patterns for Engineers and Managers
Ask Author
Back to course home

0% completed

Vote For New Content
Abstract Factory Pattern
Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. It encapsulates the creation process, allowing you to switch between different sets of related objects seamlessly. Think of it as a super factory – a factory of factories.

Consider a scenario where software needs to function across multiple platforms, each requiring a different set of UI elements that conform to the platform's standards.

Abstract Factory Pattern - UI Elements
Abstract Factory Pattern - UI Elements

Solution: The Abstract Factory pattern provides a way to encapsulate a group of individual factories with a common goal. It allows a client to create objects from a family of classes without specifying exact classes. This pattern is ideal for the software, as it can use different factories to produce UI elements that are appropriate for the platform it's running on. This results in ensuring platform consistency and reducing platform-specific code.

Real-Life Example

Abstract Factory Pattern -Example
Abstract Factory Pattern -Example

To further grasp it, let's use an example. If you want to buy a phone, you would go to a store selling phones and ask the seller for the one you want. Since the vendor sells phones from several manufacturers, he would then give you the phone you desire. Thus, as you can see, a phone store is a factory of phones that houses devices made by many factories. The phone store can be considered a super factory.

Structure of Abstract Factory Pattern

Typically, the Abstract Factory Pattern contains the following components:

  1. AbstractFactory: An interface that declares some methods required to create various products that are related to each other.
  2. ConcreteFactory: These classes implement the methods defined in the AbstractFactory to produce products.
  3. AbstractProduct: This could refer to either a group of interfaces or abstract classes that create a category of product objects that the factory must produce.
  4. ConcreteProduct:These classes produce objects that match the desired product family using the AbstractProduct.
  5. Client: Uses interfaces declared by the Abstract Factory and Abstract Products classes. The client is independent of how the products it requires are created.
Abstract Factory Pattern - Class Diagram
Abstract Factory Pattern - Class Diagram

How It Works

  • The client requests a product from the Abstract Factory without knowing where or how the objects are created.
  • The Concrete Factory is responsible for creating the products. This factory is designed so that it only creates products that belong to a specific variant.
  • The products that are created by the factory are referred to as a family and are related/dependent on each other.

Implementation of Abstract Factory Pattern

Imagine you're the owner of a charming café, determined to offer delightful experiences to your customers with their favorite drinks and pastries.

You face an interesting challenge: creating two distinct types of cafes, a CoffeeCafe and a TeaCafe, each with its own unique menu. This is where the Abstract Factory Pattern comes into play, providing you with a recipe to design diverse product families that cater to coffee and tea enthusiasts' preferences.

Now, let's introduce the magic of the Abstract Factory Pattern to our cafes:

  • Create an abstract CafeFactory interface with methods like createDrink() and createPastry().
  • Implement two concrete factories: CoffeeCafeFactory and TeaCafeFactory, each providing their own versions of createDrink() and createPastry().
  • The result? You can effortlessly switch between cafes and their menus using the corresponding factory. Your code remains elegant, modular, and easily extensible. Using the code would be more understandable, so let's discuss it through pseudocode and implementation in different languages.

Pseudocode

# Define Abstract Product Interfaces class Drink: def serve() class Pastry: def serve() # Define Concrete Products class CoffeeDrink(Drink): def serve(): return "Serving Coffee" class CoffeePastry(Pastry): def serve(): return "Serving Croissant" class TeaDrink(Drink): def serve(): return "Serving Tea" class TeaPastry(Pastry): def serve(): return "Serving Scone" # Define Abstract Factory Interface class CafeFactory: def createDrink() def createPastry() # Define Concrete Factories class CoffeeCafeFactory(CafeFactory): def createDrink(): return CoffeeDrink() def createPastry(): return CoffeePastry() class TeaCafeFactory(CafeFactory): def createDrink(): return TeaDrink() def createPastry(): return TeaPastry() # Main Function function main(): # Creating a Coffee Cafe coffee_factory = CoffeeCafeFactory() coffee = coffee_factory.createDrink() croissant = coffee_factory.createPastry() print(coffee.serve()) # Output: Serving Coffee print(croissant.serve()) # Output: Serving Croissant # Creating a Tea Cafe tea_factory = TeaCafeFactory() tea = tea_factory.createDrink() scone = tea_factory.createPastry() print(tea.serve()) # Output: Serving Tea print(scone.serve()) # Output: Serving Scone # Call the Main Function main()

The pseudocode outlines the structure of the code and defines classes and methods.

  • Abstract Product Interfaces:
    • Drink and Pastry are abstract classes defining the interfaces for drinks and pastries.
  • Concrete Products:
    • CoffeeDrink, CoffeePastry, TeaDrink, and TeaPastry are concrete classes implementing the interfaces defined by Drink and Pastry.
  • Abstract Factory Interface:
    • CafeFactory is an abstract class defining methods to create drinks and pastries.
  • Concrete Factories:
    • CoffeeCafeFactory and TeaCafeFactory are concrete classes implementing the CafeFactory interface. They create instances of specific drinks and pastries.
  • Main Function:
    • main() is the entry point of the program. It demonstrates the creation of different types of cafes, creating drinks and pastries, and printing their respective serve messages.
Python3
Python3

. . . .

Applications of Abstract Factory

This pattern is particularly useful when the system must be independent of how objects are created, composed, and represented. It's like having a secret recipe that allows you to serve an array of beverages and pastries that perfectly match the theme of your cafe. So abstract factory comes into use when:

  • You want to ensure that the created objects are compatible with each other.

  • You need to hide the details of object creation and make it interchangeable.

  • You want to enforce a common interface for multiple factories.

Pros and Cons

ProsCons
Isolation of Concrete Classes: Clients interact with interfaces rather than specific implementations, allowing for independence from how products are created and represented.Complexity: Can introduce a lot of new interfaces and classes, which can complicate the code base.
Interchangeability of Product Families: It’s easy to switch between different product families by changing the concrete factory.Difficult to Support New Kinds of Products: Extending abstract factories to produce new kinds of Products isn't straightforward.
Consistency Among Products: Ensures that products that belong to a family are compatible with each other.Requires a Lot of Forethought: Designing the correct abstraction layers upfront is crucial, as making changes later can be difficult.
Product Consistency and Integrity: When a family of products is designed to work together, it’s enforced by the pattern.High Level of Abstraction: The high level of abstraction can make the system more difficult to debug and understand.
Separation of Concerns: The client code is decoupled from the creation process, which simplifies the client code and makes it easier to manage.Tight Coupling: Factories and products can become tightly coupled, making it hard to extend or modify.

Summary

The Abstract Factory pattern is a strong design pattern that allows you to create families of related or dependent objects without specifying their exact classes. It provides robust abstraction and encapsulation, encourages product uniformity, and helps in separating the client code from the complexities of object creation. The drawbacks are that it can make the code base more complex, be challenging to extend, and need careful planning upfront. It works well in situations where a system is stable, the product families are well-understood, and frequent changes are not expected.

.....

.....

.....

Like the course? Get enrolled and start learning!

Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible