Abstract Factory Pattern

The Abstract Factory pattern is a sophisticated and versatile design pattern that enables you to create families of related objects with ease, without being tied down to their specific classes. This approach provides a great deal of abstraction, allowing for seamless switching of object families while ensuring compatibility throughout. With its emphasis on modularity and flexibility, the Abstract Factory pattern is an indispensable tool for developing complex applications that are adaptable to changing environments and requirements. Embracing this pattern can result in software that is cleaner, more maintainable, and easier to extend.




The Abstract Factory pattern allows you to create families of related or dependent objects without specifying their concrete classes. This is achieved by using a factory of factories, which groups individual but related/dependent factories together.

Explanation


Real-world example:

To create a kingdom, we need objects with a common theme. For example, the elven kingdom needs an elven king, elven castle, and elven army while the orcish kingdom needs an orcish king, orcish castle, and orcish army. These objects have a dependency on each other.

In plain words:

The Abstract Factory pattern is a factory that groups related/dependent factories together without specifying their concrete classes.

According to Wikipedia:

The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes.

Programmatic Example:

Here's an example implementation for creating objects in a kingdom:

    
interface Castle {
    public String getDescription();
}

interface King {
    public String getDescription();
}

interface Army {
    public String getDescription();
}

class ElvenCastle implements Castle {
    public String getDescription() {
        return "This is the Elven castle!";
    }
}

class ElvenKing implements King {
    public String getDescription() {
        return "This is the Elven king!";
    }
}

class ElvenArmy implements Army {
    public String getDescription() {
        return "This is the Elven army!";
    }
}

class OrcishCastle implements Castle {
    public String getDescription() {
        return "This is the Orcish castle!";
    }
}

class OrcishKing implements King {
    public String getDescription() {
        return "This is the Orcish king!";
    }
}

class OrcishArmy implements Army {
    public String getDescription() {
        return "This is the Orcish army!";
    }
}

interface KingdomFactory {
    public Castle createCastle();
    public King createKing();
    public Army createArmy();
}

class ElvenKingdomFactory implements KingdomFactory {
    public Castle createCastle() {
        return new ElvenCastle();
    }

    public King createKing() {
        return new ElvenKing();
    }

    public Army createArmy() {
        return new ElvenArmy();
    }
}

class OrcishKingdomFactory implements KingdomFactory {
    public Castle createCastle() {
        return new OrcishCastle();
    }

    public King createKing() {
        return new OrcishKing();
    }

    public Army createArmy() {
        return new OrcishArmy();
    }
}

public class Main {
    public static void main(String[] args) {
        String kingdomType = "Elven"; // or "Orcish"
        KingdomFactory factory = null;

        if (kingdomType.equals("Elven")) {
            factory = new ElvenKingdomFactory();
        } else if (kingdomType.equals("Orcish")) {
            factory = new OrcishKingdomFactory();
        }

        King king = factory.createKing();
        Castle castle = factory.createCastle();
        Army army = factory.createArmy();

        System.out.println(king.getDescription());
        System.out.println(castle.getDescription());
        System.out.println(army.getDescription());
    }
}
    

Class diagram



Abstract Factory class diagram

Abstract Factory class diagram


Applicability



The Abstract Factory pattern is a design pattern that helps you create families of related or dependent objects without specifying their concrete classes. This means that you can switch between different families of objects without affecting the rest of your code.

You should consider using the Abstract Factory pattern when:

  • Your system needs to be independent of how its products are created, composed, and represented
  • Your system needs to be configured with one of multiple families of products
  • The family of related product objects is designed to be used together, and you need to enforce this constraint
  • You want to provide a class library of products and reveal just their interfaces, not their implementations
  • The lifetime of the dependency is conceptually shorter than the lifetime of the consumer.
  • You need a run-time value to construct a particular dependency
  • You want to decide which product to call from a family at runtime.
  • You need to supply one or more parameters only known at run-time before you can resolve a dependency.
  • You need consistency among products
  • You don’t want to change existing code when adding new products or families of products to the program.

Here are some example use cases for the Abstract Factory pattern:

  • Calling the appropriate implementation of FileSystemAcmeService, DatabaseAcmeService, or NetworkAcmeService at runtime
  • Simplifying unit test case writing
  • Building UI tools for different operating systems

Consequences



  • Using dependency injection in Java can hide service class dependencies, leading to runtime errors that would have been caught at compile time.
  • The Abstract Factory pattern is great for creating predefined objects, but adding new ones can be challenging.
  • The code can become more complicated than it needs to be since a lot of new interfaces and classes are introduced along with the pattern.

Tutorials



Known uses







Copyrights and trademarks and other promotional materials are held by their respective owners and their use is allowed under the fair use clause of the Copyright Law. © 2023. BestForStudy.com