Skip to content

Factory (2) - Factory method #8

@simoniful

Description

@simoniful

Factory method 패턴은 실제로 인스턴스를 생성하는 메서드를 가진 인터페이스를 정의하지만, 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 하위 클래스(factory)가 정하도록 하는 방법입니다. 간단하게 말해서 객체 생성을 서브 클래스가 하도록 처리하는 패턴입니다. 즉 객체 생성을 캡슐화할 수 있으며 이로 인해 부모 클래스는 자식 클래스가 어떤 객체를 생성하는지 몰라도 됩니다.

  • Product: Creator와 하위 클래스가 생성할 수 있는 모든 객체에 동일한 인터페이스를 선언.
  • Concreate Product: Product가 선언한 인터페이스로 만든 실제 객체, 인스턴스.
  • Creator: 새로운 객체를 반환하는 factory method를 선언. 여기서 반환하는 객체는 Product 인터페이스를 항상 준수.
  • Concrete Creator: 기본 factory method를 override 하여 서로 다른 Product 객체를 생성.

"Factory method"라는 이름이 붙은 이유는 여러 factory들을 하나로 추상화하고 인스턴스의 생성을 담당하는 메서드를 추상화하는 것을 주요한 전략으로 사용하기 때문입니다.

사용

만약 우리가 상황에 따라 여러 구체적인 타입의 ConcreteProduct의 인스턴스를 생성하고 싶다면, Product로 타입들을 추상화하고, 이 인스턴스의 생성을 Creator 타입을 준수하는 Concrete Creator(Factory)에게 맡깁니다. 인스턴스의 생성은 Creator를 따르는 하위 계층의 클래스인 ConcreteCreator에서 진행 됩니다.

예를 들어 음악 재생 앱을 만들었다고 합시다. 처음 앱을 만들 땐 MusicPlayer라는 객체를 통해 음악만 재생 가능한 앱을 만들었는데, 비디오도 재생이 가능하도록 구성해야 상황입니다. 현재 음악만 재생할 수 있도록 만든 MusicPlayer만 있었기 때문에 만약 VideoPlayer를 추가하려고 한다면 코드 전체를 수정해야합니다. 나중에 VR Player, AR Player 등과 같은 기능들이 추가된다면 추가 될 때 마다 코드 전체를 수정해야하는 문제가 생깁니다.
 
이럴 때 사용할 수 있는 것이 Factory method 패턴입니다. 객체를 직접 만드는 것이 아닌 factory method를 통해서 생성합니다. MusicPlayer가 필요한 곳에서는 MusicPlayer를 생성하는 메서드를 호출하고 VideoPlayer가 필요한 곳에서는 VideoPlayer를 생성하는 메서드를 호출하는 거죠.
 
이렇게 된다면 새로운 유형의 Player를 만들어야 한다고 하더라도 팩토리 부분에 메서드를 추가해서 간단하게 처리할 수 있습니다. 하지만 각각의 Player들은 서로 다른 콘텐츠를 취급하더라도 궁극적인 기능은 같기 때문에 동일한 인터페이스를 사용해야 할 거예요. 또한, 기존 객체에 수정이 생기더라도 factory method만 수정하면 됩니다.

주의 사항

Factory method 패턴 구성에 있어서는 확장성을 염두에 두고 구조를 설계하는 것이 중요합니다. 엔티티에서 전달된 데이터를 통해서 객체를 구성(DTO)하는 경우에 있어서도 어떤 목적으로 Type-familly 군을 구체화하여 사용할 수 있는 여부에 대해서도 고민해봐야 합니다. 즉, 추상화와 그룹화 관련하여 활용 방안을 말합니다. 또한 인스턴스 생성에 대한 의존성이 없어졌기 때문에 런타임에 새로운 팩토리를 주입해서 인스턴스 생성을 위한 다른 전략을 선택할 수 있기에 확장적인 부분에서도 고려해야 합니다.

정리

  • Factory 패턴은 factory라는 인스턴스를 생성하는 객체를 따로 두는 기법입니다.
  • Factory method 패턴은 이 factory를 추상화하고 factory method 에 대한 인터페이스를 제공해서 구현체가 어떤 인스턴스를 어떻게 생성할지 결정하게 하는 디자인 패턴입니다.
  • 인터페이스 구성에 있어서 추상화, 그룹화에 대해 고민하여 작성해야 합니다.
  • 인스턴스 생성에 대한 의존성 분리와 factory의 유형별 활용을 고려한다면 보다 구분된 수준의 코드를 작성하는 것이 가능합니다.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions