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 )