Abstract Factory Design Pattern
Updated: Jan 7, 2018
The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interface of the factory to create the concrete objects that are part of the theme. The client does not know (or care) which concrete objects it gets from each of these internal factories, since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage and relies on object composition, as object creation is implemented in methods exposed in the factory interface.
Real world example
To create a kingdom we need objects with common theme. Elven kingdom needs an Elven king, Elven castle and Elven army whereas Orcish kingdom needs an Orcish king, Orcish castle and Orcish army. There is a dependency between the objects in the kingdom.
In plain words
A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes.
The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes.
Here is an example of creating kingdoms using abstract factory design pattern. You can also find the working example for the same on GitHub. First of all we have some interfaces and implementation for the objects in the kingdom
Then we have the abstraction and implementations for the kingdom factory
Now we have our abstract factory that lets us make family of related objects i.e. Elven kingdom factory creates Elven castle, king and army etc.
Now, we can design a factory for our different kingdom factories. In this example, we created FactoryMaker, responsible for returning an instance of either ElfKingdomFactory or OrcKingdomFactory. The client can use FactoryMaker to create the desired concrete factory which, in turn, will produce different concrete objects (Army, King, Castle). In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for.
Use the Abstract Factory pattern when
a system should be independent of how its products are created, composed and represented
a system should be configured with one of multiple families of products
a 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 you want to 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.
Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime.
Unit test case writing becomes much easier
Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time.