Free Lines Arrow
본문 바로가기
Design pattern/GoF(인강편)

[Design Pattern] Factory Method Pattern

by skahn1215 2021. 11. 24.
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
반응형

댓글