Skip to content

Commit 4450000

Browse files
authored
Merge pull request iluwatar#665 from Tschis/master
(Abstract Factory) Add factory of factories
2 parents 071cde8 + 1427927 commit 4450000

File tree

3 files changed

+79
-10
lines changed

3 files changed

+79
-10
lines changed

abstract-factory/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,45 @@ king.getDescription(); // Output: This is the Elven king!
120120
army.getDescription(); // Output: This is the Elven Army!
121121
```
122122

123+
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.
124+
The client can use FactoryMaker to create the desired concrete factory which, in turn, will produce different concrete objects (Army, King, Castle).
125+
In this example, we also used an enum to parameterize which type of kingdom factory the client will ask for.
126+
127+
```
128+
public static class FactoryMaker {
129+
130+
public enum KingdomType {
131+
ELF, ORC
132+
}
133+
134+
public static KingdomFactory makeFactory(KingdomType type) {
135+
switch (type) {
136+
case ELF:
137+
return new ElfKingdomFactory();
138+
case ORC:
139+
return new OrcKingdomFactory();
140+
default:
141+
throw new IllegalArgumentException("KingdomType not supported.");
142+
}
143+
}
144+
}
145+
146+
public static void main(String[] args) {
147+
App app = new App();
148+
149+
LOGGER.info("Elf Kingdom");
150+
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
151+
LOGGER.info(app.getArmy().getDescription());
152+
LOGGER.info(app.getCastle().getDescription());
153+
LOGGER.info(app.getKing().getDescription());
154+
155+
LOGGER.info("Orc Kingdom");
156+
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
157+
-- similar use of the orc factory
158+
}
159+
```
160+
161+
123162
## Applicability
124163
Use the Abstract Factory pattern when
125164

abstract-factory/src/main/java/com/iluwatar/abstractfactory/App.java

+35-8
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.slf4j.Logger;
2626
import org.slf4j.LoggerFactory;
2727

28+
import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType;
29+
2830
/**
2931
*
3032
* The Abstract Factory pattern provides a way to encapsulate a group of individual factories that have a common theme
@@ -56,7 +58,7 @@ public void createKingdom(final KingdomFactory factory) {
5658
setCastle(factory.createCastle());
5759
setArmy(factory.createArmy());
5860
}
59-
61+
6062
King getKing(final KingdomFactory factory) {
6163
return factory.createKing();
6264
}
@@ -92,9 +94,36 @@ public Army getArmy() {
9294
private void setArmy(final Army army) {
9395
this.army = army;
9496
}
95-
97+
9698
/**
97-
* Program entry point
99+
* The factory of kingdom factories.
100+
*/
101+
public static class FactoryMaker {
102+
103+
/**
104+
* Enumeration for the different types of Kingdoms.
105+
*/
106+
public enum KingdomType {
107+
ELF, ORC
108+
}
109+
110+
/**
111+
* The factory method to create KingdomFactory concrete objects.
112+
*/
113+
public static KingdomFactory makeFactory(KingdomType type) {
114+
switch (type) {
115+
case ELF:
116+
return new ElfKingdomFactory();
117+
case ORC:
118+
return new OrcKingdomFactory();
119+
default:
120+
throw new IllegalArgumentException("KingdomType not supported.");
121+
}
122+
}
123+
}
124+
125+
/**
126+
* Program entry point.
98127
*
99128
* @param args
100129
* command line args
@@ -104,17 +133,15 @@ public static void main(String[] args) {
104133
App app = new App();
105134

106135
LOGGER.info("Elf Kingdom");
107-
app.createKingdom(new ElfKingdomFactory());
136+
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF));
108137
LOGGER.info(app.getArmy().getDescription());
109138
LOGGER.info(app.getCastle().getDescription());
110139
LOGGER.info(app.getKing().getDescription());
111140

112141
LOGGER.info("Orc Kingdom");
113-
app.createKingdom(new OrcKingdomFactory());
142+
app.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC));
114143
LOGGER.info(app.getArmy().getDescription());
115144
LOGGER.info(app.getCastle().getDescription());
116145
LOGGER.info(app.getKing().getDescription());
117-
118146
}
119-
120-
}
147+
}

abstract-factory/src/test/java/com/iluwatar/abstractfactory/AbstractFactoryTest.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
import static org.junit.Assert.assertEquals;
2626
import static org.junit.Assert.assertTrue;
2727

28+
import com.iluwatar.abstractfactory.App.FactoryMaker;
29+
import com.iluwatar.abstractfactory.App.FactoryMaker.KingdomType;
30+
2831
import org.junit.Before;
2932
import org.junit.Test;
3033

@@ -39,8 +42,8 @@ public class AbstractFactoryTest {
3942

4043
@Before
4144
public void setUp() {
42-
elfFactory = new ElfKingdomFactory();
43-
orcFactory = new OrcKingdomFactory();
45+
elfFactory = FactoryMaker.makeFactory(KingdomType.ELF);
46+
orcFactory = FactoryMaker.makeFactory(KingdomType.ORC);
4447
}
4548

4649
@Test

0 commit comments

Comments
 (0)