• 팩토리 메소드 패턴(Factory Method Pattern) :: 마이구미
    디자인 패턴 2017. 12. 5. 21:04
    반응형

    이 글은 팩토리 메소드 패턴(Factory Method Pattern) 을 다룬다.

    디자인 패턴 중 하나로써, 특히 Java 에서 많이 사용하는 패턴 중 하나이다.

    Java 에서는 abstract 를 지원하기 때문에 abstract 를 활용한다.

    그렇기에 이 글에서는 interface 와 abstract 가 동일한 역할을 한다고 가정한다.

    사전 지식으로 interface, abstract 의 개념을 이해하길 바란다.

    interface, abstract - http://mygumi.tistory.com/257


    팩토리 메소드 패턴을 보기에 앞서 팩토리라는 용어가 낯설지 않을 것이라 생각한다.

    오픈 소스나 누군가의 코드에서 이름으로 Factory 를 붙이는 것을 접해봤을 것이다.


    *Factory.get*()

    ex) ProductFactory.getProduct()


    일반적으로 팩토리는 객체 생성을 처리하는 클래스로 사용한다.

    코드로 표현하면 다음과 같다.


    public class SwordFactory {


    public static Sword getWeapon (type) {

    if (type.equals("좋은검") {     return new 좋은검();

    } else if (type.equals("안좋은검") {

    return new 안좋은검();

    } else {

    return null; }

    }


    }


    SwordFactory factory = new SwordFactory();

    Sword goodSword = factory.getWeapon("좋은검");


    위와 같이 new 는 팩토리 클래스 안에서만 사용된다.

    생성된 인스턴스는 static 메소드를 통해 호출한다.

    예로 전사가 원하는 검을 구입하는 것을 클래스 다이어그램으로 표현한다면 다음과 같다.


    간단한 팩토리

     

    단순히 SwordFactory 에서 모든 검을 생성하고 getWeapon 메소드를 통해 인스턴스를 가져온다.

    이렇게 사용하는 이유는 인스턴스 생성에 있어, 여기저기서 사용되는 것을 방지하기 위함이다.

    그로 인해 생성에 대해서는 한 곳에서 관리할 수 있는 이점을 얻을 수 있다.

    이것은 간단한 팩토리(Simple Factory) 라고도 불리지만 디자인 패턴이라고 할 수 없고 관용구에 가깝다.


    그렇다면 팩토리 메소드 패턴은 무엇인가?


    객체를 생성하기 위한 인터페이스를 정의한다.

    이 과정에서 클래스의 인스턴스 생성은 팩토리 메소드를 통해 생성된다.

    클래스 다이어그램으로 표현하면 다음과 같다.


    팩토리 메소드 패턴


    그림에서 보듯이 팩토리 메소드는 인터페이스에서 정의되고 서브클래스에서 구현된다.

    서브클래스에서 구현된 팩토리 메소드는 인스턴스를 생성하는데 사용된다.

    인스턴스 생성을 서브클래스에게 맡기는 것이라고 볼 수 있다.


    팩토리 메소드 패턴는 어떻게 사용되는 건가?


    간단한 팩토리에서 예시에서 검의 종류가 소검, 중검, 대검으로 나뉜다고 생각해보자.

    검을 제조하는 공장에서는 검을 쇠를 녹이는 과정, 칼을 가는 과정 등은 같지만 생성에 있어서 구현 방식이 달라지게 될 것이다.

    결론은 동일한 과정은 유지하면서, 나누어진 검의 고유의 스타일을 가져가야한다.

    다음과 같은 클래스 다이어그램으로 나타낼 수 있다.


    팩토리 메소드 패턴

    팩토리 메소드 패턴의 장점은 무엇인가?


    위에서 루트 클래스가 아닌 서브클래스로 인해 인스턴스가 결정된다고 했다. (루트 클래스는 어떤 인스턴스가 생성되었는지 모른다)

    이로 인해 생성되는 객체는 자연스럽게 슐화된다.


    간단한 팩토리처럼 객체를 한 곳에서 관리할 수 있다.


    구상 클래스에 의존하지 않고 추상화된 것에 의존한다. (디자인 원칙 준수)


    객체는 인터페이스에서 정의한 팩토리 메소드를 통해 생성되기 때문에 동일한 인터페이스를 준수한다.

    인터페이스를 바탕으로 하기 때문에 유연성과 확장성 등 관리하기에 좋다.


    결국 이것들은 하나의 결론을 풀어놓은 거라 볼 수 있다.

    결론은 의존 관계 역전 원칙(Dependency inversion principle) 을 성립하게 된다.

    즉, 상위와 하위 객체는 구상 클래스에 의존하지 않고, 모두 동일한 추상화에 의존하게 되어 원칙을 성립하게 된다.


    예시로 든 클래스 다이어그램은 다음과 같은 관계를 가지게 된다.

    SwordFactory -> Sword

    Sword <- Asword, Bsword, Csword....

    반응형

    댓글

Designed by Tistory.