Skip to content

Abstract Factory Pattern

Introduction#

The Abstract Factory Pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern is used when a system needs to be independent of how its objects are created and composed. It encapsulates a group of individual factories that have a common theme.

Abstract factory pattern overview

In Java, the Abstract Factory Pattern is implemented using interfaces and abstract classes. The Abstract Factory Pattern is similar to the Factory Method Pattern in that both patterns are creational and both use interfaces and abstract classes. However, the Abstract Factory Pattern is used to create families of objects, while the Factory Method Pattern is used to create individual objects.

The Abstract Factory Pattern is useful in situations where an application needs to be able to switch between different families of objects without changing the code that uses them. For example, if an application uses a database, it might need to switch between different database drivers depending on the type of database being used. The Abstract Factory Pattern can be used to encapsulate the creation of these different drivers, making it easy to switch between them without changing the code that uses them.

The problem statement#

Here's an example of the Abstract Factory Pattern in Java:

// Step 1: Define abstract product interfaces
interface Button {
    void display();
}

interface TextField {
    void display();
}

// Step 2: Create concrete product classes
class WindowsButton implements Button {
    @Override
    public void display() {
        System.out.println("Windows Button");
    }
}

class WindowsTextField implements TextField {
    @Override
    public void display() {
        System.out.println("Windows Text Field");
    }
}

class MacButton implements Button {
    @Override
    public void display() {
        System.out.println("Mac Button");
    }
}

class MacTextField implements TextField {
    @Override
    public void display() {
        System.out.println("Mac Text Field");
    }
}

// Step 3: Define abstract factory interface
interface GUIFactory {
    Button createButton();
    TextField createTextField();
}

// Step 4: Create concrete factory classes
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }

    @Override
    public TextField createTextField() {
        return new WindowsTextField();
    }
}

class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }

    @Override
    public TextField createTextField() {
        return new MacTextField();
    }
}

// Step 5: Client code that uses the abstract factory
public class AbstractFactoryClient {
    public static void main(String[] args) {
        // Choose a concrete factory based on the desired platform (Windows or Mac)
        GUIFactory factory = new WindowsFactory(); // Change to MacFactory to switch platforms

        // Use the factory to create products
        Button button = factory.createButton();
        TextField textField = factory.createTextField();

        // Display the created products
        button.display();
        textField.display();
    }
}

Explanation:

Abstract Product Interfaces (Button and TextField):

  • Declare interfaces for the products of a family.

Concrete Product Classes (WindowsButton, WindowsTextField, MacButton, MacTextField):

  • Implement the interfaces to create concrete products for each family.

Abstract Factory Interface (GUIFactory):

  • Declares methods for creating the products of a family.

Concrete Factory Classes (WindowsFactory and MacFactory):

  • Implement the abstract factory interface to create concrete products for a specific family.

Client Code (AbstractFactoryClient):

  • Chooses a concrete factory based on the desired platform (Windows or Mac).
  • Uses the factory to create products (button and text field).
  • Displays the created products.

In this example, the AbstractFactoryClient chooses between a WindowsFactory and a MacFactory to create a family of products (button and text field) that are compatible with each other. The client code remains independent of the specific classes of the created products, promoting flexibility and ensuring that the products are from the same family.

Understanding Abstract Factory Pattern#

The Abstract Factory Pattern is a design pattern that falls under the category of creational design patterns. It is used to encapsulate the object creation process and create families of related objects without specifying their concrete classes. According to the book "Design Patterns: Elements of Reusable Object-Oriented Software", the Abstract Factory Pattern "provides an interface for creating families of related or dependent objects without specifying their concrete classes".

The Abstract Factory Pattern is used to manage the complexity of object creation by providing an abstract interface for creating families of related objects. It allows the client code to create objects without knowing the specific classes of the objects being created. This helps to reduce the coupling between the client code and the object creation code.

The Abstract Factory Pattern is used when there are multiple families of related objects that need to be created. It is particularly useful when the client code needs to create objects from multiple families and wants to ensure that the objects are created in a consistent way.

