Files
java-design-patterns/factory-kit
Ilkka Seppälä 4108f86177 docs: Prepare for new website launch (#2149)
* Changed database implementation. Removed static objects.

* Fix Logs

* Fix 40 errors from checkstyle plugin run. 139 left))

* Fix CacheStore errors from checkstyle plugin 107 left

* Fix last errors in checkstyle.

* Fix sonar issues

* Fix issues in VALIDATE phase

* Fix Bug with mongo connection. Used "Try with resources"

* Add test

* Added docker-compose for mongo db. MongoDb db work fixed.

* Provided missing tests

* Comments to start Application with mongo.

* Fix some broken links

* Remove extra space

* Update filename

* Fix some links in localization folders

* Fix link

* Update frontmatters

* Work on patterns index page

* Work on index page

* Fixes according PR comments. Mainly Readme edits.

* fix frontmatter

* add missing png

* Update pattern index.md

* Add index.md for Chinese translation

* update image paths

* update circuit breaker image paths

* Update image paths for localizations

* add generated puml

* Add missing image

* Update img file extensions

* Update the rest of the EN and ZH patterns to conform with the new website

Co-authored-by: Victor Zalevskii <zvictormail@gmail.com>
2022-10-23 16:29:49 +03:00
..
2019-12-07 18:03:49 +02:00
2022-09-14 23:22:24 +05:30
2022-09-14 23:22:24 +05:30

title, category, language, tags
title category language tags
Factory Kit Creational en
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.

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.

public interface Builder {
  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.

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);
}

Now, we can show how WeaponFactory can be used.

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()));

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

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

Credits