2015-08-13 23:54:40 +02:00
---
title: Abstract Factory
2021-09-12 13:27:23 +03:00
category: Creational
2021-05-19 10:49:05 -06:00
language: en
2016-08-20 13:17:53 +05:30
tags:
2019-12-13 22:22:11 +02:00
- Gang of Four
2015-08-13 23:54:40 +02:00
---
2016-01-03 21:14:30 +01:00
## Also known as
2020-08-01 16:26:14 +03:00
2016-01-03 21:14:30 +01:00
Kit
2015-11-04 21:13:32 +02:00
2016-01-03 21:14:30 +01:00
## Intent
2020-08-01 16:26:14 +03:00
2016-01-03 21:14:30 +01:00
Provide an interface for creating families of related or dependent
2015-08-13 23:54:40 +02:00
objects without specifying their concrete classes.
2017-08-13 10:09:26 +03:00
## Explanation
2020-08-01 16:26:14 +03:00
2021-06-05 10:33:25 +03:00
Real-world example
2017-08-13 10:09:26 +03:00
2021-06-05 10:33:25 +03:00
> To create a kingdom we need objects with a common theme. The elven kingdom needs an elven king, elven castle, and elven army whereas the orcish kingdom needs an orcish king, orcish castle, and orcish army. There is a dependency between the objects in the kingdom.
2017-08-13 10:09:26 +03:00
In plain words
> A factory of factories; a factory that groups the individual but related/dependent factories together without specifying their concrete classes.
Wikipedia 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
**Programmatic Example**
2021-06-05 10:33:25 +03:00
Translating the kingdom example above. First of all, we have some interfaces and implementation for the objects in the
2020-08-04 17:31:33 +03:00
kingdom.
2017-08-13 10:09:26 +03:00
2018-03-28 01:35:43 -04:00
```java
2017-08-13 10:09:26 +03:00
public interface Castle {
String getDescription();
}
2020-08-01 16:26:14 +03:00
2017-08-13 10:09:26 +03:00
public interface King {
String getDescription();
}
2020-08-01 16:26:14 +03:00
2017-08-13 10:09:26 +03:00
public interface Army {
String getDescription();
}
// Elven implementations ->
public class ElfCastle implements Castle {
2021-06-05 10:33:25 +03:00
static final String DESCRIPTION = "This is the elven castle!";
2017-08-13 10:09:26 +03:00
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfKing implements King {
2021-06-05 10:33:25 +03:00
static final String DESCRIPTION = "This is the elven king!";
2017-08-13 10:09:26 +03:00
@Override
public String getDescription() {
return DESCRIPTION;
}
}
public class ElfArmy implements Army {
2021-06-05 10:33:25 +03:00
static final String DESCRIPTION = "This is the elven Army!";
2017-08-13 10:09:26 +03:00
@Override
public String getDescription() {
return DESCRIPTION;
}
}
2020-08-01 16:26:14 +03:00
// Orcish implementations similarly -> ...
2017-08-13 10:09:26 +03:00
```
2021-06-05 10:33:25 +03:00
Then we have the abstraction and implementations for the kingdom factory.
2017-08-13 10:09:26 +03:00
2018-03-28 01:35:43 -04:00
```java
2017-08-13 10:09:26 +03:00
public interface KingdomFactory {
Castle createCastle();
King createKing();
Army createArmy();
}
public class ElfKingdomFactory implements KingdomFactory {
public Castle createCastle() {
return new ElfCastle();
}
public King createKing() {
return new ElfKing();
}
public Army createArmy() {
return new ElfArmy();
}
}
public class OrcKingdomFactory implements KingdomFactory {
public Castle createCastle() {
return new OrcCastle();
}
public King createKing() {
return new OrcKing();
}
public Army createArmy() {
return new OrcArmy();
}
}
```
2021-06-05 10:33:25 +03:00
Now we have the abstract factory that lets us make a family of related objects i.e. elven kingdom factory creates elven castle, king and army, etc.
2017-08-13 10:09:26 +03:00
2018-03-28 01:35:43 -04:00
```java
2019-11-13 21:34:51 +05:30
var factory = new ElfKingdomFactory();
var castle = factory.createCastle();
var king = factory.createKing();
var army = factory.createArmy();
2017-08-13 10:09:26 +03:00
2020-08-01 16:26:14 +03:00
castle.getDescription();
king.getDescription();
army.getDescription();
```
Program output:
```java
2021-06-05 10:33:25 +03:00
This is the elven castle!
This is the elven king!
This is the elven Army!
2017-08-13 10:09:26 +03:00
```
2015-08-13 23:54:40 +02:00
2021-06-05 10:33:25 +03:00
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 (derived from `Army` , `King` , `Castle` ).
2017-11-19 19:22:03 -02:00
In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for.
2018-03-28 01:35:43 -04:00
```java
2017-11-19 19:22:03 -02:00
public static class FactoryMaker {
public enum KingdomType {
ELF, ORC
}
public static KingdomFactory makeFactory(KingdomType type) {
switch (type) {
case ELF:
return new ElfKingdomFactory();
case ORC:
return new OrcKingdomFactory();
default:
throw new IllegalArgumentException("KingdomType not supported.");
}
}
}
public static void main(String[] args) {
2019-11-13 21:34:51 +05:30
var app = new App();
2017-11-19 19:22:03 -02:00
LOGGER.info("Elf Kingdom");
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
LOGGER.info("Orc Kingdom");
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
-- similar use of the orc factory
}
```
2019-12-07 20:01:13 +02:00
## Class diagram
2020-08-01 16:26:14 +03:00
2019-12-07 20:01:13 +02:00

