Abstract Factory

Provide an interfacefor creating families ofrelated or dependent objects without specifying their concrete classes.

Introduction

  • Built on top of Factory Pattern and it is considered as the highest factory in the hierarchy. This pattern will create factories that are its subclasses, and these factories are created in the same way that factories create sub-classes.

  • Purpose: To provide an interface for instantiating collections of objects with similar characteristics, regardless of what the object is.

  • Frequency of use: high

Structure

Components in the model:

  • AbstractFactory: Declare an interface or abstract class containing methods to create Abstract Product objects.

  • ConcreteFactory: Build, implement, and implement methods created from Abstract Factory. Each ConcreteFactory corresponds to another variant of the product and generates only those variations of that product. For example: AbstractFactory is Document then ConcreteFactory will be FancyDocument, MordernDocument.

  • AbstractProduct: Declare an interface or abstract class for a set of separate but related products. Example: AbstractProduct of AbstractFactory Document is CreateLetter, CreatePage, CreateResume

  • ConcreteProduct: are different implementations of AbstractProduct with many variations. Each group of AbstractProduct must be implemented with certain variations. For the example above we have:

    • AbstractFactory is Document then ConcreteFactory will be FancyDocument, MordernDocument

    • AbstractProduct of AbstractFactory Document is CreateLetter, CreatePage, CreateResume Then ConcreteProduct will be FacyCreateLetter, FancyCreatePage, FancyCreateResume

  • Client: is an object that uses AbstractFactory, AbstractProduct and the client can also work with any variant of ConcreteFactory, ConcreteProduct, as long as it communicates with the object through the abstract interface.

Pros and Cons

Pros

  • You can be sure that the products you’re getting from a factory are compatible with each other.

  • You avoid tight coupling between concrete products and client code.

  • Single Responsibility Principle. You can extract the product creation code into one place, making the code easier to support.

  • Open/Closed Principle. You can introduce new variants of products without breaking existing client code.

Cons

  • The code may become more complicated than it should be, since a lot of new interfaces and classes are introduced along with the pattern.

How to Implement

  1. Map out a matrix of distinct product types versus variants of these products.

  2. Declare abstract product interfaces for all product types. Then make all concrete product classes implement these interfaces.

  3. Declare the abstract factory interface with a set of creation methods for all abstract products.

  4. Implement a set of concrete factory classes, one for each product variant.

  5. Create a factory initialization code somewhere in the app. It should instantiate one of the concrete factory classes, depending on the application configuration or the current environment. Pass this factory object to all classes that construct products.

  6. Scan through the code and find all direct calls to product constructors. Replace them with calls to the appropriate creation method on the factory object.

  • Factory Method: Abstract Factory class is usually based on some Factory methods, but Prototype can also be used to combine methods in that Abstract class

  • Builder: Builder focuses on building complex objects step by step. Abstract Factory specializes in creating families of related objects. Abstract Factory returns the product immediately, while the Builder allows you to run some additional build steps before fetching the product.

  • Prototype: Abstract Factory is usually based on a set of Factory Methods, but Prototype can also be used to compose methods on these classes.

  • Singleton: Abstract Factory, Factory and Prototype are all implemented as Singleton.

Last updated