티스토리 뷰

파이썬은 추상 클래스를 지원합니다.
추상 클래스는 기본적인 틀을 만들어두고 상속받는 클래스에서 그 구현을 강제하는 클래스입니다.
파이썬에서는 추상 클래스를 abc(abstract base class)라는 모듈을 임포트해서 사용할 수 있습니다.
저는 여기서 Animal이라는 클래스를 추상클래스로 생성해보고 say라는 메소드를 구현하도록 강제해 보겠습니다.
예제는 아래와 같습니다.

from abc import ABCMeta, abstractmethod

class Animal(metaclass=ABCMeta):
    @abstractmethod
    def say(self):
        pass

위와 같이 Animal이라는 객체를 생성해주면 이제 Animal을 상속받는 클래스는 무조건 say 메소드를 구현을 하여야만 객체의 생성이 가능해집니다.

 

이제 위의 Animal을 상속받아 Dog와 Cat 클래스를 만들어 보겠습니다.

Dog와 Cat 클래스는 아래와 같이 작성할 수 있습니다.

class Dog(Animal):
    def say(self):
        print('왈왈!!')


class Cat(Animal):
    def say(self):
        print('냐옹!!')

이제 Dog와 Cat 클래스가 선언되었으니 Dog와 Cat의 객체를 생성해서 say를 호출해보겠습니다.

if __name__ == '__main__':
    dog = Dog()
    cat = Cat()
    dog.say()
    cat.say()

결과

왈왈!!
냐옹!!

위와 같은 결과를 볼 수 있습니다.

 

만약 아래와 같이 하위 클래스에서 say를 구현하지 않는다면 어떻게 될까요?

class Dog(Animal):
    pass


class Cat(Animal):
    pass

 

만약 하위 클래스에서 say를 구현하지 않는다면 아래와 같은 에러가 발생합니다.

Traceback (most recent call last):
  File "D:/TestProject/study/factory.py", line 25, in <module>
    Dog()
TypeError: Can't instantiate abstract class Dog with abstract methods say

추상 클래스 Dog를 인스턴스화 할 수 없다는 에러가 발생했습니다.

위와 같이 추상 클래스는 추상 메소드의 구현을 강제합니다.

 

생각보다 추상 클래스는 별거 없습니다.

그저 틀을 미리 만들어두고 그 틀에 맞춰 직접 상속받는 측에서 구현을 하도록 만들어 두었을 뿐이지요.

 

그럼 위의 추상 클래스를 이용해서 디자인 패턴 중 팩토리 패턴에 대해 알아보겠습니다.

디자인 패턴에는 생성 패턴, 구조 패턴, 행위 패턴 이렇게 3개로 구분이 됩니다.

그중에 팩토리 패턴은 생성 패턴의 한 종류입니다.

 

팩토리 패턴을 간단히 설명하자면 다른 클래스의 객체를 생성하는 클래스입니다.

팩토리 패턴은 클라이언트가 직접 객체를 생성할 수 있게 해줍니다.

또한 객체 생성과 클래스의 구현을 나누어 서로간의 의존도를 낮추고 이미 생성된 객체를 팩토리가 재활용 할 수 있게 할 수 있습니다.

 

이렇게 이야기를 해보니 ConnectionPool과 같은 개념인것 같은데 ConnectionPool이 이러한 패턴으로 만들어진건지는 모르겠네요.

이 이야기는 넘어가고 팩토리 패턴에 대해 마저 이야기를 하겠습니다.

 

디자인 패턴을 생성, 구조, 행위 패턴 3가지로 구분하듯이 팩토리 패턴 역시 심플 팩토리, 팩토리 메소드, 추상 팩토리 패턴 이렇게 3가지로 구분할 수 있습니다.

우선 이중에 나머지 두 패턴의 기본이 되는 심플 팩토리 패턴부터 알아보겠습니다.

 

심플 팩토리 패턴은 위에서 사용했던 Animal 추상 클래스와 이를 상속받아 작성되었던 Dog와 Cat 클래스를 그대로 사용합니다.

심플 팩토리 패턴은 정말로 간단합니다.

 

심플 팩토리 패턴의 작성은 아래와 같이 할 수 있습니다.

class ForestFactory(object):
    def make_sound(self, obj_type):
        return eval(obj_type)().say()

정말 간단하지요?

이러한 심플 팩토리 패턴의 사용도 쉽습니다.

사용법은 아래와 같습니다.

if __name__ == '__main__':
    ff = ForestFactory()
    animal = input('어떤 동물의 울음소리를 들으시겠습니까? Dog or Cat? ')
    ff.make_sound(animal)

결과는 아래와 같습니다.

어떤 동물의 울음소리를 들으시겠습니까? Dog or Cat? Dog
왈왈!!
어떤 동물의 울음소리를 들으시겠습니까? Dog or Cat? Cat
냐옹!!

 

이제 코드에 대해 간단히 설명 드리자면 ForestFactory라는 심플 팩토리 패턴 클래스를 작성하였습니다.

ForestFactory 클래스는 make_sound라는 메소드를 가지고 있고 obj_type이라는 클래스를 상속받습니다.

 

여기서 파이썬의 built-in 함수인 eval에 대해 처음 보시는 분들도 많을겁니다.

eval 함수는 인자로 넘어온 string 값을 그대로 실행하고 결과를 반환해줍니다.

그렇게에 아래와 같이도 사용할 수 있습니다.

return eval(obj_type)().say()

return eval('%s().say()' % obj_type)

이와 같이 런타임 중에 객체를 클라이언트가 생성할 수 있게 됩니다.

이를 심플 팩토리 패턴이라고 합니다.

 

다음 글에서는 팩토리 패턴에서의 팩토리 메소드 패턴과 추상 팩토리 패턴에 대해서 알아보겠습니다.

 

참고 : 파이썬 디자인 패턴 2/e

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함