Skip to content

Commit 3b90a05

Browse files
committed
docs: update abstract factory
1 parent 6e123be commit 3b90a05

File tree

1 file changed

+59
-82
lines changed

1 file changed

+59
-82
lines changed

abstract-factory/README.md

Lines changed: 59 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,25 @@ tag:
66
- Abstraction
77
- Decoupling
88
- Gang of Four
9+
- Instantiation
10+
- Polymorphism
911
---
1012

1113
## Also known as
1214

13-
Kit
15+
* Kit
1416

1517
## Intent
1618

17-
The Abstract Factory design pattern provides a way to create families of related objects without specifying their concrete classes. This allows for code that is independent of the specific classes of objects it uses, promoting flexibility and maintainability.
19+
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
1820

1921
## Explanation
2022

2123
Real-world example
2224

23-
> 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.
25+
> Imagine a furniture company that produces various styles of furniture: modern, Victorian, and rustic. Each style includes products like chairs, tables, and sofas. To ensure consistency within each style, the company uses an Abstract Factory pattern.
26+
>
27+
> In this scenario, the Abstract Factory is an interface for creating families of related furniture objects (chairs, tables, sofas). Each concrete factory (ModernFurnitureFactory, VictorianFurnitureFactory, RusticFurnitureFactory) implements the Abstract Factory interface and creates a set of products that match the specific style. This way, clients can create a whole set of modern or Victorian furniture without worrying about the details of their instantiation. This maintains a consistent style and allows easy swapping of one style of furniture for another.
2428
2529
In plain words
2630

@@ -32,6 +36,8 @@ Wikipedia says
3236
3337
**Programmatic Example**
3438

39+
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.
40+
3541
Translating the kingdom example above. First of all, we have some interfaces and implementation for the objects in the kingdom.
3642

3743
```java
@@ -76,7 +82,6 @@ public class ElfArmy implements Army {
7682
}
7783

7884
// Orcish implementations similarly -> ...
79-
8085
```
8186

8287
Then we have the abstraction and implementations for the kingdom factory.
@@ -108,44 +113,7 @@ public class ElfKingdomFactory implements KingdomFactory {
108113
}
109114
}
110115

