인프런 커뮤니티 질문&답변

bnamkung님의 프로필 이미지
bnamkung

작성한 질문수

CS 지식의 정석 | 디자인패턴 네트워크 운영체제 데이터베이스 자료구조

팩토리패턴 ★★★

팩토리 예시 질문

작성

·

114

·

수정됨

0

안녕하세요!

팩토리패턴 수업 5:00에 생성부분에 로직 변화가 있으면 coffee와 그 subclass만 수정하만 된다고 얘기했는데요. java 예시에서는 CoffeeFactory안에 switch문이 있어서 새로운 커피가 추가될 때마다 switch문의 내용을 바꿔줘야되는데, 이 정도 수정사항은 팩토리 디자인 원칙에 벗어나지 않는건가요?

감사합니다.

답변 1

1

큰돌님의 프로필 이미지
큰돌
지식공유자

안녕하세요 bnamkung님 ㅎㅎ

이 정도 수정사항은 팩토리 디자인 원칙에 벗어나지 않는건가요?

>> 네 맞습니다.

"객체 생성에 관해 변경되는 로직"이 발생했을 때 CoffeeFactory가 아니라 Latte나 Espresso 클래스에서만 수정하면 되기 때문에 위배되지 않습니다.

물론 팩토리 메서드 내부에서 새로운 객체 타입이 추가될 때마다 switch 문을 수정해야 하므로 이부분 때문에 객체 생성의 확장성을 제한한다고는 할 수 있습니다.

이를 개선하는 방법은 Map을 사용하는 것인데요.

예를 들어 Cafemocha를 추가한다면 다음과 같이 switch 없이 추가할 수 있습니다.

다음 코드처럼 static부분에 map에 해당 키와 값을 추가하는 put 메소드만으로 이를 처리할 수 있습니다.

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

enum CoffeeType {
    LATTE,
    ESPRESSO,
    CAFEMOCHA  
}

abstract class Coffee {
    protected String name;

    public String getName() {
        return name;
    }
}

class Latte extends Coffee {
    public Latte() {
        name = "latte";
    }
}

class Espresso extends Coffee {
    public Espresso() {
        name = "Espresso";
    }
}

class Cafemocha extends Coffee {
    public Cafemocha() {
        name = "Cafemocha";
    }
}

class CoffeeFactory {
    private static final Map<CoffeeType, Supplier<Coffee>> coffeeMap = new HashMap<>();

    static {
        coffeeMap.put(CoffeeType.LATTE, Latte::new);
        coffeeMap.put(CoffeeType.ESPRESSO, Espresso::new);
        coffeeMap.put(CoffeeType.CAFEMOCHA, Cafemocha::new);  
    }

    public static Coffee createCoffee(CoffeeType type) {
        Supplier<Coffee> coffee = coffeeMap.get(type);
        if (coffee != null) {
            return coffee.get();
        }
        throw new IllegalArgumentException("Invalid coffee type: " + type);
    }
}

public class Main {
    public static void main(String[] args) {
        Coffee latte = CoffeeFactory.createCoffee(CoffeeType.LATTE);
        System.out.println(latte.getName()); // latte

        Coffee espresso = CoffeeFactory.createCoffee(CoffeeType.ESPRESSO);
        System.out.println(espresso.getName()); // Espresso

        Coffee cafemocha = CoffeeFactory.createCoffee(CoffeeType.CAFEMOCHA);
        System.out.println(cafemocha.getName()); // Cafemocha
    }
}



또 질문 있으시면 언제든지 질문 부탁드립니다.

좋은 수강평과 별점 5점은 제게 큰 힘이 됩니다. :)

감사합니다.

강사 큰돌 올림.


bnamkung님의 프로필 이미지
bnamkung

작성한 질문수

질문하기