본문 바로가기

설계

[디자인 패턴] 데코레이터 패턴 (Decorator Pattern) - python 예제 코드

데코레이터 패턴(Decorator Pattern)은 객체 지향 디자인 패턴 중 하나로, 객체에 추가적인 기능을 동적으로 더할 수 있게 해주는 패턴입니다. 이 패턴은 기존 객체를 수정하지 않고도 객체의 기능을 확장할 수 있습니다.

1. 핵심 아이디어


데코레이터 패턴의 핵심 아이디어는 객체를 감싸는 래퍼(wrapper)를 생성하여 이 래퍼 객체가 추가적인 기능을 제공하도록 하는 것입니다. 래퍼는 기존 객체와 같은 인터페이스를 가지며, 기존 객체와 동일한 기능을 제공합니다. 래퍼 객체는 기존 객체에 덧붙여져서 새로운 객체를 형성합니다.

2. 예제 코드


다음은 파이썬으로 작성된 데코레이터 패턴 예제 코드입니다. 이 예제에서는 특정 함수의 실행 시간을 측정하는 기능을 래퍼 객체로 추가하는 예제입니다.

import time

def time_it(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"Elapsed time: {end - start}")
        return result
    return wrapper

@time_it
def my_function(n):
    return sum(range(n))

result = my_function(1000000)
print(result)



위 코드에서 time_it 함수는 래퍼 함수로, my_function 함수를 감싸서 실행 시간을 측정하는 데코레이터 역할을 합니다. @time_it 데코레이터를 사용하여 my_function 함수를 래핑하면, my_function 함수를 호출할 때 time_it 함수가 실행되고 my_function 함수가 반환한 결과를 반환합니다. 이때, wrapper 함수는 my_function 함수와 같은 인터페이스를 가지며, my_function 함수를 호출하는 것과 같은 방식으로 호출됩니다.

위 예제에서는 my_function 함수의 실행 시간을 측정하는 데코레이터를 작성했지만, 이와 같은 방식으로 래퍼를 구현하면 다른 추가적인 기능을 동적으로 더할 수 있습니다.

3. 장점

  • 개방/폐쇄 원칙(OCP)을 따르기 쉽습니다. 기존 코드를 수정하지 않고도 새로운 기능을 추가할 수 있으므로, 코드의 수정이나 변경에 유연하게 대처할 수 있습니다.
  • 객체 지향 디자인 원칙(SOLID)을 따릅니다. 래퍼 객체를 통해 코드의 중복을 제거하고 객체 간의 결합도를 낮추어 유지보수성과 확장성을 향상시킵니다.
  • 기존 객체에 영향을 미치지 않으므로, 코드의 안정성과 신뢰성을 보장합니다.
  • 다양한 조합의 데코레이터를 적용함으로써 여러 가지 기능을 구성할 수 있으며, 이를 통해 높은 수준의 재사용성을 달성할 수 있습니다.

4. 단점

  • 객체의 수가 증가할 수 있습니다. 래퍼 객체를 생성하면서 객체의 수가 증가하게 되므로, 데코레이터를 많이 사용하면 성능에 영향을 미칠 수 있습니다.
  • 래퍼 객체를 생성할 때 추가적인 비용이 들어갑니다. 래퍼 객체를 생성하면서 추가적인 비용이 들어가게 되므로, 이를 고려하여 데코레이터를 사용해야 합니다.

5. 정리

데코레이터 패턴은 객체 지향 디자인 원칙을 준수하면서도 유연한 기능 확장이 가능하기 때문에, 적절하게 사용한다면 코드의 재사용성, 유지보수성, 확장성을 향상시킬 수 있습니다. 하지만, 객체의 수가 증가하거나 래퍼 객체 생성 시 비용이 추가되는 등의 단점이 있으므로, 상황에 맞게 사용해야 합니다.