[Design Pattern] Factory Method

KIM KYUBIN·2023년 2월 7일
0

Design Pattern

목록 보기
1/1

정의

부모 클래스에서 객체들을 생성할 수 있는 인터페이스를 제공
자식 클래스들이 생성될 객체들의 유형을 변경할 수 있도록 하는 생성 패턴

문제 예시

🚛 물류 관리 앱 개발

  • 첫 번째 버전은 대부분의 코드가 Truck 클래스에 있다.
  • 해상 물류 기능을 담당하는 Ship 클래스를 추가해야 한다.
    => 하지만, 추가하려면 전체 코드 베이스를 변경해야 한다.

해결책

new 연산자를 사용한 객체 생성 호출들을 특별한 팩토리 메서드에 대한 호출들로 대체

팩토리 메서드에서 반환된 객체 => Product

  • 자식 클래스에서 팩토리 메서드를 오버라이딩하고 그 메서드에 의해 생성되는 제품들의 클래스를 변경 가능
  • 하지만, 모든 제품들은 같은 인터페이스를 따라야 한다.

🚛 TruckShip 클래스들은 모두 Transport 인터페이스를 구현해야 하며, deliver 메서드를 선언

🚛 RoadLogistics 클래스에 포함된 팩토리 메서드는 Truck 객체들을 반환
SeaLogistics 클래스에 포함된 팩토리 메서드는 Ship 객체들을 반환

구조

  1. Product는 인터페이스를 선언

  2. ConcreteProduct들은 Product 인터페이스의 구현체들

  3. Creator 클래스는 새로운 Product 객체들을 반환하는 팩토리 메서드 선언
    => 팩토리 메서드의 반환 타입이 Product와 일치해야 한다.

🔥 팩토리 메서드를 abstract으로 선언하여 모든 자식 클래스들이 각각 자체 버전들을 구현하도록 강제 가능

🔥 또는, 기본 팩토리 메서드가 디폴트 제품 타입을 반환하도록 가능

🔥 Creator의 책임은 Product를 생성하는 것이 아니다.
=> 핵심 비즈니스 로직을 Product 클래스들로부터 분리하는데 도움을 줄 뿐

  1. ConcreteCreator들은 기본 팩토리 메서드를 오버라이드하여 다른 타입의 Product를 반환

적용

🌞 코드가 함께 작동해야 하는 객체들의 정확한 타입과 의존 관계를 모르는 경우 사용

Product 생성 코드를 Product를 실제로 사용하는 코드와 분리
=> Product 생성 코드를 나머지 코드와 독립적으로 확장하기 쉬워진다

🌞 라이브러리 또는 프레임워크 사용자들에게 내부 컴포넌트를 확장하는 방법을 제공하고 싶을 때 사용

⭐ 프레임워크에서 컴포넌트 생성 코드를 단일 팩토리 메서드로 줄인 후, 누구나 오버라이드 할 수 있도록 만든다.

🌞 기존 객체들을 매번 재구축하는 대신 이들을 재사용하여 시스템 리소스를 절약하고 싶을 때 사용

구현 방법

🎯 모든 Product가 같은 인터페이스를 구현하도록 하자

🎯 Creator 클래스 내부에 팩토리 메서드 추가
=> 반환 타입은 Product 인터페이스

🎯 Creator에서 Product 생성에 대한 모든 참조를 찾아라
=> 참조들을 팩토리 메소드에 대한 호출로 교체하면서 Product 생성 코드를 팩토리 메서드로 추출

🎯 팩토리 메서드에 나열된 각 Product 타입에 대한 Creator 자식 클래스들의 집합을 생성한 후, 자식 클래스들에서 팩토리 메서드를 오버라이딩하고 기본 메서드에서 생성 코드의 적절한 부분을 추출하라

🎯 Product 타입이 너무 많아 모든 Product에 대하여 자식 클래스를 만드는 것이 합리적이지 않을 경우, 자식 클래스들의 기본 클래스의 제어 매개변수를 재사용 가능

🎯 추출이 끝난 후 기본 팩토리 메서드가 비어 있으면, 해당 팩토리 메서드를 추상화 가능
=> 비어 있지 않으면, 나머지를 그 메서드의 디폴트로 만들 수 있다

장단점

👍 CreatorProduct가 느슨한 결합이 되도록 할 수 있다.

👍 단일 책임 원칙(SRP)
=> Product 생성 코드를 별도의 위치로 이동하여 코드를 더 쉽게 유지관리 가능

👍 개방 / 폐쇄 원칙(OCP)
=> 기존 클라이언트 코드를 훼손하지 않고 새로운 타입의 Product들을 프로그램에 도입 가능

👎 패턴을 구현하기 위해 많은 자식 클래스들을 만들어야 하므로 코드가 더 복잡해질 수 있다
=> 가장 좋은 방법은 Creator 클래스들의 기존 계층 구조에 패턴을 도입하는 것

다른 패턴과의 관계

😐 추상 팩토리, 프로토타입, 빌더 패턴으로 발전

😐 추상 팩토리 클래스는 팩토리 메서드의 집합을 기반으로 하는 경우가 많다

😐 프로토타입을 사용하여 추상 팩토리의 구현 클래스들의 생성 메서드들을 구현할 수도 있다

😐 팩토리 메서드를 반복자 패턴과 함께 사용하여 자식 클래스들이 해당 컬렉션들과 호환되는 다양한 타입의 반복자들을 반환하도록 할 수 있따

😐 프로토타입은 상속을 하지않지만 복제된 객체의 복잡한 초기화가 필요하다
=> 팩토리 메서드는 상속을 하지만 초기화 단계가 필요없다

😐 팩토리 메서드는 템플릿 메서드의 특수화
=> 대규모 템플릿 메서드의 한 역할을 팩토리 메서드가 할 수 있다

참조

https://refactoring.guru/ko/design-patterns/factory-method

profile
상상을 현실로 만들기 위해 노력하는 개발자

0개의 댓글