데코레이터 패턴(Decorator Pattern)은 객체를 동적으로 감싸(wrap) 새로운 기능을 추가하는 구조 디자인 패턴이다. 상속 없이 기존 클래스를 변경하지 않고 기능을 확장한다.
개념
Component (인터페이스)
↑
ConcreteComponent (기본 구현)
↑
Decorator (Component를 감싸고, Component를 참조)
↑
ConcreteDecoratorA, ConcreteDecoratorB (기능 추가)
Python 데코레이터 (함수 래핑)
python
import functools
import time
# 로깅 데코레이터
def log_calls(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print(f"호출: {func.__name__}({args}, {kwargs})")
result = func(*args, **kwargs)
print(f"반환: {result}")
return result
return wrapper
# 타이밍 데코레이터
def timing(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"{func.__name__}: {elapsed:.3f}s")
return result
return wrapper
# 여러 데코레이터 중첩
@log_calls
@timing
def calculate(x, y):
return x + y
calculate(3, 4)
Python 클래스 기반 데코레이터
python
# Flask/FastAPI 스타일의 라우트 데코레이터
class Router:
def __init__(self):
self.routes = {}
def route(self, path, methods=None):
def decorator(func):
self.routes[path] = {'func': func, 'methods': methods or ['GET']}
return func
return decorator
app = Router()
@app.route('/users', methods=['GET'])
def get_users():
return [{"id": 1}]
Java 데코레이터 패턴
java
// BufferedReader가 Reader를 감싸는 데코레이터
Reader r = new FileReader("file.txt");
BufferedReader br = new BufferedReader(r); // 버퍼링 추가
// Java I/O 스트림 전체가 데코레이터 패턴
관련 개념
- •디자인 패턴 — 데코레이터가 속하는 구조 패턴
- •SOLID 원칙 — OCP 원칙의 구현
- •클로저 — Python 데코레이터의 기반
- •람다 함수 — 데코레이터와 함께 사용