2017-11-19 19:22:03 -02:00
2016-01-03 21:14:30 +01:00
## Applicability
2020-08-01 16:26:14 +03:00
2016-01-03 21:14:30 +01:00
Use the Abstract Factory pattern when
2015-08-13 23:54:40 +02:00
2021-06-05 10:33:25 +03:00
* The system should be independent of how its products are created, composed, and represented
* The system should be configured with one of the multiple families of products
2020-08-01 16:26:14 +03:00
* 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 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.
* When you need consistency among products
* You don’ t want to change existing code when adding new products or families of products to the program.
2017-05-07 13:28:54 +05:30
2020-08-04 17:31:33 +03:00
Example use cases
2017-05-07 13:28:54 +05:30
2020-08-04 17:31:33 +03:00
* Selecting to call to the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime.
2020-08-01 16:26:14 +03:00
* Unit test case writing becomes much easier
2019-10-02 08:53:57 +01:00
* UI tools for different OS
2017-05-07 13:28:54 +05:30
2021-06-24 15:57:20 +03:00
## Consequences
2017-05-07 13:28:54 +05:30
2020-08-01 16:26:14 +03:00
* Dependency injection in java hides the service class dependencies that can lead to runtime errors that would have been caught at compile time.
2019-10-02 08:53:57 +01:00
* While the pattern is great when creating predefined objects, adding the new ones might be challenging.
2021-06-05 10:33:25 +03:00
* The code becomes more complicated than it should be since a lot of new interfaces and classes are introduced along with the pattern.
2018-01-28 14:44:19 -05:00
2021-06-24 15:57:20 +03:00
## Tutorials
2020-08-01 16:26:14 +03:00
2018-01-27 20:30:15 -05:00
* [Abstract Factory Pattern Tutorial ](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java )
2017-09-23 20:55:38 -04:00
2020-08-04 17:31:33 +03:00
## Known uses
2015-08-13 23:54:40 +02:00
2015-08-15 18:03:05 +02:00
* [javax.xml.parsers.DocumentBuilderFactory ](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html )
2016-08-20 13:17:53 +05:30
* [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-- )
2015-09-22 18:25:56 +05:30
2020-08-04 17:31:33 +03:00
## Related patterns
2021-01-30 14:16:35 +02:00
* [Factory Method ](https://java-design-patterns.com/patterns/factory-method/ )
* [Factory Kit ](https://java-design-patterns.com/patterns/factory-kit/ )
2020-08-04 17:31:33 +03:00
2016-01-03 21:14:30 +01:00
## Credits
2015-09-22 18:25:56 +05:30
2020-07-06 13:31:07 +03:00
* [Design Patterns: Elements of Reusable Object-Oriented Software ](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59 )
2020-07-07 18:05:11 +03:00
* [Head First Design Patterns: A Brain-Friendly Guide ](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b )