코드/GOF

디자인 패턴 - 행위(Behavioral) 패턴 (3) 책임 연쇄 패턴(Chain Of Responsibility Pattern)

미로처럼 2024. 3. 18. 11:31
728x90

클라이언트의 요청에 대한 세세한 처리를 하나의 객체가 몽땅하는 것이 아닌 여러개의 처리 객체들로 나누고 이들을 사슬(chain)처럼 연결해 집합 안에서 연쇄적으로 처리하는 행동 패턴이다.

이러한 처리 객체들을 핸들러(handler)라고 부르는데, 요청을 받으면 각 핸들러는 요청을 처리할 수 있는지, 없으면 체인의 다음 핸들러로 처리에 대한 책임을 전가한다.

 

구조

 

 

Handler

  • 요청을 수신하고 처리 객체들의 집합을 정의하는 인터페이스

 

ConcreteHandler

  • 요청을처리하는 실제 처리 객체
    • 핸들러에 대한 필드를 내부에 가지고 있으며 메서드를 통해 다음 핸들러를 체인시키고 다음 바라본다.
    • 자신이 처리할 수 없는 요구가 나오면 바라보고 있는 다음 체인의 핸들러에게 요청을 떠넘긴다.
    • ConcreteHandler1 - ConcreteHandler2 - ConcreteHandler3 - ... 이런식으로 체인형식이 구성되게 된다.

 

Client

  • 요청을 Handler에 전달한다.

핸들러끼리 체이닝 되는 구조는 어떤 형태이든 상관이 없다. 리스트형 일수도 있고 선형 일 수도 있고 트리 형태일 수도 있다.

 

 

특징

 

사용시기

  • 특정 요청을 2개 이상의 여러 객체에서 판별하고 처리해야 할때
  • 특정 순서로 여러 핸들러를 실행해야 하는 경우
  • 프로그램이 다양한 방식과 종류의 요청을 처리할 것으로 예상되지만 정확한 요청 유형과 순서를 미리 알 수 없는 경우
  • 요청을 처리할 수 있는 객체 집합이 동적으로 정의되어야 할 때 (체인 연결을 런타임에서 동적으로 설정)

 

장점

  • 클라이언트는 처리 객체의 체인 집합 내부의 구조를 알 필요가 없다.
  • 각각의 체인은 자신이 해야하는 일만 하기 떄문에 새로운 요청에 대한 처리객체 생성이 편리해진다.
  • 클라이언트 코드를 변경하지 않고 핸들러를 체인에 동적으로 추가하거나 처리 순서를 변경하거나 삭제 할 수 있어 유연해진다.
  • 요청의 호출자(invoker)와 수신자(receiver)를 분리시킬 수 있다.
    • 요청을 하는 쪽과 요청을 처리하는 쪽을 디커플링 시켜 결합도를 낮춘다.
    • 요청을 처리하는 방법이 바뀌더라도 호출자 코드는 변경되지 않는다.

 

단점

  • 실행 시에 코드의 흐름이 많아져서 과정을 살펴보거나 디버깅 및 테스트가 쉽지 않다.
  • 충분한 디버깅을 거치지 않았을 경우 집합 내부에서 무한 사이클이 발생할 수 있다.
  • 요청이 반드시 수행된다는 보장이 없다. (체인 끝까지 갔는데도 처리되지 않을 수 있다.)
  • 책임 연쇄로 인한 처리 지연 문제가 발생할 수 있다. 다만 이는 트레이드 오프로서 요청과 처리에 대한 관계가 고정적이고 속도가 중요하면 책임 연쇄 패턴 사용을 유의하여야 한다.

 

 

 

 

 

 

 

 

728x90