> "The abstract factory pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes"
<br/>
* In plain words:
* A factory that groups individual but related/dependent factories together without specifying their concrete classes;
* A factory of factories;
---
# Example
* In a factory that creates kingdoms, we need objects with common theme:
* Elven kingdom needs an Elven king, Elven castle and Elven army;
* Orcish kingdom needs an Orcish king, Orcish castle and Orcish army;
<br/>
* There is a dependency between the objects in the kingdom;
---
# Diagram
* Based on the kingdom example, the diagram below showcases the different concrete factories and their concrete products:
.center[]
---
# Diagram
* The class diagram below showcases the factory of factories;
* At runtime, we can define which Kingdom type is needed and pass it as a parameter to define which concrete KingdomFactory to instantiate;
* The concrete factory returned will then be able to produce the related objects of the specified type;
.center[]
---
# Applicability
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;
---
# Applicability
Use the Abstract Factory pattern when:
* 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;
---
#Use Cases
* Selecting to call the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime;
* Unit test case writing becomes much easier;
---
# Consequences
* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time
* [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612)