Creation Design Pattern
오브젝트를 생성하는 방법을 다루는 패턴
이름과 같이 공장을 뜻하며, 공장은 함수 또는 클래스로 나타낼 수 있음
# 제품 정의
class Robot:
def speak(self):
pass
class Cat(Robot):
def spea(self):
print("meow")
class Dog(Robot):
def speak(self):
print("bark")
# 공장
def factoryFunc(animal):
if animal == "cat":
return Cat()
elif animal == "dog":
return Dog()
# 클라이언트 요청
cat = factoryFunc("cat")
dog = factoryFunct("dog")
cat.speak()
dog.speak()
from enum import Enum
class Robot(Enum):
CAT = 0
DOG = 1
class Cat(Robot):
def spea(self):
print("meow")
class Dog(Robot):
def speak(self):
print("bark")
# 공장
def RobotFactory:
def makeRobot(self, robot:RobotEnum):
if robot == RobotEnum.CAT:
return Cat()
elif robot == RobotEnum.DOG:
reutrn Dog()
# 클라이언트 요청
fac1 = RobotFactory()
dog = fac1.makeRobot(RobotEnum.DOG)
dog.speak()
cat = fac1.makeRobot(RobotEnum.CAT)
cat.speak()
- 사용자가 오브젝트들의 생성과정ㅇ르 클라이언트가 직접 다룰 필요가 없게 됨
- 어떤 상황에서는 오브젝트를 만드는 과정이 복잡해질 수 있음
- 인스턴스를 만드는 방법을 상위 클래스 측에서 결정하지만, 구체적인 이름까지는 결정 x
- 구체적인 내용은 모두 하위 클래스(상속을 받은 하위 클래스) 측에서 수행
# Robot interface
class Robot:
def speak(self):
pass
class Cat(Robot):
def speak(self):
print("meow")
class Dog(Robot):
def speak(self):
print("barK")
# Factory interface
class Factory():
def createRobot(self):
pass # pass로 만들어놓고 이후에 구현
class CatFactory(Factory):
def __init__(self):
self.cat_count = 0
def createRobot(self):
self.cat_count += 1
return Cat()
def catCount(self):
return self.cat_count
class DogFactory(Factory):
def haveDog(self):
self.dog = self.createRobot()
def createRobot(self):
return Dog()
def addWing(self, dog:Dog):
print("dog wings added")
return dog
cat_Factory = CatFactory()
cat1 = cat_Factory.createRobot()
cat2 = cat_Factory.createRobot()
print(cat_Factory.cat_count) # 2
dog_Factory = DogFactory()
dog1 = dog_Factory.createRobot()
dog_Factory.addWing(dog1) # dog wings added
- Factory Pattern의 확장 버전
- A 제품과 B 제품을 몇 개를 만들었는지 추적하고 싶거나, Facotyr의 상태를 알고 싶을 수 있음
이럴 때 Factory Pattern만으로는 추가 기능 구현이 어려울 수 있어서 사용함- Factory Interface를 따로 두어 각 제품에 특화된 Factory들을 만들어서 특화된 Factory에 여러 기능을 추가할 수 있도록 함
- 위의 고양이, 강아지 공장에서 보았듯이 Abstract Class를 구현해두고 그 밑에서 특화된 Concrete Class를 만들어서 사용함