Skip to content
Merged

847 #1517

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 30 additions & 87 deletions abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@

package com.iluwatar.abstractfactory;

import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -41,84 +40,14 @@
* and its implementations ( {@link ElfKingdomFactory}, {@link OrcKingdomFactory}). The example uses
* both concrete implementations to create a king, a castle and an army.
*/
public class App {
public class App implements Runnable {

private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
private static Logger log = LoggerFactory.getLogger(App.class);

private King king;
private Castle castle;
private Army army;
private final Kingdom kingdom = new Kingdom();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can refactor it to

Supplier<Kingdom> kingdomSupplier = Kingdom::new

...

public Kingdom getKingdom() {
    return kingdomSupplier.get();
}

but its upto you

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand why. Can you explain it in more detail?


/**
* Creates kingdom.
*/
public void createKingdom(final KingdomFactory factory) {
setKing(factory.createKing());
setCastle(factory.createCastle());
setArmy(factory.createArmy());
}

King getKing(final KingdomFactory factory) {
return factory.createKing();
}

public King getKing() {
return king;
}

private void setKing(final King king) {
this.king = king;
}

Castle getCastle(final KingdomFactory factory) {
return factory.createCastle();
}

public Castle getCastle() {
return castle;
}

private void setCastle(final Castle castle) {
this.castle = castle;
}

Army getArmy(final KingdomFactory factory) {
return factory.createArmy();
}

public Army getArmy() {
return army;
}

private void setArmy(final Army army) {
this.army = army;
}

/**
* 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.");
}
}
public Kingdom getKingdom() {
return kingdom;
}

/**
Expand All @@ -127,19 +56,33 @@ public static KingdomFactory makeFactory(KingdomType type) {
* @param args command line args
*/
public static void main(String[] args) {

var app = new App();
app.run();
}

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());
@Override
public void run() {
log.info("Elf Kingdom");
createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
log.info(kingdom.getArmy().getDescription());
log.info(kingdom.getCastle().getDescription());
log.info(kingdom.getKing().getDescription());

log.info("Orc Kingdom");
createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
log.info(kingdom.getArmy().getDescription());
log.info(kingdom.getCastle().getDescription());
log.info(kingdom.getKing().getDescription());
}

LOGGER.info("Orc Kingdom");
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
LOGGER.info(app.getArmy().getDescription());
LOGGER.info(app.getCastle().getDescription());
LOGGER.info(app.getKing().getDescription());
/**
* Creates kingdom.
* @param kingdomType type of Kingdom
*/
public void createKingdom(final Kingdom.FactoryMaker.KingdomType kingdomType) {
final KingdomFactory kingdomFactory = Kingdom.FactoryMaker.makeFactory(kingdomType);
kingdom.setKing(kingdomFactory.createKing());
kingdom.setCastle(kingdomFactory.createCastle());
kingdom.setArmy(kingdomFactory.createArmy());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.iluwatar.abstractfactory;

public class Kingdom {

private King king;
private Castle castle;
private Army army;

public King getKing() {
return king;
}

public Castle getCastle() {
return castle;
}

public Army getArmy() {
return army;
}

public void setKing(King king) {
this.king = king;
}

public void setCastle(Castle castle) {
this.castle = castle;
}

public void setArmy(Army army) {
this.army = army;
}

/**
* 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.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,65 +23,71 @@

package com.iluwatar.abstractfactory;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import com.iluwatar.abstractfactory.App.FactoryMaker;
import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

/**
* Test for abstract factory.
*/
public class AbstractFactoryTest {

private final App app = new App();
private KingdomFactory elfFactory;
private KingdomFactory orcFactory;

@BeforeEach
public void setUp() {
elfFactory = FactoryMaker.makeFactory(KingdomType.ELF);
orcFactory = FactoryMaker.makeFactory(KingdomType.ORC);
}

@Test
public void king() {
final var elfKing = app.getKing(elfFactory);
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
final var kingdom = app.getKingdom();

final var elfKing = kingdom.getKing();
assertTrue(elfKing instanceof ElfKing);
assertEquals(ElfKing.DESCRIPTION, elfKing.getDescription());
final var orcKing = app.getKing(orcFactory);

app.createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
final var orcKing = kingdom.getKing();
assertTrue(orcKing instanceof OrcKing);
assertEquals(OrcKing.DESCRIPTION, orcKing.getDescription());
}

@Test
public void castle() {
final var elfCastle = app.getCastle(elfFactory);
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
final var kingdom = app.getKingdom();

final var elfCastle = kingdom.getCastle();
assertTrue(elfCastle instanceof ElfCastle);
assertEquals(ElfCastle.DESCRIPTION, elfCastle.getDescription());
final var orcCastle = app.getCastle(orcFactory);

app.createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
final var orcCastle = kingdom.getCastle();
assertTrue(orcCastle instanceof OrcCastle);
assertEquals(OrcCastle.DESCRIPTION, orcCastle.getDescription());
}

@Test
public void army() {
final var elfArmy = app.getArmy(elfFactory);
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
final var kingdom = app.getKingdom();

final var elfArmy = kingdom.getArmy();
assertTrue(elfArmy instanceof ElfArmy);
assertEquals(ElfArmy.DESCRIPTION, elfArmy.getDescription());
final var orcArmy = app.getArmy(orcFactory);

app.createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
final var orcArmy = kingdom.getArmy();
assertTrue(orcArmy instanceof OrcArmy);
assertEquals(OrcArmy.DESCRIPTION, orcArmy.getDescription());
}

@Test
public void createElfKingdom() {
app.createKingdom(elfFactory);
final var king = app.getKing();
final var castle = app.getCastle();
final var army = app.getArmy();
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ELF);
final var kingdom = app.getKingdom();

final var king = kingdom.getKing();
final var castle = kingdom.getCastle();
final var army = kingdom.getArmy();
assertTrue(king instanceof ElfKing);
assertEquals(ElfKing.DESCRIPTION, king.getDescription());
assertTrue(castle instanceof ElfCastle);
Expand All @@ -92,10 +98,12 @@ public void createElfKingdom() {

@Test
public void createOrcKingdom() {
app.createKingdom(orcFactory);
final var king = app.getKing();
final var castle = app.getCastle();
final var army = app.getArmy();
app.createKingdom(Kingdom.FactoryMaker.KingdomType.ORC);
final var kingdom = app.getKingdom();

final var king = kingdom.getKing();
final var castle = kingdom.getCastle();
final var army = kingdom.getArmy();
assertTrue(king instanceof OrcKing);
assertEquals(OrcKing.DESCRIPTION, king.getDescription());
assertTrue(castle instanceof OrcCastle);
Expand Down