--- layout: pattern title: Factory Kit folder: factory-kit permalink: /patterns/factory-kit/ categories: Creational language: en tags: - Extensibility --- ## Intent Define a factory of immutable content with separated builder and factory interfaces. ## Explanation 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. In plain words > Factory kit is a configurable object builder. **Programmatic Example** Let's first define the simple `Weapon` hierarchy. ```java public interface Weapon { } public enum WeaponType { SWORD, AXE, BOW, SPEAR } public class Sword implements Weapon { @Override public String toString() { return "Sword"; } } // 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 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. ```java public interface WeaponFactory { static WeaponFactory factory(Consumer consumer) { var map = new HashMap>(); 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 list = new ArrayList(); 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())); ``` Here is the console output when the example is run. ``` 21:15:49.709 [main] INFO com.iluwatar.factorykit.App - Axe 21:15:49.713 [main] INFO com.iluwatar.factorykit.App - Spear 21:15:49.713 [main] INFO com.iluwatar.factorykit.App - Sword 21:15:49.713 [main] INFO com.iluwatar.factorykit.App - Bow ``` ## Class diagram ![alt text](./etc/factory-kit.png "Factory Kit") ## Applicability Use the Factory Kit pattern when * The factory class can't anticipate the types of objects it must create * A new instance of a custom builder is needed instead of a global one * The types of objects that the factory can build need to be defined outside the class * The builder and creator interfaces need to be separated ## Related patterns * [Builder](https://java-design-patterns.com/patterns/builder/) * [Factory](https://java-design-patterns.com/patterns/factory/) ## Credits * [Design Pattern Reloaded by Remi Forax](https://www.youtube.com/watch?v=-k2X7guaArU)