The Applicability of the Abstract Factory Pattern is when a system should be independent of how its products are created, composed and represented. It is also used when a system needs to be configured with one of multiple families of products.

In summary, the Abstract Factory Pattern is a powerful tool for managing the complexity of object creation. It allows the client code to create families of related objects without knowing the specific classes of the objects being created. This helps to reduce the coupling between the client code and the object creation code, making the system more flexible and easier to maintain.

Abstract Factory Pattern Basics#


Singleton Pattern Definition

The Singleton pattern restricts the instantiation of a class to a single instance and ensures that the instance is globally accessible. In other words, it guarantees that only one instance of a class is created and provides a global point of access to that instance.

   classDiagram
        direction LR
        Client --> AbstractFactory
        Client --> AbstractProduct
        AbstractFactory <|-- ConcreteFactory
        AbstractProduct <|-- ProductA
        AbstractProduct <|-- ProductB
        ProductA <.. ConcreteFactory : creates
        ProductB <.. ConcreteFactory : creates

        class Client {
        }
        class AbstractFactory{
        +CreateProductA()
        +CreateProductB()
        }
        class ConcreteFactory{
        +Create productA()
        +Create productB()
        }
        class AbstractProduct{
        }
package com.javadesignpatterns.creational.singleton.solution;

public class Singleton {

    private static Singleton instance; //(1)!

    private Singleton() {} //(2)!

    public static Singleton getInstance() { //(3)!
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

}
  1. static instance: Singleton declares a private static instance of the Singleton class. This will hold the sole instance of the class.
  2. Singleton() marks the constructor as private to prevent instantiation from outside the class.
  3. static getInstance(): Singleton is a public static method that controls access to the singleton instance. This method creates a new instance of the class if one does not already exist, or returns the existing instance if it does.

In Java, the Abstract Factory pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. The pattern is an extension of the Factory Method pattern and is used to create a group of related objects.

The Abstract Factory pattern involves the use of abstract classes and interfaces to define the common theme among individual factories, which are responsible for creating objects. The pattern consists of a super-factory that creates other factories, which in turn create factory objects that create the final objects.

The Abstract Factory pattern is useful in situations where a system should be independent of how its products are created, composed, and represented. The pattern allows for the creation of families of related objects without the need to specify their concrete classes. This makes the system more flexible and easier to maintain, as changes to the product family can be made by simply changing the factory that creates it.

The Abstract Factory design pattern is similar to the Factory Method pattern in that it also uses factory classes to create objects. However, the difference between the two is that the Factory Method pattern creates objects through inheritance, while the Abstract Factory pattern creates objects through composition.

In Java, the Abstract Factory pattern can be implemented by defining an abstract factory interface or class that declares a set of factory methods that return abstract product objects. Concrete factory classes are then created that implement the factory interface and return concrete product objects.

Overall, the Abstract Factory pattern is a powerful design pattern that can be used to create families of related objects without the need to specify their concrete classes. It is a useful pattern for creating complex systems that need to be flexible and easy to maintain.

Key Components of Abstract Factory Pattern#

The Abstract Factory pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. It is composed of four key components: Abstract Factory, Concrete Factory, Abstract Product, and Concrete Product.

Abstract Factory#

The Abstract Factory is an abstract class that provides an interface for creating a family of related products. It declares a set of methods, each of which returns a different abstract product. The Abstract Factory class is independent of the concrete classes that implement the products.

Concrete Factory#

A Concrete Factory is a concrete class that implements the Abstract Factory interface. It is responsible for creating a family of related products. Concrete factories are represented by sub-classes of the AbstractFactory class.

Abstract Product#

The Abstract Product is an abstract class that declares an interface for a type of product. Each product family has a corresponding Abstract Product. The Abstract Product is independent of the concrete classes that implement the product.

Concrete Product#

A Concrete Product is a concrete class that implements the Abstract Product interface. It is a specific type of product in a product family. Concrete products are represented by sub-classes of the AbstractProduct class.

The Abstract Factory pattern provides a way to ensure consistency among the products that are created by a factory. The products that are created by a factory are composed of related objects that work together to accomplish a task. By using an Abstract Factory pattern, the relationships among the objects are represented in the factory interface.

The Abstract Factory pattern is useful when there are families of objects that need to be created. The pattern provides a way to ensure that the objects in a family are related and work together. The pattern also provides a way to create families of objects that can be easily extended in the future.

Abstract Factory Pattern Class Diagram#

The class diagram for the Abstract Factory Pattern is a UML diagram that shows the relationship between the classes involved in the pattern. It is a graphical representation of the pattern's structure and is useful in understanding how the pattern works.

The Abstract Factory Pattern consists of four main components:

