issue #333 diagrams and index added

This commit is contained in:
Crossy147 2016-02-15 20:37:16 +01:00
parent 10bbf988ea
commit 022ab28e20
15 changed files with 159 additions and 134 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.1.9" icons="true" automaticImage="PNG" always-add-relationships="false" generalizations="true"
realizations="true" associations="true" dependencies="false" nesting-relationships="true">
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</classifier-display>
<association-display labels="true" multiplicity="true"/>
</class-diagram>

View File

@ -10,21 +10,18 @@ tags:
- Functional - Functional
--- ---
## Also known as
Virtual Constructor
## Intent ## Intent
Define factory of immutable content with separated builder and factory interfaces. Define factory of immutable content with separated builder and factory interfaces.
![alt text](./etc/factory-kit_1.png "Factory Kit") ![alt text](./etc/factory-kit.png "Factory Kit")
## Applicability ## Applicability
Use the Factory Kit pattern when Use the Factory Kit pattern when
* a class can't anticipate the class of objects it must create * 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 * you just want a new instance of a custom builder instead of the global one
* a class wants its subclasses to specify the objects it creates * you explicitly want to define types of objects, that factory can build
* classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate * you want a separated builder and creator interface
## Credits ## Credits

View File

@ -2,14 +2,14 @@ package com.iluwatar.factorykit;
public class App { public class App {
public static void main(String[] args) { public static void main(String[] args) {
WeaponFactory factory = WeaponFactory.factory(builder -> { WeaponFactory factory = WeaponFactory.factory(builder -> {
builder.add(WeaponType.SWORD, Sword::new); builder.add(WeaponType.SWORD, Sword::new);
builder.add(WeaponType.AXE, Axe::new); builder.add(WeaponType.AXE, Axe::new);
builder.add(WeaponType.SPEAR, Spear::new); builder.add(WeaponType.SPEAR, Spear::new);
builder.add(WeaponType.BOW, Bow::new); builder.add(WeaponType.BOW, Bow::new);
}); });
Weapon axe = factory.create(WeaponType.AXE); Weapon axe = factory.create(WeaponType.AXE);
System.out.println(axe); System.out.println(axe);
} }
} }

View File

@ -1,7 +1,8 @@
package com.iluwatar.factorykit; package com.iluwatar.factorykit;
public class Axe implements Weapon { public class Axe implements Weapon {
@Override public String toString() { @Override
return "Axe{}"; public String toString() {
} return "Axe";
}
} }

View File

@ -1,7 +1,8 @@
package com.iluwatar.factorykit; package com.iluwatar.factorykit;
/**
* Created by crossy on 2016-01-16.
*/
public class Bow implements Weapon { public class Bow implements Weapon {
@Override
public String toString() {
return "Bow";
}
} }

View File

@ -2,6 +2,9 @@ package com.iluwatar.factorykit;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* Functional interface that allows adding builder with name to the factory
*/
public interface Builder { public interface Builder {
void add(WeaponType name, Supplier<Weapon> supplier); void add(WeaponType name, Supplier<Weapon> supplier);
} }

View File

@ -1,7 +1,8 @@
package com.iluwatar.factorykit; package com.iluwatar.factorykit;
public class Spear implements Weapon { public class Spear implements Weapon {
@Override public String toString() { @Override
return "Spear{}"; public String toString() {
} return "Spear";
}
} }

View File

@ -1,7 +1,8 @@
package com.iluwatar.factorykit; package com.iluwatar.factorykit;
public class Sword implements Weapon { public class Sword implements Weapon {
@Override public String toString() { @Override
return "Sword{}"; public String toString() {
} return "Sword";
}
} }

View File

@ -1,4 +1,7 @@
package com.iluwatar.factorykit; package com.iluwatar.factorykit;
/**
* Interface representing weapon
*/
public interface Weapon { public interface Weapon {
} }

View File

@ -4,13 +4,18 @@ import java.util.HashMap;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* Functional interface that represents factory kit. Instance created locally gives an opportunity to strictly define
* which objects types the instance of a factory would be able to create. Factory is just a placeholder for builders with
* create method to initialize new objects.
*/
public interface WeaponFactory { public interface WeaponFactory {
Weapon create(WeaponType name); Weapon create(WeaponType name);
static WeaponFactory factory(Consumer<Builder> consumer) { static WeaponFactory factory(Consumer<Builder> consumer) {
HashMap<WeaponType, Supplier<Weapon>> map = new HashMap<>(); HashMap<WeaponType, Supplier<Weapon>> map = new HashMap<>();
consumer.accept(map::put); consumer.accept(map::put);
return name -> map.get(name).get(); return name -> map.get(name).get();
} }
} }

