Skip to content

Commit 017e04d

Browse files
authored
Implement the Creational Design Patterns (#3)
* Implement the Factory Method Design Pattern * Implement the Abstract Factory Design Pattern * Implement the Builder Design Pattern * Implement the Object Pool Design Pattern * Implement the Prototype Design Pattern * Implement the Singleton Design Pattern
1 parent c0f0702 commit 017e04d

31 files changed

+737
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package practice.creational.builder;
2+
3+
import practice.creational.builder.CustomPizza.PizzaChef;
4+
import practice.creational.builder.PizzaElement.DoughType;
5+
import practice.creational.builder.PizzaElement.SauceType;
6+
import practice.creational.builder.PizzaElement.ToppingType;
7+
8+
/**
9+
* Example of Builder Design Pattern
10+
*/
11+
public final class BuilderDemo {
12+
13+
public static void main(final String... arguments) {
14+
15+
new PizzaChef(DoughType.BAKED).setSauceType(SauceType.HOT)
16+
.setTopping(ToppingType.CAPSICUM_MUSHROOM).cookPizza().eatPizza();
17+
18+
new PizzaChef(DoughType.CROSS).setSauceType(SauceType.MILD)
19+
.setTopping(ToppingType.CHEESE_CORN_TOMATO).cookPizza().eatPizza();
20+
}
21+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package practice.creational.builder;
2+
3+
import lombok.AccessLevel;
4+
import lombok.EqualsAndHashCode;
5+
import lombok.NonNull;
6+
import lombok.RequiredArgsConstructor;
7+
import lombok.Setter;
8+
import lombok.ToString;
9+
import lombok.experimental.Accessors;
10+
import lombok.extern.java.Log;
11+
12+
@Log
13+
@ToString
14+
@EqualsAndHashCode
15+
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
16+
public final class CustomPizza {
17+
18+
@NonNull
19+
private final PizzaElement.DoughType doughType;
20+
@NonNull
21+
private final PizzaElement.SauceType sauceType;
22+
@NonNull
23+
private final PizzaElement.ToppingType topping;
24+
25+
public void eatPizza() {
26+
log.info("EATING Pizza => " + this);
27+
}
28+
29+
@Setter
30+
@ToString
31+
@EqualsAndHashCode
32+
@RequiredArgsConstructor
33+
@Accessors(chain = true)
34+
protected static final class PizzaChef {
35+
36+
@NonNull
37+
private final PizzaElement.DoughType doughType;
38+
39+
private PizzaElement.SauceType sauceType;
40+
private PizzaElement.ToppingType topping;
41+
42+
public CustomPizza cookPizza() {
43+
log.info("COOKING Pizza => " + this); // In OVEN
44+
return new CustomPizza(doughType, sauceType, topping);
45+
}
46+
}
47+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package practice.creational.builder;
2+
3+
import lombok.EqualsAndHashCode;
4+
import lombok.ToString;
5+
6+
@ToString
7+
@EqualsAndHashCode
8+
public final class PizzaElement {
9+
10+
protected enum DoughType {
11+
12+
BAKED, CROSS
13+
}
14+
15+
protected enum SauceType {
16+
17+
HOT, MILD
18+
}
19+
20+
protected enum ToppingType {
21+
22+
CAPSICUM_MUSHROOM, CHEESE_CORN_TOMATO
23+
}
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package practice.creational.factory;
2+
3+
import lombok.EqualsAndHashCode;
4+
import lombok.NonNull;
5+
import lombok.RequiredArgsConstructor;
6+
import lombok.ToString;
7+
import lombok.extern.java.Log;
8+
9+
@Log
10+
@ToString
11+
@EqualsAndHashCode
12+
@RequiredArgsConstructor
13+
public final class BronzeCoin implements MetalCoin {
14+
15+
private static final Integer PRINCIPAL_COST = 2_500;
16+
17+
@NonNull
18+
private final Float demandFactor; // Price MULTIPLIER
19+
20+
@Override
21+
public void printWorth() {
22+
final var value = (PRINCIPAL_COST * demandFactor) + " INR";
23+
log.info("Monetary WORTH of BRONZE Coin => " + value);
24+
}
25+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package practice.creational.factory;
2+
3+
import lombok.EqualsAndHashCode;
4+
import lombok.NonNull;
5+
import lombok.extern.java.Log;
6+
7+
@Log
8+
@EqualsAndHashCode
9+
public abstract sealed class CoinFactory permits MassFactory, RareFactory {
10+
11+
protected abstract Float getDemandFactor(); // Get SPECIFIC multiplier
12+
13+
public MetalCoin mintCoin(@NonNull final CoinType coinType) {
14+
var mintedCoin = coinType.getCreator().apply(getDemandFactor());
15+
log.info("CATEGORY of Minted COIN => [" + mintedCoin + "]");
16+
return mintedCoin; // Return the SPECIFIC category of minted COIN
17+
}
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package practice.creational.factory;
2+
3+
import java.util.function.Function;
4+
import lombok.Getter;
5+
import lombok.NonNull;
6+
import lombok.RequiredArgsConstructor;
7+
8+
@Getter
9+
@RequiredArgsConstructor
10+
public enum CoinType {
11+
12+
BRONZE(BronzeCoin::new), // Holds CONSTRUCTOR
13+
SILVER(SilverCoin::new); // Holds CONSTRUCTOR
14+
15+
@NonNull
16+
private final Function<Float, MetalCoin> creator;
17+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package practice.creational.factory;
2+
3+
import java.util.List;
4+
5+
/**
6+
* Example of Factory Method Design Pattern
7+
*/
8+
public final class FactoryDemo {
9+
10+
public static void main(final String... arguments) {
11+
12+
createCoinMints().forEach(coinFactory -> {
13+
coinFactory.mintCoin(CoinType.BRONZE).printWorth();
14+
coinFactory.mintCoin(CoinType.SILVER).printWorth();
15+
});
16+
}
17+
18+
private static List<CoinFactory> createCoinMints() {
19+
return List.of(new MassFactory(), new RareFactory());
20+
}
21+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package practice.creational.factory;
2+
3+
import lombok.NoArgsConstructor;
4+
import lombok.NonNull;
5+
import lombok.ToString;
6+
import lombok.extern.java.Log;
7+
8+
@Log
9+
@ToString
10+
@NoArgsConstructor
11+
public final class MassFactory extends CoinFactory {
12+
13+
private static final Float DEMAND_FACTOR = 1.2F;
14+
15+
@Override
16+
protected Float getDemandFactor() {
17+
return DEMAND_FACTOR;
18+
}
19+
20+
@Override
21+
public MetalCoin mintCoin(@NonNull final CoinType coinType) {
22+
log.info("Current FACTORY for MINT => [" + this + "]");
23+
return super.mintCoin(coinType); // Get CURRENT minted COIN
24+
}
25+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package practice.creational.factory;
2+
3+
public sealed interface MetalCoin permits BronzeCoin, SilverCoin {
4+
5+
void printWorth(); // Prints monetary WORTH of minted Metal COIN
6+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package practice.creational.factory;
2+
3+
import lombok.NoArgsConstructor;
4+
import lombok.NonNull;
5+
import lombok.ToString;
6+
import lombok.extern.java.Log;
7+
8+
@Log
9+
@ToString
10+
@NoArgsConstructor
11+
public final class RareFactory extends CoinFactory {
12+
13+
private static final Float DEMAND_FACTOR = 4.8F;
14+
15+
@Override
16+
protected Float getDemandFactor() {
17+
return DEMAND_FACTOR;
18+
}
19+
20+
@Override
21+
public MetalCoin mintCoin(@NonNull final CoinType coinType) {
22+
log.info("Current FACTORY for MINT => [" + this + "]");
23+
return super.mintCoin(coinType); // Get CURRENT minted COIN
24+
}
25+
}

0 commit comments

Comments
 (0)