구체적인 클래스에 의존하지 않고 서로 연관되거나 의존적인 객체들의 조합을 만드는 인터페이스를 제공하는 패턴. 관련성 있는 여러 종류의 객체를 일관된 방식으로 생성하는 경우에 유용하다.
상세화된 서브클래스를 정의하지 않고도 서로 관련성이 있거나 독립적인 여러 객체의 군을 생성하기 위한 인터페이스를 제공한다.
추상 팩토리는 다음의 경우에 사용한다.
[참고] 팩토리 메서드 패턴에 관한 자세한 설명은 이전 포스트를 참고.
팩토리 메소드 패턴이란, product의 세부 종류인 concreteProduct 객체의 생성을 creator의 자식 클래스인 concreteProduct에서 담당하는 것이다. 이때 서로 다른 product 클래스별로 각각에 대응하는 factory(creator)가 존재한다. 반면, 추상 팩토리 패턴은 product의 조합별로 factory를 만든다.
예를 들어, 키보드와 마우스라는 두 유형의 product가 존재한다고 가정하자. 키보드 product의 concreteProduct는 k380과 magic keyboard 두 종류가 있다. 마찬가지로, 마우스 클래스의 자식 클래스는 g102와 magic mouse2가 존재한다. 한편 client는 키보드와 마우스의 조합(컴퓨터)을 생산하고 이를 사용한다. 이때 컴퓨터는 g102와 k380, magic keyboard와 magic mouse2의 조합으로만 생산된다고 하자.
이러한 경우에 팩토리 메소드 패턴은 k380과 magic keyboard 중 하나의 객체를 생성하는 concreteCreator 클래스, g102와 magic mouse2 중 하나의 객체를 생성하는 concreteCreator 클래스를 각각 정의한다. 하지만 추상팩토리 패턴은 k380과 g102 객체를 함께 생성하는 concreteFactory 클래스와 magic keyboard와 magic mouse2를 함께 생성하는 concreteFactory 클래스를 각각 정의한다. 그리하여 client는 두 클래스 중 하나의 인스턴스를 생성하여 원하는 조합의 product들을 사용하게 된다.
from abc import ABCMeta, abstractmethod
# (abstract)Product
class Keyboard(metaclass=ABCMeta):
@abstractmethod
def type_words(self):
pass
class Mouse(metaclass=ABCMeta):
@abstractmethod
def click_left(self):
pass
# concreteProduct
class K380(Keyboard):
def type_words(self):
print('...type with k380 manufactured by Logi')
class MagicKeyborad(Keyboard):
def type_words(self):
print('...type with magic keyboard manufactured by Apple')
class G102(Mouse):
def click_left(self):
print('...click g102 manufactured by Logi')
class MagicMouse2(Mouse):
def click_left(self):
print('...click magic mouse2 manufactured by Apple')
# (abstract)Factory
class ComputerFactory(metaclass=ABCMeta):
@abstractmethod
def createKeyboard(self):
pass
@abstractmethod
def createMouse(self):
pass
# concreteFactory
class LogiComputerFactory(ComputerFactory):
def createKeyboard(self):
return K380()
def createMouse(self):
return G102()
class AppleComputerFactory(ComputerFactory):
def createKeyboard(self):
return MagicKeyborad()
def createMouse(self):
return MagicMouse2()
# client
class Client():
def use(self, company):
"""company는 사용자 요구에 따라 변경"""
# product를 생산할 factory 생성
if company == 'logi':
factory = LogiComputerFactory()
elif company == 'apple':
factory = AppleComputerFactory()
else:
return
# product 생산 (객체 생성)
keyboard = factory.createKeyboard()
mouse = factory.createMouse()
# 생산된 product를 사용
keyboard.type_words()
mouse.click_left()
if __name__ == '__main__':
client = Client()
client.use('logi')
print()
client.use('apple')
...type with k380 manufactured by Logi
...click g102 manufactured by Logi
...type with magic keyboard manufactured by Apple
...click magic mouse2 manufactured by Apple
추상 팩토리 패턴 (Abstract Factory Pattern) - 기계인간 John Grib
[Design Pattern] 추상 팩토리 패턴이란 - Heee's Development Blog
[디자인패턴] 추상 팩토리 패턴 ( Abstract Factory Pattern ) :: victolee