Skip to content
Merged

847 #1517

Show file tree
Hide file tree
Changes from 3 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
5 changes: 5 additions & 0 deletions abstract-factory/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
120 changes: 28 additions & 92 deletions abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@

package com.iluwatar.abstractfactory;

import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
* The Abstract Factory pattern provides a way to encapsulate a group of individual factories that
Expand All @@ -41,105 +40,42 @@
* 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 {
@Slf4j
public class App implements Runnable {

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

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

/**
* 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.");
}
}
}
@Getter
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?


/**
* Program entry point.
*
* @param args command line args
*/
public static void main(String[] args) {

var 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());
@Override
public void run() {
log.info("Elf Kingdom");
createKingdom(Kingdom.FactoryMaker.makeFactory(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.makeFactory(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.
*/
public void createKingdom(final KingdomFactory factory) {
kingdom.setKing(factory.createKing());
kingdom.setCastle(factory.createCastle());
kingdom.setArmy(factory.createArmy());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.iluwatar.abstractfactory;

import lombok.Data;

@Data
public class Kingdom {

private King king;
private Castle castle;
private 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,14 +23,13 @@

package com.iluwatar.abstractfactory;

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 lombok.val;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

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

/**
* Test for abstract factory.
*/
Expand All @@ -42,46 +41,63 @@ public class AbstractFactoryTest {

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

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

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

app.createKingdom(orcFactory);
val orcKing = kingdom.getKing();
assertTrue(orcKing instanceof OrcKing);
assertEquals(OrcKing.DESCRIPTION, orcKing.getDescription());
}

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

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

app.createKingdom(orcFactory);
val orcCastle = kingdom.getCastle();
assertTrue(orcCastle instanceof OrcCastle);
assertEquals(OrcCastle.DESCRIPTION, orcCastle.getDescription());
}

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

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

app.createKingdom(orcFactory);
val 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();
val kingdom = app.getKingdom();

val king = kingdom.getKing();
val castle = kingdom.getCastle();
val army = kingdom.getArmy();
assertTrue(king instanceof ElfKing);
assertEquals(ElfKing.DESCRIPTION, king.getDescription());
assertTrue(castle instanceof ElfCastle);
Expand All @@ -93,9 +109,11 @@ 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();
val kingdom = app.getKingdom();

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