스택큐힙리스트

책임을 넘겨라! Chain of Responsibility 한방 정복 본문

개발

책임을 넘겨라! Chain of Responsibility 한방 정복

스택큐힙리스트 2025. 7. 28. 10:06
반응형

1. 패턴 한 줄 요약

“여러 처리자(handler) 를 체인처럼 묶어, 요청을 순차적으로 건네며 해당 단계가 책임을 지면 거기서 끝·못 하면 다음으로 패스한다.”


2. 왜 써야 할까?

  • 결합도↓ : 클라이언트가 ‘누가 처리할지’를 몰라도 된다.
  • 확장성↑ : 새 규칙이 생겨도 체인에 핸들러만 끼워 넣으면 끝.
  • 실행 흐름 제어 : 요청 로깅→인증→권한→비즈니스 로직 같은 가변 파이프라인을 우아하게 다룬다.

3. 구조 감 잡기

  1. Handler 인터페이스 – handle(request) + next 보관
  2. ConcreteHandler – 조건 확인 후 처리·패스 결정
  3. Client – 첫 번째 핸들러에게만 요청하고, 나머지는 체인이 알아서

4. 코틀린 예제 – API 필터 체인

interface ApiFilter {
    fun doFilter(req: Request): Boolean       // true면 처리 완료
    var next: ApiFilter?
}

abstract class BaseFilter : ApiFilter {
    override var next: ApiFilter? = null
    final override fun doFilter(req: Request): Boolean {
        if (process(req)) return true         // 자신이 처리
        return next?.doFilter(req) ?: false   // 패스
    }
    protected abstract fun process(req: Request): Boolean
}

class AuthFilter : BaseFilter() {
    override fun process(req: Request) =
        if (req.token == "VALID") false else { println("401"); true }
}

class LogFilter : BaseFilter() {
    override fun process(req: Request): Boolean {
        println("요청 로그: ${req.path}"); return false
    }
}

// 체인 조립
val chain = AuthFilter().apply { next = LogFilter() }
chain.doFilter(Request("/pay", "INVALID"))  // 401

AuthFilter가 실패를 잡아내면 이후 필터는 건너뛴다. 체인 순서·구성은 런타임에 자유롭게 바꿀 수 있다.


5. 실무에서 보이는 체인들

  • Servlet Filter Chain – HTTP 요청을 여러 필터가 순서대로 가공하고 통과시키는 전형적인 예.
  • Spring Security Filter Chain – 인증·인가·CSRF 등 수십 개의 보안 필터가 ‘책임 연쇄’로 연결된다.
  • 로깅 & 미들웨어 스택 – SLF4J MDC 설정, 트레이싱, 모니터링까지 계층형으로 삽입.
  • 결제 프로세스 – 한 주문이 재고 확인→결제 승인→마일리지 적립→알림 발송 단계를 타고 흐른다.

6. 장단점 체크

  • 👍 유연성 : 핸들러 순서·유무를 설정 파일만으로도 조정 가능.
  • ⚠️ 주의 : 디버깅이 어렵다. 어느 단계에서 멈췄는지 로깅을 꼭 집어넣자.
반응형
Comments