팩토리 메소드 패턴

Lee yun bok·2021년 8월 22일
0

디자인 패턴

목록 보기
1/1
post-thumbnail

new 연산자의 모순

new를 사용하는 것은 구현 클래스의 인스턴스를 생성하는 것인데 그러면 유연하지 못한 것 아닐까? 특정 구현을 의존하게 되면 코드를 나중에 수정해야할 것이 필연적이고, 결국에는 유연성이 떨어지게 된다.

만약에 일련의 조건에 따라 다양한 구현 클래스를 가져와야 한다면 다음과 같은 코드를 확인할 수 있게 된다.

if( a ) return new A();
else if ( b ) return new B(); 
else if ( c ) return new C(); 

특정 조건에 따라 특정 구현을 반환하는 구조라면, 변경하거나 확장해야 할 때 코드를 다시 확인하고 추가 또는 제거를 해야한다는 것을 의미한다. 결국에는 변경에 자유롭지 못하다. 물론 new는 단순히 자바에서 필연적으로 사용해야 하는 것이므로 사용하지 않을 수는 없다. 그렇다면 결국 변경에 따른 영향을 최소화 해야 한다.

위와 같은 문제를 해결해줄 수 있는 디자인 패턴이 바로 팩토리 메소드 패턴 이다.

객체 생성을 캡슐화 해주는 팩토리 메소드 패턴

팩토리 메소드 패턴이란?

팩토리 메소드 패턴에서는 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브 클래스에서 결정한다. 팩토리 메소드 패턴을 이용하게 되면 클래스의 인스턴스를 만드는 일을 서브클래스에게 맡긴다.

여기서 “서브 클래스에서 결정한다”라는 의미는 서브 클래스에서 진짜 결정한다는 의미가 아니라 메인 클래스에서는 어떠한 클래스의 인스턴스가 만들어지는지 전혀 모른다는 의미이다.

질문 : 구현 클래스의 종류가 별로 없다면 사용하지 않아도 되지 않나요?
주요 로직과 구현 클래스를 생성하는 부분을 분리시켜 느슨하게 관리한다면 후에 새로운 클래스가 추가 되더라도, 단순히 팩토리만 수정하면 된다.

질문 : 결국에 팩토리에서 구현 클래스를 의존하게 되지 않나요?
구현 클래스의 인스턴스를 생성하는 것은 어쩔 수 없다. 자바의 매커니즘이기 때문이다. 대신 구현 클래스의 인스턴스를 하나의 클래스에서 모두 관리함으로써 변경이나 확장에 유연한 구조로 만들어줄 수 있다.

직접 구현 해보자

PizzaStore.java

public abstract class PizzaStore {

    public Pizza orderPizza(String type) {
        Pizza pizza;

        pizza = createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }

    protected abstract Pizza createPizza(String type);
}

메인 로직을 가지고 있는 추상 클래스 PizzaStore 이다. PizzaStore는 자신이 무슨 구현 객체를 사용하게 되는지 알지 못한다. PizzaStore의 역할은 단순히 피자를 주문 받아, 요리하고 손님에게 전달하는 것이다.

NYPizzaStore.java

public class NYPizzaStore extends PizzaStore {

    @Override
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")) {
            return new NYStyleCheesePizza();
        }
        else if (type.equals("clam")) {
            return new NYStyleClamPizza();
        }
        else return null; 
    }
}

PizzaStore를 상속받은 뉴옥에 위치한 피자집을 나타낸 구현 클래스 NYPizzaStore이다. NYPizzaStorePizzaStore 대신 구현 객체를 선택하는 역할을 담당하고 있다.

위와 같이 구현 클래스의 인스턴스를 생성하는 역할을 NYPizzaStore에 캡슐화 함으로써 변경에 유연한 코드를 완성시킬 수 있다.

출처
Head First Design Patterns - (에릭 프리먼, 엘리자베스 프리먼, 케이시 시에라, 비트 베이츠) 을 보며 정리한 내용입니다.

profile
https://ybdeveloper.tistory.com/ 로 이동했습니다 : )

0개의 댓글