issue #333 factory kit pattern introduced
This commit is contained in:
parent
bd82387fc1
commit
10bbf988ea
31
factory-kit/index.md
Normal file
31
factory-kit/index.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
layout: pattern
|
||||||
|
title: Factory Kit
|
||||||
|
folder: factory-kit
|
||||||
|
permalink: /patterns/factory-kit/
|
||||||
|
categories: Creational
|
||||||
|
tags:
|
||||||
|
- Java
|
||||||
|
- Difficulty-Beginner
|
||||||
|
- Functional
|
||||||
|
---
|
||||||
|
|
||||||
|
## Also known as
|
||||||
|
Virtual Constructor
|
||||||
|
|
||||||
|
## Intent
|
||||||
|
Define factory of immutable content with separated builder and factory interfaces.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Applicability
|
||||||
|
Use the Factory Kit pattern when
|
||||||
|
|
||||||
|
* a class can't anticipate the class of objects it must create
|
||||||
|
* you just want a new instance of custom builder instead of global one
|
||||||
|
* a class wants its subclasses to specify the objects it creates
|
||||||
|
* classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
* [Design Pattern Reloaded by Remi Forax: ](https://www.youtube.com/watch?v=-k2X7guaArU)
|
21
factory-kit/pom.xml
Normal file
21
factory-kit/pom.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>java-design-patterns</artifactId>
|
||||||
|
<groupId>com.iluwatar</groupId>
|
||||||
|
<version>1.10.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<artifactId>factory-kit</artifactId>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
15
factory-kit/src/main/java/com/iluwatar/factorykit/App.java
Normal file
15
factory-kit/src/main/java/com/iluwatar/factorykit/App.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
WeaponFactory 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);
|
||||||
|
});
|
||||||
|
Weapon axe = factory.create(WeaponType.AXE);
|
||||||
|
System.out.println(axe);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
public class Axe implements Weapon {
|
||||||
|
@Override public String toString() {
|
||||||
|
return "Axe{}";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by crossy on 2016-01-16.
|
||||||
|
*/
|
||||||
|
public class Bow implements Weapon {
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public interface Builder {
|
||||||
|
void add(WeaponType name, Supplier<Weapon> supplier);
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
public class Spear implements Weapon {
|
||||||
|
@Override public String toString() {
|
||||||
|
return "Spear{}";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
public class Sword implements Weapon {
|
||||||
|
@Override public String toString() {
|
||||||
|
return "Sword{}";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
public interface Weapon {
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public interface WeaponFactory {
|
||||||
|
|
||||||
|
Weapon create(WeaponType name);
|
||||||
|
|
||||||
|
static WeaponFactory factory(Consumer<Builder> consumer) {
|
||||||
|
HashMap<WeaponType, Supplier<Weapon>> map = new HashMap<>();
|
||||||
|
consumer.accept(map::put);
|
||||||
|
return name -> map.get(name).get();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.iluwatar.factorykit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by crossy on 2016-01-16.
|
||||||
|
*/
|
||||||
|
public enum WeaponType {
|
||||||
|
SWORD, AXE, BOW, SPEAR
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.iluwatar.factorykit.app;
|
||||||
|
|
||||||
|
import com.iluwatar.factorykit.App;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AppTest {
|
||||||
|
|
||||||
|
@Test public void test() {
|
||||||
|
String[] args = {};
|
||||||
|
App.main(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
|||||||
|
package com.iluwatar.factorykit.factorykit;
|
||||||
|
|
||||||
|
import com.iluwatar.factorykit.*;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by crossy on 2016-01-16.
|
||||||
|
*/
|
||||||
|
public class FactoryKitTest {
|
||||||
|
|
||||||
|
private WeaponFactory factory;
|
||||||
|
|
||||||
|
@Before public void init() {
|
||||||
|
factory = WeaponFactory.factory(builder -> {
|
||||||
|
builder.add(WeaponType.SPEAR, Spear::new);
|
||||||
|
builder.add(WeaponType.AXE, Axe::new);
|
||||||
|
builder.add(WeaponType.SWORD, Sword::new);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing {@link WeaponFactory} to produce a SPEAR asserting that the Weapon is an instance of {@link Spear}
|
||||||
|
*/
|
||||||
|
@Test public void testSpearWeapon() {
|
||||||
|
Weapon weapon = factory.create(WeaponType.SPEAR);
|
||||||
|
verifyWeapon(weapon, Spear.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing {@link WeaponFactory} to produce a AXE asserting that the Weapon is an instance of {@link Axe}
|
||||||
|
*/
|
||||||
|
@Test public void testAxeWeapon() {
|
||||||
|
Weapon weapon = factory.create(WeaponType.AXE);
|
||||||
|
verifyWeapon(weapon, Axe.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing {@link WeaponFactory} to produce a SWORD asserting that the Weapon is an instance of {@link Sword}
|
||||||
|
*/
|
||||||
|
@Test public void testWeapon() {
|
||||||
|
Weapon weapon = factory.create(WeaponType.SWORD);
|
||||||
|
verifyWeapon(weapon, Sword.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method asserts that the weapon object that is passed is an instance of the clazz
|
||||||
|
*
|
||||||
|
* @param weapon weapon object which is to be verified
|
||||||
|
* @param clazz expected class of the weapon
|
||||||
|
*/
|
||||||
|
private void verifyWeapon(Weapon weapon, Class clazz) {
|
||||||
|
assertTrue("Weapon must be an object of: " + clazz.getName(), clazz.isInstance(weapon));
|
||||||
|
}
|
||||||
|
}
|
@ -1,79 +1,75 @@
|
|||||||
package com.iluwatar.factory.method;
|
package com.iluwatar.factory.method;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Factory Method is a creational design pattern which uses factory methods to deal with the
|
* The Factory Method is a creational design pattern which uses factory methods to deal with the
|
||||||
* problem of creating objects without specifying the exact class of object that will be created.
|
* problem of creating objects without specifying the exact class of object that will be created.
|
||||||
* This is done by creating objects via calling a factory method either specified in an interface
|
* This is done by creating objects via calling a factory method either specified in an interface
|
||||||
* and implemented by child classes, or implemented in a base class and optionally overridden by
|
* and implemented by child classes, or implemented in a base class and optionally overridden by
|
||||||
* derived classes—rather than by calling a constructor.
|
* derived classes—rather than by calling a constructor.
|
||||||
*
|
* <p>
|
||||||
* <p>Factory produces the object of its liking.
|
* <p>Factory produces the object of its liking.
|
||||||
* The weapon {@link Weapon} manufactured by the
|
* The weapon {@link Weapon} manufactured by the
|
||||||
* blacksmith depends on the kind of factory implementation it is referring to.
|
* blacksmith depends on the kind of factory implementation it is referring to.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class FactoryMethodTest {
|
public class FactoryMethodTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testing {@link OrcBlacksmith} to produce a SPEAR asserting that the Weapon is an instance
|
* Testing {@link OrcBlacksmith} to produce a SPEAR asserting that the Weapon is an instance
|
||||||
* of {@link OrcWeapon}.
|
* of {@link OrcWeapon}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test public void testOrcBlacksmithWithSpear() {
|
||||||
public void testOrcBlacksmithWithSpear() {
|
Blacksmith blacksmith = new OrcBlacksmith();
|
||||||
Blacksmith blacksmith = new OrcBlacksmith();
|
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
|
||||||
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
|
verifyWeapon(weapon, WeaponType.SPEAR, OrcWeapon.class);
|
||||||
verifyWeapon(weapon, WeaponType.SPEAR, OrcWeapon.class);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testing {@link OrcBlacksmith} to produce a AXE asserting that the Weapon is an instance
|
* Testing {@link OrcBlacksmith} to produce a AXE asserting that the Weapon is an instance
|
||||||
* of {@link OrcWeapon}.
|
* of {@link OrcWeapon}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test public void testOrcBlacksmithWithAxe() {
|
||||||
public void testOrcBlacksmithWithAxe() {
|
Blacksmith blacksmith = new OrcBlacksmith();
|
||||||
Blacksmith blacksmith = new OrcBlacksmith();
|
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
|
||||||
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
|
verifyWeapon(weapon, WeaponType.AXE, OrcWeapon.class);
|
||||||
verifyWeapon(weapon, WeaponType.AXE, OrcWeapon.class);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testing {@link ElfBlacksmith} to produce a SHORT_SWORD asserting that the Weapon is an
|
* Testing {@link ElfBlacksmith} to produce a SHORT_SWORD asserting that the Weapon is an
|
||||||
* instance of {@link ElfWeapon}.
|
* instance of {@link ElfWeapon}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test public void testElfBlacksmithWithShortSword() {
|
||||||
public void testElfBlacksmithWithShortSword() {
|
Blacksmith blacksmith = new ElfBlacksmith();
|
||||||
Blacksmith blacksmith = new ElfBlacksmith();
|
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SHORT_SWORD);
|
||||||
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SHORT_SWORD);
|
verifyWeapon(weapon, WeaponType.SHORT_SWORD, ElfWeapon.class);
|
||||||
verifyWeapon(weapon, WeaponType.SHORT_SWORD, ElfWeapon.class);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Testing {@link ElfBlacksmith} to produce a SPEAR asserting that the Weapon is an instance
|
* Testing {@link ElfBlacksmith} to produce a SPEAR asserting that the Weapon is an instance
|
||||||
* of {@link ElfWeapon}.
|
* of {@link ElfWeapon}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test public void testElfBlacksmithWithSpear() {
|
||||||
public void testElfBlacksmithWithSpear() {
|
Blacksmith blacksmith = new ElfBlacksmith();
|
||||||
Blacksmith blacksmith = new ElfBlacksmith();
|
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
|
||||||
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
|
verifyWeapon(weapon, WeaponType.SPEAR, ElfWeapon.class);
|
||||||
verifyWeapon(weapon, WeaponType.SPEAR, ElfWeapon.class);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method asserts that the weapon object that is passed is an instance of the clazz and the
|
* This method asserts that the weapon object that is passed is an instance of the clazz and the
|
||||||
* weapon is of type expectedWeaponType.
|
* weapon is of type expectedWeaponType.
|
||||||
*
|
*
|
||||||
* @param weapon weapon object which is to be verified
|
* @param weapon weapon object which is to be verified
|
||||||
* @param expectedWeaponType expected WeaponType of the weapon
|
* @param expectedWeaponType expected WeaponType of the weapon
|
||||||
* @param clazz expected class of the weapon
|
* @param clazz expected class of the weapon
|
||||||
*/
|
*/
|
||||||
private void verifyWeapon(Weapon weapon, WeaponType expectedWeaponType, Class clazz) {
|
private void verifyWeapon(Weapon weapon, WeaponType expectedWeaponType, Class clazz) {
|
||||||
assertTrue("Weapon must be an object of: " + clazz.getName(), clazz.isInstance(weapon));
|
assertTrue("Weapon must be an object of: " + clazz.getName(), clazz.isInstance(weapon));
|
||||||
assertEquals("Weapon must be of weaponType: " + clazz.getName(), expectedWeaponType,
|
assertEquals("Weapon must be of weaponType: " + clazz.getName(), expectedWeaponType,
|
||||||
weapon.getWeaponType());
|
weapon.getWeaponType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1
pom.xml
1
pom.xml
@ -93,6 +93,7 @@
|
|||||||
<module>publish-subscribe</module>
|
<module>publish-subscribe</module>
|
||||||
<module>delegation</module>
|
<module>delegation</module>
|
||||||
<module>event-driven-architecture</module>
|
<module>event-driven-architecture</module>
|
||||||
|
<module>factory-kit</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user