728x90
반응형
Factory Method Pattern
- 객체를 생성을 전담하는 클래스를 만든다.
- 객체생성을 따로 함으로써 유연성을 가진다.
- 장점 OCP 를 지킬수 있다.
- OCP 를 지킬수 있는 이유는 객체를 생성할때 new를 쓰게 되는데 요구사항이 바뀌거나 수정으 해야 하면 손이 많이 가게 된다. 즉 수정이 많아진다.
- 하지만 기존 코드를 수정하지 않고 새로운 유형들 추가할수 있다.
- new 는 팩토리메서드가 전담하기 떄문이다.
Factory Method 구조
- Creator: 추상 클래스
- 추상클래스로 만든이유는 확장성 때문이다. - ConcreteCreator: Creator 를 구현한 구현체
- 실제 factoryMethod 를 통해 Product 를 생성해낸다. - Product: 생성될 아이템의 Intreface
- ConcreateProductor 실제 Item
Factory Method Pattern 예제
- 커피를 만드는 작업을 코드로 짜본다고 하자
- 아메리카노, 디카페인, 콜드브루 등 다양한 종류가 있다.
- 그렇다면 모든 클래스들을 일단 만들고 어떻게 사용할수 있을까?
Factory Method Pattern 예제 구조
- CoffeeFactory: makeCoffee 를 팩토리 메서드로 사용한다.
- CoffeeMachine: CoffeeFactory 를 상속받아 실제 구현부를 만든다.
- Coffee: 다양한 커피들을 만들기 위해 Interface 로 만든다.
Factory Method Pattern 적용 전
- 아래 코드는 OCP 를 위반한다.
- 그 이유는 new 로 생성자를 만들었기 때문이다 새로운 커피가 추가 되면
아래 코드를 수정해야 된다. 만약 여러군데에서 사용한다 하면? 유지보수가 힘들것이다.
Coffee coffee;
if(type == "COLDBREW") {
coffee = new ColdBrew();
} else if (type == "Lattee") {
coffee = new Lattee();
}
...
...
Factory Method Pattern 적용 후
Coffee 관련 코드
CoffeeType
package patterns.factorymethod.coffee;
public enum CoffeeType {
LATTE, COLDEBREW, CAPPUCCINO, JUICE
}
Coffee
package patterns.factorymethod.coffee;
public abstract class Coffee {
public void makeCoffee() {
boilWater();
brew();
addCondiments();
System.out.println("커피제조완료");
}
void boilWater() {
System.out.println("물을 끓인다.");
}
public abstract void brew();
public abstract void addCondiments();
public abstract int getPrice();
}
Cappuccino
package patterns.factorymethod.coffee;
public class Cappuccino extends Coffee {
private int price = 4500;
@Override
void boilWater() {
System.out.println("물을 끓인다.");
}
@Override
public void brew() {
System.out.println("커피를 내린다.");
}
@Override
public void addCondiments() {
System.out.println("우유 + 우유 거품+ 시나몬가루를 추가한다.");
}
@Override
public int getPrice() {
return price;
}
}
ColdBrew
package patterns.factorymethod.coffee;
public class ColdBrew extends Coffee {
private int price = 5000;
@Override
void boilWater() {
System.out.println("물을 끓이지 않는다.");
}
@Override
public void brew() {
System.out.println("찬물을 한방울씩 떨어뜨려 커피를 내린다.");
}
@Override
public void addCondiments() {
System.out.println("따로 추가 하지 않는다.");
}
@Override
public int getPrice() {
return price;
}
}
Factory 관련코드
CoffeeFactory
package patterns.factorymethod;
import patterns.factorymethod.coffee.*;
public abstract class CoffeeFactory {
abstract Coffee makeCoffee(CoffeeType type);
}
CoffeeMachine
package patterns.factorymethod;
import patterns.factorymethod.coffee.*;
public class CoffeeMachine extends CoffeeFactory {
@Override
Coffee makeCoffee(CoffeeType type) {
switch (type) {
case LATTE:
return new Lattee();
case COLDEBREW:
return new ColdBrew();
case CAPPUCCINO:
return new Cappuccino();
default:
throw new IllegalArgumentException("지원하지 않는 메뉴입니다.");
}
}
}
Main 코드
package patterns.factorymethod;
import patterns.factorymethod.coffee.Coffee;
import patterns.factorymethod.coffee.CoffeeType;
public class Main {
public static void main(String[] args) {
CoffeeMachine coffeeMachine = new CoffeeMachine();
Coffee latte = coffeeMachine.makeCoffee(CoffeeType.LATTE);
latte.makeCoffee();
System.out.println("커피가격: "+latte.getPrice());
System.out.println(" ");
Coffee coldBrew = coffeeMachine.makeCoffee(CoffeeType.COLDEBREW);
coldBrew.makeCoffee();
System.out.println("커피가격: "+coldBrew.getPrice());
}
}
결과
물을 끓인다.
커피를 내린다.
우유를 넣는다.
커피제조완료
커피가격: 4300
물을 끓이지 않는다.
찬물을 한방울씩 떨어뜨려 커피를 내린다.
따로 추가 하지 않는다.
커피제조완료
커피가격: 5000
728x90
반응형
'Design pattern > GoF(인강편)' 카테고리의 다른 글
[Design Pattern] Prototype Pattern (0) | 2021.11.24 |
---|---|
[Design Pattern] Singleton Pattern (0) | 2021.11.24 |
[Design Pattern] Template Method Pattern (0) | 2021.11.10 |
[Design Pattern] Adapter Pattern (0) | 2021.10.28 |
[Design Pattern] Strategy Pattern (0) | 2021.10.28 |
댓글