[디자인패턴] 추상 팩토리

Foo·2022년 3월 24일

Design Pattern

목록 보기
2/3
post-thumbnail

Abstract Factory

배경

추상 팩토리는 생성적 디자인 패턴으로, 구체적인 자식 클래스 명시 없이 연관된 객체 그룹을 생성하게 한다. 팩토리에서의 Product가 한 종류에서 여러개로 늘어났다고 생각하면 된다.

  • 팩토리 : 한개의 그룹
    ex. Transport -> Ship, Truck..
  • 추상 팩토리 : 여러개의 그룹
    ex. Chair->ModernChair, VictorianChair
    Sofa->ModernSofa, VictorianSofa

💀 문제 정의

가구가게를 생각해보자. 가구가게 어플리케이션이 제공해야하는 product들은 :

  1. 연관된 상품 그룹 : 의자 + 소파 + 커피테이블
  2. 각 상품 그룹의 다양한 버전 : Modern, Victorian, ArtDeco

고객이 이미 가지고 있는 버전에 맞는 가구를 제공해야함
ex. 이미 Modern 의자와 소파가 있는데 한개만 Victorian이면 안됨.

새로운 상품이나 연관 상품들을 프로그램에 추가할 때마다 기존의 핵심 코드를 매번 변경하고 싶지 않다.

😊 해결방안

추상팩토리 패턴을 사용해보자.


위 사진처럼 소파와 커피테이블도 같은 구조를 따를 것이다.

하나의 가구팩토리에는 연관된 가구 그룹을 생성하는 팩토리 메소드들이 있다. 가구팩토리 인터페이스를 구현한 자식 팩토리들은 하나의 버전으로 묶인 가구들을 생성해낸다.
VictorianFurnitureFactory는 Victorian 버전만, ModernFurnitureFactory는 Modern 버전의 가구만 생성한다.

가구를 제공할 때 클라이언트는 팩토리 안에 무슨 팩토리가 있는지, 그 팩토리에서 무슨 버전의 가구를 생성하는지 관심없다. 만약 의자를 생성하고 싶다면, 팩토리의 createChair 메소드를 호출한다. 그 의자가 무슨 버전인지 상관 없이 모두 추상화된 의자 인터페이스를 통해 다룬다. 클라이언트가 보게 되는 것은 오직 의자의 메소드인 sitOn이다.

하지만 추상화된 인터페이스로 비즈니스 로직을 구성한다 하더라도, 결국에 처음에는 조건에 따라 버전별로 팩토리를 생성하는 부분이 있어야 한다. 무엇이 팩토리 객체를 만드는가? 통상적으로, 앱의 초기화 단계에서 추상팩토리를 구현한 자식팩토리들을 생성한다.

🧱 구조

  1. Abstract Products : 의자, 소파, 커피테이블 등을 정의

  2. Concrete Products : 각 가구의 여러가지 버전. 의자의 A버전, B버전, 소파의 A버전, B버전 등.

  3. The Abstract Factory : 각 abstract product를 생성하는 메소드들이 존재함

  4. Concrete Factories : 추상 팩토리의 생성 메소드를 구현함. 각 concrete factory는 product의 한 버전에 대응하고 오직 그 버전의 product들만 생성함.

    ex VictorianFactory에서는 Victorian 가구만 생성.

  5. 비즈니스 로직을 담은 Client Code : Client는 추상 인터페이스들을 통해 모든 concrete factory/product와 상호작용한다.

🙋 언제 사용해요?

  • 여러 버전의 연관 상품들을 다뤄야 하지만 각각 버전의 상품들로부터 최대한 독립적이고 싶을 때! 혹은 어떻게 될 지 몰라서 미래의 확장성을 고려하고 싶을 때

🔪 장단점

장점

  • 하나의 팩토리에서 반환된 상품들을 서로 호환된다.
  • client code와 product의 여러가지 버전이 서로 독립적이다.
  • Single Responsibility Principle(SRP). product 생성부분을 떼어내어서 유지보수가 쉬워진다.
  • Open/Closed Principle(OCP). 최소화의 수정으로 최대한의 확장 가능.

단점

  • 버전이 너무 많아지면 상품의 자식클래스들과 인터페이스가 많아지면서 코드의 복잡성 증가.

📝 질문 및 고찰

결국에는 (버전)X(추상 product 개수)만큼의 클래스를 정의해야하는데, 버전이 유한개가 아니거나 특정지어지지 않은 경우에는 어떻게 해야할까?🧐

참고

Refactoring Guru

profile
천천히, 꾸준히, 겸손히

0개의 댓글