Skip to content

abstract-factory-pattern

TL; DR

  • 상세한 서브 클래스를 정의하지 않고도 서로 관련이 있거나 독립적인 여러 객체 군을 생성하기 위한 인터페이스를 제공

활용성

  • 객체가 생성되거나 구성, 표현되는 방식과 무관하게 시스템을 독립적으로 만들고자 할 때
  • 여러 제품군 중 하나를 선택하여 시스템을 설정해야 하고, 한 번 구성한 제품군을 다른 것으로 대체할 수 있어야 할 때
  • 제품에 대한 클래스 라이브러리를 제공하고, 그들의 구현이 아닌 인터페이스를 노출하고자 할 때

결과

  • 장점
    • 구체적인 클래스를 분리 : 응용 프로그램이 생성할 객체를 제어할 수 있음. 일반 프로그램은 구체적인 클래스를 사용하지 않고 추상 팩토리의 인터페이스를 통해 객체를 생성
    • 제품군을 쉽게 대체 : 추상 팩토리를 사용하면 제품군을 쉽게 대체할 수 있음
    • 제품군 사이의 일관성 : 제품군 내의 객체들이 함께 사용될 때 일관성을 유지할 수 있품
  • 비용
    • 새로운 제품 추가가 어려움 : 새로운 종류의 제품을 추가하려면 팩토리 클래스를 추가해야 함

구현

  • 팩토리를 싱글톤으로 정의 : 하나의 제품군에 대해서는 하나의 팩토리만 있으면 됨
  • 제품을 생성 : Abstract Factory 는 인터페이스만 정의하고, 구체 팩토리를 통해서 제품을 생성하도록 함

예시

from abc import ABC, abstractmethod

# 추상 제품 클래스들
class Chair(ABC):
    @abstractmethod
    def sit_on(self):
        pass

class Table(ABC):
    @abstractmethod
    def put_on(self):
        pass

# 구체적인 제품 클래스들
class ModernChair(Chair):
    def sit_on(self):
        return "모던 의자에 앉았습니다."

class VintageChair(Chair):
    def sit_on(self):
        return "빈티지 의자에 앉았습니다."

class ModernTable(Table):
    def put_on(self):
        return "모던 테이블 위에 물건을 올려놓았습니다."

class VintageTable(Table):
    def put_on(self):
        return "빈티지 테이블 위에 물건을 올려놓았습니다."

# 추상 팩토리 클래스
class FurnitureFactory(ABC):
    @abstractmethod
    def create_chair(self) -> Chair:
        pass

    @abstractmethod
    def create_table(self) -> Table:
        pass

# 구체적인 팩토리 클래스들
class ModernFurnitureFactory(FurnitureFactory):
    def create_chair(self) -> Chair:
        return ModernChair()

    def create_table(self) -> Table:
        return ModernTable()

class VintageFurnitureFactory(FurnitureFactory):
    def create_chair(self) -> Chair:
        return VintageChair()

    def create_table(self) -> Table:
        return VintageTable()

# 클라이언트 코드
def client_code(factory: FurnitureFactory) -> None:
    chair = factory.create_chair()
    table = factory.create_table()

    print(chair.sit_on())
    print(table.put_on())

# 사용 예시
if __name__ == "__main__":
    print("모던 가구 생산:")
    client_code(ModernFurnitureFactory())

    print("\n빈티지 가구 생산:")
    client_code(VintageFurnitureFactory())