mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 12:58:37 +00:00
docs: update factory-kit
This commit is contained in:
+46
-27
@@ -3,11 +3,17 @@ title: Factory Kit
|
||||
category: Creational
|
||||
language: en
|
||||
tag:
|
||||
- Extensibility
|
||||
- Decoupling
|
||||
- Encapsulation
|
||||
- Generic
|
||||
- Instantiation
|
||||
- Object composition
|
||||
---
|
||||
## Also Known As
|
||||
|
||||
Abstract-Factory
|
||||
## Also known as
|
||||
|
||||
* Object Kit
|
||||
* Toolkit
|
||||
|
||||
## Intent
|
||||
|
||||
@@ -17,9 +23,7 @@ Define a factory of immutable content with separated builder and factory interfa
|
||||
|
||||
Real-world example
|
||||
|
||||
> Imagine a magical weapon factory that can create any type of weapon wished for. When the factory
|
||||
> is unboxed, the master recites the weapon types needed to prepare it. After that, any of those
|
||||
> weapon types can be summoned in an instant.
|
||||
> Imagine a magical weapon factory that can create any type of weapon wished for. When the factory is unboxed, the master recites the weapon types needed to prepare it. After that, any of those weapon types can be summoned in an instant.
|
||||
|
||||
In plain words
|
||||
|
||||
@@ -47,49 +51,47 @@ public class Sword implements Weapon {
|
||||
}
|
||||
}
|
||||
|
||||
// Axe, Bow, and Spear are defined similarly
|
||||
// Axe, Bow, and Spear are defined similarly...
|
||||
```
|
||||
|
||||
Next, we define a functional interface that allows adding a builder with a name to the factory.
|
||||
|
||||
```java
|
||||
public interface Builder {
|
||||
void add(WeaponType name, Supplier<Weapon> supplier);
|
||||
void add(WeaponType name, Supplier<Weapon> supplier);
|
||||
}
|
||||
```
|
||||
|
||||
The meat of the example is the `WeaponFactory` interface that effectively implements the factory
|
||||
kit pattern. The method `#factory` is used to configure the factory with the classes it needs to
|
||||
be able to construct. The method `#create` is then used to create object instances.
|
||||
The meat of the example is the `WeaponFactory` interface that effectively implements the factory kit pattern. The method `#factory` is used to configure the factory with the classes it needs to be able to construct. The method `#create` is then used to create object instances.
|
||||
|
||||
```java
|
||||
public interface WeaponFactory {
|
||||
|
||||
static WeaponFactory factory(Consumer<Builder> consumer) {
|
||||
var map = new HashMap<WeaponType, Supplier<Weapon>>();
|
||||
consumer.accept(map::put);
|
||||
return name -> map.get(name).get();
|
||||
}
|
||||
|
||||
Weapon create(WeaponType name);
|
||||
static WeaponFactory factory(Consumer<Builder> consumer) {
|
||||
var map = new HashMap<WeaponType, Supplier<Weapon>>();
|
||||
consumer.accept(map::put);
|
||||
return name -> map.get(name).get();
|
||||
}
|
||||
|
||||
Weapon create(WeaponType name);
|
||||
}
|
||||
```
|
||||
|
||||
Now, we can show how `WeaponFactory` can be used.
|
||||
|
||||
```java
|
||||
var factory = WeaponFactory.factory(builder -> {
|
||||
builder.add(WeaponType.SWORD, Sword::new);
|
||||
builder.add(WeaponType.AXE, Axe::new);
|
||||
builder.add(WeaponType.SPEAR, Spear::new);
|
||||
builder.add(WeaponType.BOW, Bow::new);
|
||||
var factory = WeaponFactory.factory( builder-> {
|
||||
builder.add(WeaponType.SWORD,Sword::new);
|
||||
builder.add(WeaponType.AXE,Axe::new);
|
||||
builder.add(WeaponType.SPEAR,Spear::new);
|
||||
builder.add(WeaponType.BOW,Bow::new);
|
||||
});
|
||||
var list = new ArrayList<Weapon>();
|
||||
list.add(factory.create(WeaponType.AXE));
|
||||
list.add(factory.create(WeaponType.SPEAR));
|
||||
list.add(factory.create(WeaponType.SWORD));
|
||||
list.add(factory.create(WeaponType.BOW));
|
||||
list.stream().forEach(weapon -> LOGGER.info("{}", weapon.toString()));
|
||||
list.stream().forEach(weapon->LOGGER.info("{}",weapon.toString()));
|
||||
```
|
||||
|
||||
Here is the console output when the example is run.
|
||||
@@ -115,11 +117,28 @@ Use the Factory Kit pattern when
|
||||
* The builder and creator interfaces need to be separated
|
||||
* Game developments and other applications that have user customisation
|
||||
|
||||
## Known Uses
|
||||
|
||||
* In Java libraries such as the Java Development Kit (JDK) where different rendering engines might be instantiated based on the runtime environment.
|
||||
* Frameworks like Spring or applications where dependency injection is heavily used, often implement this pattern to manage object creation more flexibly.
|
||||
|
||||
## Consequences
|
||||
|
||||
Benefits:
|
||||
|
||||
* Promotes loose coupling by eliminating the need to bind application-specific classes into the code.
|
||||
* Simplifies code by shifting the responsibility of instantiation to a factory object.
|
||||
|
||||
Trade-offs:
|
||||
|
||||
* Can introduce complexity into the code by requiring additional classes and interfaces.
|
||||
* Sometimes can lead to dependency issues if not properly managed.
|
||||
|
||||
## Related patterns
|
||||
|
||||
* [Builder](https://java-design-patterns.com/patterns/builder/)
|
||||
* [Factory](https://java-design-patterns.com/patterns/factory/)
|
||||
* [Abstract-Factory](https://java-design-patterns.com/patterns/abstract-factory/)
|
||||
* [Abstract Factory](https://java-design-patterns.com/patterns/abstract-factory/): Often used together with the Factory Kit to create families of related objects.
|
||||
* [Builder](https://java-design-patterns.com/patterns/builder/): Can be used to construct complex objects step-by-step using a similar approach.
|
||||
* [Prototype](https://java-design-patterns.com/patterns/prototype/): Objects that are created by cloning a prototypical instance often use a factory to manage it.
|
||||
|
||||
## Tutorials
|
||||
|
||||
|
||||
Reference in New Issue
Block a user