111-
public class OrcKingdomFactory implements KingdomFactory {
112-
113-
@Override
114-
public Castle createCastle() {
115-
return new OrcCastle();
116-
}
117-
118-
@Override
119-
public King createKing() {
120-
return new OrcKing();
121-
}
122-
123-
@Override
124-
public Army createArmy() {
125-
return new OrcArmy();
126-
}
127-
}
128-
```
129-
130-
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.
131-
132-
```java
133-
var factory=new ElfKingdomFactory();
134-
var castle=factory.createCastle();
135-
var king=factory.createKing();
136-
var army=factory.createArmy();
137-
138-
castle.getDescription();
139-
king.getDescription();
140-
army.getDescription();
141-
```
142-
143-
Program output:
144-
145-
```java
146-
This is the elven castle!
147-
This is the elven king!
148-
This is the elven Army!
116+
// Orcish implementations similarly -> ...
149117
```
150118

151119
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`). In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for.
@@ -164,50 +132,62 @@ public static class FactoryMaker {
164132
};
165133
}
166134
}
135+
```
167136

168-
public static void main(String[] args) {
169-
var app = new App();
137+
Here is the main function of our example application:
138+
139+
```java
140+
LOGGER.info("elf kingdom");
141+
createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
142+
LOGGER.info(kingdom.getArmy().getDescription());
143+
LOGGER.info(kingdom.getCastle().getDescription());
144+
LOGGER.info(kingdom.getKing().getDescription());
145+
146+
LOGGER.info("orc kingdom");
147+
createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
148+
LOGGER.info(kingdom.getArmy().getDescription());
149+
LOGGER.info(kingdom.getCastle().getDescription());
150+
LOGGER.info(kingdom.getKing().getDescription());
151+
```
170152

171-
LOGGER.info("Elf Kingdom");
172-
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
173-
LOGGER.info(app.getArmy().getDescription());
174-
LOGGER.info(app.getCastle().getDescription());
175-
LOGGER.info(app.getKing().getDescription());
153+
The program output:
176154

177-
LOGGER.info("Orc Kingdom");
178-
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
179-
--similar use of the orc factory
180-
}
155+
```
156+
07:35:46.340 [main] INFO com.iluwatar.abstractfactory.App -- elf kingdom
157+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven army!
158+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven castle!
159+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the elven king!
160+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- orc kingdom
161+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc army!
162+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc castle!
163+
07:35:46.343 [main] INFO com.iluwatar.abstractfactory.App -- This is the orc king!
181164
```
182165

183166
## Class diagram
184167

185-
![alt text](./etc/abstract-factory.urm.png "Abstract Factory class diagram")
168+
![Abstract Factory](./etc/abstract-factory.urm.png "Abstract Factory class diagram")
186169

187170
## Applicability
188171

189-
Use the Abstract Factory pattern when
172+
Use the Abstract Factory pattern when:
190173

191-
* The system should be independent of how its products are created, composed, and represented
192-
* The system should be configured with one of the multiple families of products
193-
* The family of related product objects is designed to be used together, and you need to enforce this constraint
194-
* You want to provide a class library of products, and you want to reveal just their interfaces, not their implementations
195-
* The lifetime of the dependency is conceptually shorter than the lifetime of the consumer.
196-
* You need a run-time value to construct a particular dependency
197-
* You want to decide which product to call from a family at runtime.
198-
* You need to supply one or more parameters only known at run-time before you can resolve a dependency.
199-
* When you need consistency among products
200-
* You don’t want to change existing code when adding new products or families of products to the program.
174+
* The system should be independent of how its products are created, composed, and represented.
175+
* You need to configure the system with one of multiple families of products.
176+
* A family of related product objects must be used together, enforcing consistency.
177+
* You want to provide a class library of products, exposing only their interfaces, not their implementations.
178+
* The lifetime of dependencies is shorter than the consumer's lifetime.
179+
* Dependencies need to be constructed using runtime values or parameters.
180+
* You need to choose which product to use from a family at runtime.
181+
* Adding new products or families should not require changes to existing code.
201182

202-
Example use cases
183+
## Tutorials
203184

204-
* Selecting to call to the appropriate implementation of FileSystemAcmeService or DatabaseAcmeService or NetworkAcmeService at runtime.
205-
* Unit test case writing becomes much easier
206-
* UI tools for different OS
185+
* [Abstract Factory Design Pattern in Java (DigitalOcean)](https://www.digitalocean.com/community/tutorials/abstract-factory-design-pattern-in-java)
186+
* [Abstract Factory(Refactoring Guru)](https://refactoring.guru/design-patterns/abstract-factory)
207187

208188
## Consequences
209189

210-
Benefits
190+
Benefits:
211191

212192
* Flexibility: Easily switch between product families without code modifications.
213193

@@ -217,32 +197,29 @@ Benefits
217197

218198
* Maintainability: Changes to individual product families are localized, simplifying updates.
219199

220-
Trade-offs
200+
Trade-offs:
221201

222202
* Complexity: Defining abstract interfaces and concrete factories adds initial overhead.
223203

224204
* Indirectness: Client code interacts with products indirectly through factories, potentially reducing transparency.
225205

226-
## Tutorials
227-
228-
* [Abstract Factory Pattern Tutorial](https://www.journaldev.com/1418/abstract-factory-design-pattern-in-java)
229-
* [Refactoring Guru - Abstract Factory](https://refactoring.guru/design-patterns/abstract-factory)
230-
231206
## Known uses
232207

208+
* Java Swing's `LookAndFeel` classes for providing different look-and-feel options.
209+
* Various implementations in the Java Abstract Window Toolkit (AWT) for creating different GUI components.
233210
* [javax.xml.parsers.DocumentBuilderFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/parsers/DocumentBuilderFactory.html)
234211
* [javax.xml.transform.TransformerFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/transform/TransformerFactory.html#newInstance--)
235212
* [javax.xml.xpath.XPathFactory](http://docs.oracle.com/javase/8/docs/api/javax/xml/xpath/XPathFactory.html#newInstance--)
236213

237214
## Related patterns
238215

239-
* [Factory Method](https://java-design-patterns.com/patterns/factory-method/)
240-
* [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/)
216+
* [Factory Method](https://java-design-patterns.com/patterns/factory-method/): Abstract Factory uses Factory Methods to create products.
217+
* [Singleton](https://java-design-patterns.com/patterns/singleton/): Abstract Factory classes are often implemented as Singletons.
218+
* [Factory Kit](https://java-design-patterns.com/patterns/factory-kit/): Similar to Abstract Factory but focuses on configuring and managing a set of related objects in a flexible way.
241219

242220
## Credits
243221

244-
* [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)
245-
* [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)
246-
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3HWNf4U)
222+
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI)
247223
* [Design Patterns in Java](https://amzn.to/3Syw0vC)
248-
*
224+
* [Head First Design Patterns: Building Extensible and Maintainable Object-Oriented Software](https://amzn.to/49NGldq)
225+
* [Java Design Patterns: A Hands-On Experience with Real-World Examples](https://amzn.to/3HWNf4U)

0 commit comments

Comments
 (0)