반응형
팩토리 메소드 패턴
- 인터페이스를 통해 객체를 생성하지만 팩토리가 아닌 서브 클래스가 해당 객체 생성을 위해 어떤 클래스를 호출할지 결정한다.
- 팩토리 메소드는 인스턴스화가 아닌 상속을 통해 객체를 생성한다.
- 팩토리 메소드 디자인은 유동적이다. 특정 객체가 아닌 같은 인스턴스나 서브 클래스 객체를 반환할 수 있다.
- 팩토리 메소드 패턴은 객체를 생성하는 인터페이스를 정의하고 어떤 클래스를 초기화할지는서브 클래스의 결정에 맡긴다.
팩토리 메소드 구현 예
- 커리어 서비스(링크드인)과 앨범 서비스(페이스북)가 개별적으로 존재한다.
- 두 서비스는 공통적으로 개인 정보를 입력해야한다.
- 서비스 종류에 따라 알맞는 내용을 포함하는 프로필을 생성해보자
from abc import abstractmethod
# Product 인터페이스
# Section 추상 클래스
class Section:
@abstractmethod
def describe(self):
pass
# ConcreateProduct 클래스
class PersonalSection(Section):
def describe(self):
return "개인정보"
class AlbumSection(Section):
def describe(self):
return "앨범"
class CareerSection(Section):
def describe(self):
return "커리어"
# Creator 추상 클래스
class Profile:
def __init__(self):
self.sections = []
self.createProfile() # profile 인스턴스 생성과 동시에 메서드를 실행시킨다.
@abstractmethod
def createProfile(self):
pass
def getSections(self):
return self.sections
def addSections(self, section):
self.sections.append(section)
# ConcreateCreator 클래스
class linkedin(Profile):
def createProfile(self): # 해당하는 Section을 sections에 담는다.
self.addSections(PersonalSection())
self.addSections(CareerSection())
class facebook(Profile):
def createProfile(self):
self.addSections(PersonalSection())
self.addSections(AlbumSection())
# Creator 클래스를 호출하는 클라이언트
if __name__ == '__main__':
profile_type = input("어떤 프로필을 만드시겠습니까? [LinkedIn or FaceBook]")
profile = eval(profile_type.lower())()
print("생성한 프로필", type(profile).__name__)
print("프로필에 포함된 섹션 ::", [section.describe() for section in profile.getSections()])
# 결과1.
어떤 프로필을 만드시겠습니까? [LinkedIn or FaceBook]linkedin
생성한 프로필 linkedin
프로필에 포함된 섹션 :: ['개인정보', '커리어']
# 결과2.
어떤 프로필을 만드시겠습니까? [LinkedIn or FaceBook]facebook
생성한 프로필 facebook
프로필에 포함된 섹션 :: ['개인정보', '앨범']
팩토리 메소드 패턴의 장점
- 유연성과 포괄성을 갖추며 한 클래스에 종속되지 않는다. ConcreateProduct가 아닌 인터페이스(Product)에 의존한다.
- 객체를 생성하는 코드와 활용하는 코드를 분리해 의존성이 줄어든다. 클라이언트는 인자나 어떤 클래스가 생성되는지 알 필요가 없다.
- 새로운 클래스 추가 등 유지보수가 쉽다.
추가 레퍼런스
추상 팩토리 패턴
- 관련된 객체 집단을 생성하기 위해 한 개 이상의 팩토리 메소드가 필요
- 다른 클래스 객체를 생성하기 위해 컴포지션을 사용
- 관련된 객체 집단을 생성
추상 팩토리 구현 예
- 인도식 피자와 미국식 피자를 판매하는 가게
- 채식 피자와 일반 피자를 주문할 수 있음
from abc import abstractmethod
# AbstractFactory
class PizzaFactory:
@abstractmethod
def createVegPizza(self):
pass
@abstractmethod
def createNonVegPizza(self):
pass
# ConcreateFactory
class IndianPizzaFactory(PizzaFactory):
def createVegPizza(self):
return DeluxVeggiePizza()
def createNonVegPizza(self):
return ChickenPizza()
class USPizzaFactory(PizzaFactory):
def createVegPizza(self):
return MexicanVegPizza()
def createNonVegPizza(self):
return HamPizza()
# AbstractPorduct
class VegPizza:
@abstractmethod
def prepare(self, VegPizza):
pass
class NonVegPizza:
@abstractmethod
def serve(self, VegPizza):
pass
# ConcreateProducts
class DeluxVeggiePizza(VegPizza):
def prepare(self):
print(f"{type(self).__name__} 를 준비합니다.")
class ChickenPizza(NonVegPizza):
def serve(self, VegPizza):
print(f"{type(self).__name__} 는 {type(VegPizza).__name__} 에 치킨을 추가합니다.")
class MexicanVegPizza(VegPizza):
def prepare(self):
print(f"{type(self).__name__} 를 준비합니다.")
class HamPizza(NonVegPizza):
def serve(self, VegPizza):
print(f"{type(self).__name__} 는 {type(VegPizza).__name__} 에 햄을 추가합니다.")
# 실행 클래스
class PizzaStore:
def __init__(self):
pass
def makePizzas(self):
for factory in [IndianPizzaFactory(), USPizzaFactory()]:
self.factory = factory
self.NonVegPizza = self.factory.createNonVegPizza()
self.VegPizza = self.factory.createVegPizza()
self.VegPizza.prepare()
self.NonVegPizza.serve(self.VegPizza)
pizza = PizzaStore()
pizza.makePizzas()
"""
# 결과.
DeluxVeggiePizza 를 준비합니다.
ChickenPizza 는 DeluxVeggiePizza 에 치킨을 추가합니다.
MexicanVegPizza 를 준비합니다.
HamPizza 는 MexicanVegPizza 에 햄을 추가합니다.
"""
추가 레퍼런스
반응형
'나는 이렇게 본다 > 파이썬 디자인 패턴' 카테고리의 다른 글
퍼사드 패턴 (0) | 2022.05.31 |
---|---|
심플 팩토리 패턴 (0) | 2022.05.27 |
모노스테이트, 메타클래스, 싱글톤 구현예시 (0) | 2022.05.25 |
싱글톤 패턴, 게으른 초기화, 모듈 싱글톤 (0) | 2022.05.24 |
디자인 패턴 개요 (0) | 2022.05.23 |