스택큐힙리스트

데코레이터 패턴: 핵심 기능에 ‘슈퍼파워’를 덧입히는 법 본문

개발

데코레이터 패턴: 핵심 기능에 ‘슈퍼파워’를 덧입히는 법

스택큐힙리스트 2025. 7. 18. 13:49
반응형

레거시 코드를 뒤흔들지 않고, 로깅·캐싱·보안 같은 부가 기능을 플러그인처럼 꽂고 빼고 싶을 때—Decorator 패턴이 가장 우아한 해답입니다. 스프링 AOP가 동작하는 원리도 결국 데코레이터의 변주죠.


1️⃣ 데코레이터 패턴, 5초 요약

  • 정의 : ‘원본(Component)’을 래핑해 호출을 위임(delegate)하면서, 전 후처리 로직으로 기능을 확장하는 구조 패턴.
  • 구성 요소
    • Component : 클라이언트가 기대하는 인터페이스
    • ConcreteComponent : 실제 핵심 기능
    • Decorator : Component를 보유하며, 부가 기능을 더해 다시 Component 형태로 노출
  • 주요 효과 : 상속 없이 런타임에 새 기능 조립, OCP(개방·폐쇄 원칙) 준수.

2️⃣ 백엔드에서 언제 빛나나?

  • 로깅·트랜잭션 관리 – 메서드 앞뒤에 시작·종료 로그, 트랜잭션 demarcation 삽입
  • 캐싱 계층 – 동일한 쿼리 결과를 메모리·Redis에 저장 후 빠른 재사용
  • 인증·권한 체크 – 요청 객체를 검사해 불법 호출 차단
  • 3rd-Party SDK 감싸기 – 정제되지 않은 외부 라이브러리 호출을 내 규격으로 포장

3️⃣ Spring Boot 예제 – 서비스 로깅 데코레이터

public interface OrderService {
    void placeOrder(String id);
}

// 핵심 기능
@Service
@RequiredArgsConstructor
public class RealOrderService implements OrderService {
    private final OrderRepository repo;
    @Override
    public void placeOrder(String id) {
        repo.save(new Order(id));
    }
}

// 데코레이터
@Service
@Primary   // 같은 빈 타입이 둘이면 이쪽을 우선 주입
@RequiredArgsConstructor
public class LogOrderService implements OrderService {

    private final RealOrderService target;
    private final Logger log = LoggerFactory.getLogger(getClass());

    @Override
    public void placeOrder(String id) {
        long start = System.currentTimeMillis();
        try {
            target.placeOrder(id);          // 핵심 기능 위임
        } finally {
            log.info("placeOrder {} ms", System.currentTimeMillis() - start);
        }
    }
}

스프링 컨테이너가 OrderService 타입으로 의존성을 주입할 때 LogOrderService가 선택되므로, 클라이언트는 단 한 줄도 수정하지 않고 로그 기능이 추가된 서비스를 사용합니다.


4️⃣ 구현 꿀팁 & 주의점

  1. 생성자 주입으로 불변성 확보 : 데코레이터의 component 필드는 final로 두어야 누락을 방지합니다.
  2. 체인 길이 조절 : new Cache(new Retry(new Log(svc))) 형태가 길어진다면, 스프링 빈 후처리기나 AOP로 자동 조립을 고려하세요.
  3. Proxy와의 차이 : 둘 다 ‘래핑’이지만, Proxy는 접근 제어 초점, Decorator는 행동 확장 초점입니다. 개념을 혼용하지 않도록 명확히 문서화하세요.
  4. 단일 책임 원칙 유지 : 데코레이터 하나에 ‘캐싱+로그+트랜잭션’처럼 다 몰아넣지 말고, 역할별 클래스로 분리해 체이닝하도록 설계합니다.

한 줄 요약

Decorator 패턴은 “함수는 그대로, 능력만 업그레이드”하는 객체지향형 DLC(Downloadable Content)다.

반응형
Comments