diff --git a/abstract-factory/README.md b/abstract-factory/README.md index c049401fc..0fb3c3cb2 100644 --- a/abstract-factory/README.md +++ b/abstract-factory/README.md @@ -120,6 +120,45 @@ king.getDescription(); // Output: This is the Elven king! army.getDescription(); // Output: This is the Elven Army! ``` +Now, we can design a factory for our different kingdom factories. In this example, we created FactoryMaker, responsible for returning an instance of either ElfKingdomFactory or OrcKingdomFactory. +The client can use FactoryMaker to create the desired concrete factory which, in turn, will produce different concrete objects (Army, King, Castle). +In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for. + +``` +public static class FactoryMaker { + + public enum KingdomType { + ELF, ORC + } + + public static KingdomFactory makeFactory(KingdomType type) { + switch (type) { + case ELF: + return new ElfKingdomFactory(); + case ORC: + return new OrcKingdomFactory(); + default: + throw new IllegalArgumentException("KingdomType not supported."); + } + } +} + +public static void main(String[] args) { + App app = new App(); + + LOGGER.info("Elf Kingdom"); + app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF)); + LOGGER.info(app.getArmy().getDescription()); + LOGGER.info(app.getCastle().getDescription()); + LOGGER.info(app.getKing().getDescription()); + + LOGGER.info("Orc Kingdom"); + app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC)); + -- similar use of the orc factory +} +``` + + ## Applicability Use the Abstract Factory pattern when diff --git a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java index d7cb296c0..4d6043abc 100644 --- a/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java +++ b/abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java @@ -25,6 +25,8 @@ package com.iluwatar.abstractfactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType; + /** * * The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme @@ -56,7 +58,7 @@ public class App { setCastle(factory.createCastle()); setArmy(factory.createArmy()); } - + King getKing(final KingdomFactory factory) { return factory.createKing(); } @@ -92,9 +94,36 @@ public class App { private void setArmy(final Army army) { this.army = army; } - + /** - * Program entry point + * The factory of kingdom factories. + */ + public static class FactoryMaker { + + /** + * Enumeration for the different types of Kingdoms. + */ + public enum KingdomType { + ELF, ORC + } + + /** + * The factory method to create KingdomFactory concrete objects. + */ + public static KingdomFactory makeFactory(KingdomType type) { + switch (type) { + case ELF: + return new ElfKingdomFactory(); + case ORC: + return new OrcKingdomFactory(); + default: + throw new IllegalArgumentException("KingdomType not supported."); + } + } + } + + /** + * Program entry point. * * @param args * command line args @@ -104,17 +133,15 @@ public class App { App app = new App(); LOGGER.info("Elf Kingdom"); - app.createKingdom(new ElfKingdomFactory()); + app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF)); LOGGER.info(app.getArmy().getDescription()); LOGGER.info(app.getCastle().getDescription()); LOGGER.info(app.getKing().getDescription()); LOGGER.info("Orc Kingdom"); - app.createKingdom(new OrcKingdomFactory()); + app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC)); LOGGER.info(app.getArmy().getDescription()); LOGGER.info(app.getCastle().getDescription()); LOGGER.info(app.getKing().getDescription()); - } - -} +} \ No newline at end of file diff --git a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java index b6fca8b23..7613edf65 100644 --- a/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java +++ b/abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java @@ -25,6 +25,9 @@ package com.iluwatar.abstractfactory; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import com.iluwatar.abstractfactory.App.FactoryMaker; +import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType; + import org.junit.Before; import org.junit.Test; @@ -39,8 +42,8 @@ public class AbstractFactoryTest { @Before public void setUp() { - elfFactory = new ElfKingdomFactory(); - orcFactory = new OrcKingdomFactory(); + elfFactory = FactoryMaker.makeFactory(KingdomType.ELF); + orcFactory = FactoryMaker.makeFactory(KingdomType.ORC); } @Test