class: center, middle # Abstract Factory --- # Also known as * Kit --- # Intent * Provide an interface for creating families of related or dependent objects without specifying their concrete classes --- # Explanation * [Wikipedia](https://en.wikipedia.org/wiki/Abstract_factory_pattern) says: > "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](diagram1.png)] --- # 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[![Diagram](diagram2.png)] --- # 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 --- # Real world examples [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html) [javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--) [javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--) --- # Credits * [Design Patterns: Elements of Reusable Object-Oriented Software](http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612) --- # Tutorials * Source code http://java-design-patterns.com/patterns/abstract-factory/