객체를 생성하는 클래스를 따로 두는 패턴
public class CoffeeFactory {
public Coffee orderCoffee(String type) {
Coffee coffee = createCoffee(type);
coffee.complete();
return coffee;
}
private Coffee createCoffee(String type) {
return switch (type) {
case "Latte" -> new Latte();
case "Americano" -> new Americano();
default -> null;
};
}
}
// 커피 인터페이스
public interface Coffee {
void complete();
void drink();
}
// 라떼
public class Latte implements Coffee {
@Override
public void complete() {
System.out.println("라떼 완성");
}
@Override
public void drink() {
System.out.println("라떼 마시기");
}
}
// 아메리카노
public class Americano implements Coffee {
@Override
public void complete() {
System.out.println("아메리카노 완성");
}
@Override
public void drink() {
System.out.println("아메리카노 마시기");
}
}
// 클라이언트가 커피 공장에서 커피를 주문한다.
public class Demo {
public static void main(String[] args) {
CoffeeFactory coffeeFactory = new CoffeeFactory();
Coffee coffee = coffeeFactory.orderCoffee("Latte");
coffee.drink();
}
}
클래스의 인스턴스를 만드는 일을 서브 클래스에게 맡기는 것
public interface CoffeeFactory {
default Coffee orderCoffee() {
Coffee coffee = createCoffee();
coffee.complete();
return coffee;
}
Coffee createCoffee();
}
public class LatteFactory implements CoffeeFactory {
@Override
public Coffee createCoffee() {
return new Latte();
}
}
public class AmericanoFactory implements CoffeeFactory {
@Override
public Coffee createCoffee() {
return new Americano();
}
}
// 커피 인터페이스
public interface Coffee {
void complete();
void drink();
}
// 라떼
public class Latte implements Coffee {
@Override
public void complete() {
System.out.println("라떼 완성");
}
@Override
public void drink() {
System.out.println("라떼 마시기");
}
}
// 아메리카노
public class Americano implements Coffee {
@Override
public void complete() {
System.out.println("아메리카노 완성");
}
@Override
public void drink() {
System.out.println("아메리카노 마시기");
}
}
// 클라이언트가 커피 공장에서 커피를 주문한다.
public class Demo {
public static void main(String[] args) {
LatteFactory latteFactory = new LatteFactory();
Coffee coffee1 = latteFactory.orderCoffee();
coffee1.drink();
AmericanoFactory americanoFactory = new AmericanoFactory();
Coffee coffee2 = americanoFactory.orderCoffee();
coffee2.drink();
}
}
💡 심플 팩토리에서는 CoffeeFactory가 Latte, Americano 객체를 만들었지만, 팩토리 메소드 패턴에서는 LatteFactory와 AmericanoFactory에서 각각 Latte와 Americano 객체를 만든다.
서로 연관되거나 의존적인 객체들의 조합을 만드는 인터페이스를 제공하는 패턴
👉 아메리카노는 kenya
원두를, 라떼는 normal
원두를 사용한다고 가정하자.
public interface CoffeeFactoryOfFactory {
CoffeeFactory requestCoffee(String type);
}
public class DefaultCoffeeFactoryOfFactory implements CoffeeFactoryOfFactory {
@Override
public CoffeeFactory requestCoffee(String type) {
switch (type) {
case "Latte":
return new LatteFactory();
case "Americano":
return new AmericanoFactory();
}
throw new IllegalArgumentException();
}
}
public interface CoffeeFactory {
Coffee createCoffee();
Bean createBean();
}
public class LatteFactory implements CoffeeFactory {
@Override
public Coffee createCoffee() {
Bean bean = createBean();
bean.putBean();
return new Latte();
}
@Override
public Bean createBean() {
return new NormalBean();
}
}
public class AmericanoFactory implements CoffeeFactory {
@Override
public Coffee createCoffee() {
Bean bean = createBean();
bean.putBean();
return new Americano();
}
@Override
public Bean createBean() {
return new KenyaBean();
}
}
public interface Bean {
void putBean();
}
public class NormalBean implements Bean {
@Override
public void putBean() {
System.out.println("일반 원두");
}
}
public class KenyaBean implements Bean {
@Override
public void putBean() {
System.out.println("케냐 원두");
}
}
public interface Coffee {
void complete();
void drink();
}
public class Latte implements Coffee {
@Override
public void complete() {
System.out.println("라떼 완성");
}
@Override
public void drink() {
System.out.println("라떼 마시기");
}
}
public class Americano implements Coffee {
@Override
public void complete() {
System.out.println("아메리카노 완성");
}
@Override
public void drink() {
System.out.println("아메리카노 마시기");
}
}
public class Demo {
public static void main(String[] args) {
CoffeeFactoryOfFactory coffeeFactoryOfFactory = new DefaultCoffeeFactoryOfFactory();
CoffeeFactory latteFactory = coffeeFactoryOfFactory.requestCoffee("Latte");
Coffee latte = latteFactory.createCoffee();
latte.complete();
latte.drink();
CoffeeFactory americanoFactory = coffeeFactoryOfFactory.requestCoffee("Americano");
Coffee americano = americanoFactory.createCoffee();
americano.complete();
americano.drink();
}
}
💡 CoffeeFactory
에서 Coffee
와 Bean
을 생성할 수 있다. LatteFactory
는 Latte
와 NormalBean
조합으로 객체를 생성할 수 있고, AmericanoFactory
는 Americano
와 KenyaBean
의 조합으로 객체를 생성할 수 있다.
💡 즉, CoffeeFactory
는 Coffee
와 Bean
을 조합하는 구현체를 제공한다.