  1. AbstractFactory: This is an abstract class or interface that defines the methods for creating the objects of a family. It provides an interface for creating the product objects without specifying their concrete classes.

  2. ConcreteFactory: This is a class that implements the AbstractFactory interface. It creates concrete product objects of a family.

  3. AbstractProduct: This is an abstract class or interface that defines the methods for the products created by the AbstractFactory.

  4. ConcreteProduct: This is a class that implements the AbstractProduct interface. It creates concrete product objects of a family.

The class diagram for the Abstract Factory Pattern shows the relationship between these components. It consists of two main parts:

  1. Abstract Factory: This is the top-level interface or abstract class that defines the methods for creating the objects of a family. It has a method for each product in the family.

  2. Concrete Factory: This is a class that implements the Abstract Factory interface. It creates concrete product objects of a family. It has a method for each product in the family.

The class diagram also shows the relationship between the AbstractProduct and ConcreteProduct classes. The AbstractProduct is an abstract class or interface that defines the methods for the products created by the AbstractFactory. The ConcreteProduct is a class that implements the AbstractProduct interface. It creates concrete product objects of a family.

Finally, the class diagram shows the relationship between the AbstractFactory and ConcreteFactory classes. The AbstractFactory is an abstract class or interface that defines the methods for creating the objects of a family. The ConcreteFactory is a class that implements the AbstractFactory interface. It creates concrete product objects of a family.

In summary, the class diagram for the Abstract Factory Pattern is a UML diagram that shows the relationship between the classes involved in the pattern. It consists of two main parts, the Abstract Factory and the Concrete Factory, and shows the relationship between the AbstractProduct and ConcreteProduct classes as well as the relationship between the AbstractFactory and ConcreteFactory classes.

Implementation of Abstract Factory Pattern in Java#

The Abstract Factory design pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern is useful when a system should be independent of how its products are created, composed, and represented. The Abstract Factory pattern is used when a group of related objects must be created and configured in a specific way.

Factory Interface#

The first step in implementing the Abstract Factory pattern is to create a factory interface. This interface defines the methods that will be used to create the concrete objects. For example, consider a Car Factory interface that defines methods to create different types of cars.

Concrete Factory Class#

The next step is to create concrete factory classes that implement the factory interface. These classes are responsible for creating the concrete objects. For example, a Luxury Car Factory class can create a Luxury Car object, while a Default Car Factory class can create a default car object.

Abstract Product Interface#

The Abstract Product interface defines the methods that will be used by the concrete product classes. For example, consider a Car interface that defines methods to get the car type.

Concrete Product Class#

The Concrete Product class implements the Abstract Product interface and provides the implementation for the methods defined in the interface. For example, a Luxury Car class can implement the Car interface and provide an implementation for the getCarType method.

Client Class#

The Client class uses the factory interface to create the concrete objects. The client code is decoupled from the concrete classes and is configured to use a specific factory at runtime. For example, a client can use the Luxury Car Factory to create a Luxury Car object.

Inheritance and dependency injection can also be used to implement the Abstract Factory pattern in Java. An example Java implementation of the Abstract Factory pattern can be found here.

Abstract Factory Pattern with JDK#

The Abstract Factory pattern is a creational design pattern that allows the creation of objects without specifying their concrete classes. In Java, the Abstract Factory pattern is implemented by an interface or an abstract class that defines a set of methods for creating related objects. The concrete subclasses implement these methods to create objects of specific classes.

The JDK provides examples of the Abstract Factory pattern implementation. For instance, the javax.xml.parsers.DocumentBuilderFactory class is an example of the Abstract Factory pattern. It provides a set of methods to create objects that implement the javax.xml.parsers.DocumentBuilder interface. The DocumentBuilderFactory#newInstance() method creates a new instance of the DocumentBuilderFactory class, which can then be used to create DocumentBuilder objects.

Similarly, the javax.xml.transform.TransformerFactory class is another example of the Abstract Factory pattern in the JDK. It provides a set of methods to create objects that implement the javax.xml.transform.Transformer interface. The TransformerFactory#newInstance() method creates a new instance of the TransformerFactory class, which can then be used to create Transformer objects.

Another example is the javax.xml.xpath.XPathFactory class, which provides a set of methods to create objects that implement the javax.xml.xpath.XPath interface. The XPathFactory#newInstance() method creates a new instance of the XPathFactory class, which can then be used to create XPath objects.

In conclusion, the JDK provides several examples of the Abstract Factory pattern implementation, such as DocumentBuilderFactory, TransformerFactory, and XPathFactory. These classes provide a set of methods to create related objects without specifying their concrete classes.

Abstract Factory Pattern in Real World Examples#

The Abstract Factory pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern is widely used in real-world applications, especially in situations where the system needs to be independent of how its products are created, composed, or represented.

Car Factory Example#

One of the most common examples of the Abstract Factory pattern is the car factory. A car factory produces different models of cars, such as sedans, SUVs, and trucks. Each model has different components, such as engines, transmissions, and suspensions. These components are produced by different factories, such as engine factories, transmission factories, and suspension factories.

For instance, a car factory in the USA may produce cars with engines made by a factory in Japan, transmissions made by a factory in Germany, and suspensions made by a factory in the USA. The car factory uses the Abstract Factory pattern to create families of related components, such as engines, transmissions, and suspensions, without specifying their concrete classes.

Location-Based Factory Example#

Another example of the Abstract Factory pattern is the location-based factory. A location-based factory produces products that depend on the location of the user. For instance, a location-based factory may produce products that are suitable for a particular climate, language, or culture.

For example, a location-based factory may produce jackets that are suitable for cold weather in the USA and T-shirts that are suitable for hot weather in India. The location-based factory uses the Abstract Factory pattern to create families of related products, such as jackets and T-shirts, without specifying their concrete classes.

In conclusion, the Abstract Factory pattern is a powerful design pattern that enables the creation of families of related or dependent objects without specifying their concrete classes. The pattern is widely used in real-world applications, such as car factories and location-based factories, to create families of related components and products.

Advantages and Disadvantages of Abstract Factory Pattern#

The Abstract Factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. This pattern is useful when the system needs to be independent of how its objects are created, composed, and represented.

Advantages of Abstract Factory Pattern#

The following are the advantages of using the Abstract Factory pattern:

