[python] 리팩토링 디자인 패턴

리팩토링은 소프트웨어 개발 과정에서 코드를 개선하는 작업입니다. 코드를 리팩토링할 때는 주로 디자인 패턴을 사용하여 구조적인 변경을 수행합니다. 디자인 패턴은 일반적인 문제에 대한 해결책을 제공하며, 코드를 더 효율적으로 만들어줍니다. 이번 글에서는 파이썬에서 자주 사용되는 몇 가지 리팩토링 디자인 패턴을 살펴보겠습니다.

1. 싱글톤 패턴 (Singleton Pattern)

싱글톤 패턴은 오직 하나의 인스턴스만을 생성하도록 하는 디자인 패턴입니다. 파이썬에서는 클래스 레벨 변수와 __new__ 메서드를 이용하여 간단하게 싱글톤을 구현할 수 있습니다. 예를 들어, 다음과 같이 싱글톤을 구현할 수 있습니다.

class Singleton:
    instance = None

    def __new__(cls, *args, **kwargs):
        if not cls.instance:
            cls.instance = super().__new__(cls, *args, **kwargs)
        return cls.instance

위의 코드에서 instance 변수는 싱글톤 인스턴스를 저장하는 변수입니다. __new__ 메서드는 객체를 생성할 때 호출되며, 이 메서드를 오버라이딩하여 인스턴스가 이미 존재하는지 체크한 후, 없을 경우에만 인스턴스를 생성합니다.

2. 템플릿 메서드 패턴 (Template Method Pattern)

템플릿 메서드 패턴은 알고리즘의 골격을 정의한 후, 일부 과정을 서브클래스에서 구현할 수 있도록 하는 디자인 패턴입니다. 파이썬에서는 추상 베이스 클래스를 이용하여 템플릿 메서드를 구현할 수 있습니다. 예를 들어, 다음과 같이 추상 베이스 클래스를 정의하고 템플릿 메서드를 구현할 수 있습니다.

from abc import ABC, abstractmethod

class AbstractClass(ABC):
    def template_method(self):
        self._step1()
        self._step2()
        self._step3()

    @abstractmethod
    def _step1(self):
        pass

    @abstractmethod
    def _step2(self):
        pass

    @abstractmethod
    def _step3(self):
        pass

class ConcreteClass(AbstractClass):
    def _step1(self):
        print("Step 1")

    def _step2(self):
        print("Step 2")

    def _step3(self):
        print("Step 3")

위의 코드에서 AbstractClass는 추상 베이스 클래스로, _step1, _step2, _step3 메서드를 정의하고 템플릿 메서드인 template_method에서 이들 메서드를 차례대로 호출합니다. ConcreteClassAbstractClass를 상속받아 필요한 메서드를 구현합니다.

3. 옵서버 패턴 (Observer Pattern)

옵서버 패턴은 객체 사이의 일 대 다 관계를 정의하여, 한 객체의 상태가 변하면 이에 응답하여 다른 객체에게 알려주는 디자인 패턴입니다. 파이썬에서는 옵서버 패턴을 구현하기 위해 Observable 클래스와 Observer 클래스를 정의할 수 있습니다. 예를 들어, 다음과 같이 구현할 수 있습니다.

class Observable:
    def __init__(self):
        self.observers = []

    def register(self, observer):
        self.observers.append(observer)

    def unregister(self, observer):
        self.observers.remove(observer)

    def notify(self, msg):
        for observer in self.observers:
            observer.update(msg)

class Observer:
    def update(self, msg):
        print(f"Received message: {msg}")

# 사용 예시
subject = Observable()

observer1 = Observer()
observer2 = Observer()

subject.register(observer1)
subject.register(observer2)

subject.notify("Hello world!")

위의 코드에서 Observable은 옵서버를 등록 및 해제하고 알림을 전송하는 기능을 제공합니다. Observerupdate 메서드를 정의하여 변경 사항을 받아 처리할 수 있습니다.Observable 객체를 생성한 후, 옵서버를 등록하고 변경 사항을 알릴 수 있습니다.

마무리

위에서 소개한 리팩토링 디자인 패턴들은 파이썬에서 자주 사용되며, 코드의 구조적인 개선을 도와줍니다. 이 외에도 여러 가지 다른 디자인 패턴들이 존재하며, 각각의 상황에 맞게 적용할 수 있습니다. 디자인 패턴을 잘 이해하고 활용한다면, 코드의 가독성과 유지보수성을 높일 수 있습니다.

참고 문서: