[파이썬] 생성 패턴의 종류와 사용법

소프트웨어 개발에서 생성 패턴은 객체의 생성에 관련된 문제들을 해결하기 위해 사용되는 디자인 패턴의 일종입니다. 생성 패턴은 객체 생성의 유연성, 확장성, 재사용성을 향상시키는 방법들을 제공합니다. 이번 블로그 글에서는 생성 패턴의 종류와 그 사용법에 대해 알아보겠습니다.

싱글톤 패턴 (Singleton Pattern)

싱글톤 패턴은 특정 클래스의 인스턴스가 오직 하나만 생성되도록 보장하는 패턴입니다. 이는 전역 변수의 사용을 통해 구현되며, 객체의 생성, 사용, 소멸을 관리하는 데 유용합니다.

사용법:

class Singleton:
    instance = None  # 인스턴스 변수
    
    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = super().__new__(cls, *args, **kwargs)
        return cls.instance

# 사용 예시:
s1 = Singleton()
s2 = Singleton()

print(s1 is s2)  # 결과: True

팩토리 메서드 패턴 (Factory Method Pattern)

팩토리 메서드 패턴은 객체의 생성을 서브 클래스에 위임하는 패턴입니다. 즉, 생성 로직을 분리하여 새로운 객체 생성이 필요한 경우 서브 클래스에서 직접 객체를 생성하게 됩니다. 이를 통해 객체 생성의 역할을 구체적인 서브 클래스에게 위임함으로써 유연성과 확장성을 제공합니다.

사용법:

from abc import ABC, abstractmethod

class Creator(ABC):
    @abstractmethod
    def factory_method(self):
        pass

    def create_product(self):
        return self.factory_method()

class ConcreteCreator1(Creator):
    def factory_method(self):
        return ConcreteProduct1()

class ConcreteCreator2(Creator):
    def factory_method(self):
        return ConcreteProduct2()

class Product(ABC):
    @abstractmethod
    def operation(self):
        pass

class ConcreteProduct1(Product):
    def operation(self):
        return "Product 1"

class ConcreteProduct2(Product):
    def operation(self):
        return "Product 2"

# 사용 예시:
creator1 = ConcreteCreator1()
product1 = creator1.create_product()
print(product1.operation())  # 결과: "Product 1"

creator2 = ConcreteCreator2()
product2 = creator2.create_product()
print(product2.operation())  # 결과: "Product 2"

추상 팩토리 패턴 (Abstract Factory Pattern)

추상 팩토리 패턴은 관련성 있는 여러 개의 객체를 일관성 있게 생성하는 패턴입니다. 서로 연관된 객체들을 그룹으로 묶어 팩토리 클래스를 정의하고, 이 팩토리 클래스를 사용하여 객체를 생성합니다. 이를 통해 객체의 생성과 구성을 분리하여 클라이언트 코드에서는 각 객체의 구현을 알 필요가 없게 됩니다.

사용법:

from abc import ABC, abstractmethod

class AbstractFactory(ABC):
    @abstractmethod
    def create_product_a(self):
        pass

    @abstractmethod
    def create_product_b(self):
        pass

class ConcreteFactory1(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductA1()

    def create_product_b(self):
        return ConcreteProductB1()

class ConcreteFactory2(AbstractFactory):
    def create_product_a(self):
        return ConcreteProductA2()

    def create_product_b(self):
        return ConcreteProductB2()

class AbstractProductA(ABC):
    @abstractmethod
    def operation(self):
        pass

class ConcreteProductA1(AbstractProductA):
    def operation(self):
        return "Product A1"

class ConcreteProductA2(AbstractProductA):
    def operation(self):
        return "Product A2"

class AbstractProductB(ABC):
    @abstractmethod
    def operation(self):
        pass

class ConcreteProductB1(AbstractProductB):
    def operation(self):
        return "Product B1"

class ConcreteProductB2(AbstractProductB):
    def operation(self):
        return "Product B2"

# 사용 예시:
factory1 = ConcreteFactory1()
productA1 = factory1.create_product_a()
productB1 = factory1.create_product_b()
print(productA1.operation())  # 결과: "Product A1"
print(productB1.operation())  # 결과: "Product B1"

factory2 = ConcreteFactory2()
productA2 = factory2.create_product_a()
productB2 = factory2.create_product_b()
print(productA2.operation())  # 결과: "Product A2"
print(productB2.operation())  # 결과: "Product B2"

생성 패턴은 객체의 생성과 관련된 문제를 해결하는 유용한 디자인 패턴들입니다. 각 패턴마다 고유한 특징과 사용법이 있으며, 적절하게 선택하여 프로젝트에 적용할 수 있도록 고려해야 합니다.