[디자인패턴] 팩토리 메소드 패턴 (in python)

azzurri21·2021년 6월 26일
0

디자인패턴

목록 보기
1/2

클래스 다이어그램

구조

팩토리 메소드 패턴이란, product의 세부 종류인 concreteProduct 객체의 생성을 creator의 자식 클래스인 concreteCreator에서 담당하는 것이다.

객체 생성 인터페이스(creator), 생성할 객체 종류(concrete product) 선정 및 실제 생성을 담당하는 자식 클래스(concrete creator)로 구성된다.

이때 concrete creator마다 다른 조합(종류)의 concrete product를 생성하고 보유한다. 즉, 서로 다른 product 클래스별로 각각에 대응하는 creator가 존재한다.

자식 팩토리클래스(concrete creator)에서는, if-else 분기 등을 이용하여 인스턴스를 생성할 상품클래스(product)의 세부 상품(concrete product)를 결정한다. 부모 팩토리클래스의 메소드를 자식클래스에서 오버라이딩하여 구현한다.

구현

시스템 명세

마우스라는 유형의 product가 있다고 하자. 마우스 product(부모 클래스)의 concrete product(자식 클래스)에는 g102와 magic mouse2가 존재한다. 한편 client는 product와 factory(이상 부모 추상클래스)의 사용법(메소드)만 알고 있다.

python 코드

[참고]

  • 위 클래스 다이어그램을 코드화 하는 것에 초점을 두었으므로 product와 factory의 기능은 최대한 줄였다.
  • factory에서 생성한 product 객체는 반환하여 client의 지역변수에 저장하도록 설계했다.
  • ##으로 주석처리된 코드는 팩토리 메소드 패턴에 템플릿 메소드 패턴을 추가하는 내용이다. (아래 절에서 자세히 설명)
from abc import ABCMeta, abstractmethod


# Product
class Mouse(metaclass=ABCMeta):
    @abstractmethod
    def click_left(self):
        pass

    @abstractmethod
    def click_right(self):
        pass


# concreteProduct
class G102(Mouse):
    def click_left(self):
        print('...click left g102 manufactured by Logi')
        
    def click_right(self):
        print('...click right g102 manufactured by Logi')


class MagicMouse2(Mouse):
    def click_left(self):
        print('...click left magic mouse2 manufactured by Apple')
        
    def click_right(self):
        print('...click right magic mouse2 manufactured by Apple')


# Factory
class MouseFactory(metaclass=ABCMeta):
    @abstractmethod
    def createMouse(self):
        ''' factory method '''
        pass

##    def useMouse(self):
##        ''' templete method '''
##        mouse = self.createMouse()
##        mouse.click_left()
##        mouse.click_right()
##        
##        return mouse


# concreteFactory
class LogiMouseFactory(MouseFactory):
    def createMouse(self):
        return G102()


class AppleMouseFactory(MouseFactory):
    def createMouse(self):
        return MagicMouse2()


# client
class Client():
    def use(self, company):
        """company는 사용자 요구에 따라 변경"""

        # 사용자 요구에 따라, product를 생산할 factory 생성
        if company == 'logi':
            factory = LogiMouseFactory()
        elif company == 'apple':
            factory = AppleMouseFactory()
        else:
            return

        # product 생산 (객체 생성)
        mymouse = factory.createMouse()
        # 생산된 product를 사용
        mymouse.click_left()

##        # product 생산, 실행, 반환하는 templete_method 호출
##        mymouse = factory.useMouse()


if __name__ == '__main__':
    client = Client()
    client.use('logi')
    client.use('apple')
    

실행결과

...click left g102 manufactured by Logi
...click left magic mouse2 manufactured by Apple

템플릿 메서드 패턴 적용하기

사용자가 factory_method에서 반환된 product 객체를 가지고 메서드를 호출하는 순서나 내용이 일정하여 concreteProduct에 무관히 반복된다면, 부모(creator) 클래스에 main 코드를 복사한 templete_method를 추가하여 사용자의 사용양식을 추상화한다.

(이때 템플릿 메서드 패턴에서 일컫는 operation에는 factory_method를 포함한 product의 메소드들이 해당한다.)

[참고] 템플릿 메서드와 팩토리 메서드 패턴 비교

  • 템플릿 메서드: 부모 메서드(추상X) templete_method 내에서는 자식이 구현할 부모 추상메서드 operation1,2,3 차례로 호출. 사용자는 자식 인스턴스 생성하여 부모 메서드 templete_method 호출.
  • 팩토리 메서드: 자식(concreteCreator) 구현메서드 factory_method에서는 concreteProduct 인스턴스 생성하고 반환. 사용자는 요구에 따라 분기하여 자식(concreteCreator) 인스턴스 생성하고 자식(concreteCreator) 구현메서드 factory_method 호출. 반환된 concreteProduct는 client 멤버변수나 main 지역변수에 저장.

참고자료

팩토리 메소드 패턴 (Factory Method Pattern) - 기계인간 John Grib

profile
파이썬 백엔드 개발자

0개의 댓글