회원가입

[생성패턴] 추상 팩토리 abstract_factory

NULL 2022-10-04

 

참고 문서https://github.com/faif/python-patterns

아래 글은 위 참고 문서를 토대로 만들어진 내용입니다.

 


 

추상 팩토리 패턴은 무슨 패턴인가?

서로 관련성이 있거나 독립적인 여러 객체들의 조합을 만들기 위한 인터페이스를 제공하는 패턴입니다.

 


 

참고 문서의 내용으로는 아래와 같이 설명합니다.

In Java and other languages, the Abstract Factory Pattern serves to provide an interface for
creating related/dependent objects without need to specify their
actual class.
자바와 다른 언어에서 추상 팩토리 패턴은 실제 클래스를 지정할 필요 없이 관련/의존 객체를 만들기 위한 인터페이스를 제공하는 역할을 한다.

 

예제로 Pet 그리고 Pet 을 상속 받는 Dog, Cat 을 기준으로 해보겠습니다.

import random
from typing import Type


class Pet:
    def __init__(self, name: str) -> None:
        self.name = name

    def speak(self) -> None:
        raise NotImplementedError

    def __str__(self) -> str:
        raise NotImplementedError


class Dog(Pet):
    def speak(self) -> None:
        print("woof")

    def __str__(self) -> str:
        return f"Dog<{self.name}>"


class Cat(Pet):
    def speak(self) -> None:
        print("meow")

    def __str__(self) -> str:
        return f"Cat<{self.name}>"

 

PetShop 이라는 클래스를 정의합시다.

class PetShop:

    """A pet shop"""

    def __init__(self, animal_factory: Type[Pet]) -> None:
        """pet_factory is our abstract factory.  We can set it at will."""

        self.pet_factory = animal_factory

    def buy_pet(self, name: str) -> Pet:
        """Creates and shows a pet using the abstract factory"""

        pet = self.pet_factory(name)
        print(f"Here is your lovely {pet}")
        return pet

여기서 self.pet_factory 추상 팩토리가 되는 것입니다.

 

이제 위에 생성한 클래스들로 구체적인 사용 예를 들어봅시다.

import random
from typing import Type


class Pet:
    def __init__(self, name: str) -> None:
        self.name = name

    def speak(self) -> None:
        raise NotImplementedError

    def __str__(self) -> str:
        raise NotImplementedError


class Dog(Pet):
    def speak(self) -> None:
        print("woof")

    def __str__(self) -> str:
        return f"Dog<{self.name}>"


class Cat(Pet):
    def speak(self) -> None:
        print("meow")

    def __str__(self) -> str:
        return f"Cat<{self.name}>"


class PetShop:

    """A pet shop"""

    def __init__(self, animal_factory: Type[Pet]) -> None:
        """pet_factory is our abstract factory.  We can set it at will."""

        self.pet_factory = animal_factory

    def buy_pet(self, name: str) -> Pet:
        """Creates and shows a pet using the abstract factory"""

        pet = self.pet_factory(name)
        print(f"Here is your lovely {pet}")
        return pet


# Additional factories:

# Create a random animal
def random_animal(name: str) -> Pet:
    """Let's be dynamic!"""
    return random.choice([Dog, Cat])(name)


# Show pets with various factories
def main() -> None:
    """
    # A Shop that sells only cats
    >>> cat_shop = PetShop(Cat)
    >>> pet = cat_shop.buy_pet("Lucy")
    Here is your lovely Cat<Lucy>
    >>> pet.speak()
    meow
    # A shop that sells random animals
    >>> shop = PetShop(random_animal)
    >>> for name in ["Max", "Jack", "Buddy"]:
    ...    pet = shop.buy_pet(name)
    ...    pet.speak()
    ...    print("=" * 20)
    Here is your lovely Cat<Max>
    meow
    ====================
    Here is your lovely Dog<Jack>
    woof
    ====================
    Here is your lovely Dog<Buddy>
    woof
    ====================
    """


if __name__ == "__main__":
    random.seed(1234)  # for deterministic doctest outputs
    shop = PetShop(random_animal)
    import doctest

    doctest.testmod()

위 코드를 보면 PetShop Pet 의 클래스를 의존하고 있습니다.

PetShop Pet 을 생성하고 있습니다.

0 0
디자인패턴
A collection of design patterns and idioms in Python.
Yesterday: 677
Today: 179