View File

@ -1,8 +1,5 @@
package com.iluwatar.factorykit; package com.iluwatar.factorykit;
/**
* Created by crossy on 2016-01-16.
*/
public enum WeaponType { public enum WeaponType {
SWORD, AXE, BOW, SPEAR SWORD, AXE, BOW, SPEAR
} }

View File

@ -5,9 +5,10 @@ import org.junit.Test;
public class AppTest { public class AppTest {
@Test public void test() { @Test
String[] args = {}; public void test() {
App.main(args); String[] args = {};
} App.main(args);
}
} }

View File

@ -6,53 +6,54 @@ import org.junit.Test;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
/**
* Created by crossy on 2016-01-16.
*/
public class FactoryKitTest { public class FactoryKitTest {
private WeaponFactory factory; private WeaponFactory factory;
@Before public void init() { @Before
factory = WeaponFactory.factory(builder -> { public void init() {
builder.add(WeaponType.SPEAR, Spear::new); factory = WeaponFactory.factory(builder -> {
builder.add(WeaponType.AXE, Axe::new); builder.add(WeaponType.SPEAR, Spear::new);
builder.add(WeaponType.SWORD, Sword::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} * Testing {@link WeaponFactory} to produce a SPEAR asserting that the Weapon is an instance of {@link Spear}
*/ */
@Test public void testSpearWeapon() { @Test
Weapon weapon = factory.create(WeaponType.SPEAR); public void testSpearWeapon() {
verifyWeapon(weapon, Spear.class); 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} * Testing {@link WeaponFactory} to produce a AXE asserting that the Weapon is an instance of {@link Axe}
*/ */
@Test public void testAxeWeapon() { @Test
Weapon weapon = factory.create(WeaponType.AXE); public void testAxeWeapon() {
verifyWeapon(weapon, Axe.class); 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} * Testing {@link WeaponFactory} to produce a SWORD asserting that the Weapon is an instance of {@link Sword}
*/ */
@Test public void testWeapon() { @Test
Weapon weapon = factory.create(WeaponType.SWORD); public void testWeapon() {
verifyWeapon(weapon, Sword.class); 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 * 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 weapon weapon object which is to be verified
* @param clazz expected class of the weapon * @param clazz expected class of the weapon
*/ */
private void verifyWeapon(Weapon weapon, Class clazz) { private void verifyWeapon(Weapon weapon, 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));
} }
} }

View File

@ -19,57 +19,61 @@ import static org.junit.Assert.assertTrue;
*/ */
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 public void testOrcBlacksmithWithSpear() { @Test
Blacksmith blacksmith = new OrcBlacksmith(); public void testOrcBlacksmithWithSpear() {
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR); Blacksmith blacksmith = new OrcBlacksmith();
verifyWeapon(weapon, WeaponType.SPEAR, OrcWeapon.class); Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
} 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 public void testOrcBlacksmithWithAxe() { @Test
Blacksmith blacksmith = new OrcBlacksmith(); public void testOrcBlacksmithWithAxe() {
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.AXE); Blacksmith blacksmith = new OrcBlacksmith();
verifyWeapon(weapon, WeaponType.AXE, OrcWeapon.class); Weapon weapon = blacksmith.manufactureWeapon(WeaponType.AXE);
} 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 public void testElfBlacksmithWithShortSword() { @Test
Blacksmith blacksmith = new ElfBlacksmith(); public void testElfBlacksmithWithShortSword() {
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SHORT_SWORD); Blacksmith blacksmith = new ElfBlacksmith();
verifyWeapon(weapon, WeaponType.SHORT_SWORD, ElfWeapon.class); Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SHORT_SWORD);
} 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 public void testElfBlacksmithWithSpear() { @Test
Blacksmith blacksmith = new ElfBlacksmith(); public void testElfBlacksmithWithSpear() {
Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR); Blacksmith blacksmith = new ElfBlacksmith();
verifyWeapon(weapon, WeaponType.SPEAR, ElfWeapon.class); Weapon weapon = blacksmith.manufactureWeapon(WeaponType.SPEAR);
} 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());
} }
} }