  • Isolation of client code from concrete classes: Abstract Factory Pattern isolates the client code from concrete (implementation) classes. This means that the client code only interacts with the interface of the abstract factory and is not exposed to the details of the implementation classes.
  • Eases exchanging of object families: Abstract Factory Pattern promotes the ease of exchanging object families. This is because the abstract factory can create different sets of related objects depending on the concrete implementation of the factory.
  • Promotes consistency among objects: Abstract Factory Pattern promotes consistency among objects. This is because the abstract factory ensures that all objects created belong to the same family, ensuring consistency in the system.

Disadvantages of Abstract Factory Pattern#

The following are the disadvantages of using the Abstract Factory pattern:

  • Increased complexity: Abstract Factory Pattern adds an additional layer of abstraction and complexity to the program. This can make the program more difficult to understand and maintain.
  • Limited flexibility: Abstract Factory Pattern limits the flexibility of the program. This is because the abstract factory is responsible for creating a family of related objects, which means that adding new object families requires creating a new abstract factory.
  • Increased overhead: Abstract Factory Pattern can result in increased overhead, which can affect performance. This is because the pattern requires the creation of additional objects and interfaces, which can add to the memory and processing requirements of the program.

Overall, the Abstract Factory pattern is a useful design pattern for creating families of related or dependent objects. However, it is important to carefully consider the advantages and disadvantages of the pattern before implementing it in a program.