정기간행물/daily

Chain of Responsibility

:)jun 2023. 9. 26. 19:42

요약 : 여러 객체를 사슬처럼 연쇄적으로 묶고, 객체 사슬을 차례대로 돌면서 원하는 객체를 결정하는 방법

요청이 들어오고 요청을 처리할 수 있으면 처리하고 없으면 다음 사람에게 떠넘긴다.

클래스 목록

Trouble 트러블 클래스, 특정 번호(Number)를 갖는다.

Support 트러블을 해결하는 추상 클래스
NoSupport 트러블을 해결하는 구상 클래스(항상 No!)
LimitSupport 트러블을 해결하는 구상 클래스(지정한 번호 미만의 트러블만 Yes)
OddSupport 트러블을 해결하는 구상 클래스(홀수 번호만 Yes)
SpecialSupport 트러블을 해결하는 구상 클래스(특정 번호만 Yes)
Main 동작 테스트용 클래스

예제 프로그램의 클래스 다이어그램

Chain of Responsibility 패턴의 클래스 다이어그램


특징

1. 요구하는 사람과 처리하는 사람을 느슨하게 연결한다.

Client는 첫 번째 사람에게 요구하기만 하면 된다. 요구가 사슬을 흘러가다가 적절한 처리자에 의해 처리된다.

만약 이 패턴을 사용하지 않는다면 ‘이 요구는 이 사람이 처리해야 한다.’라는 정보를 누군가가 중앙집권적으로 가지고 있어야 한다. 해당 정보를 ‘요구하는 사람’이 갖는 것은 현명하지 못하다. (?)

→ 요구하는 사람이 세부적인 역할 분담까지 알아야 한다면, 부품으로서 독립성이 훼손되기 때문

 

2. 동적으로 사슬 형태를 바꾼다.

상황 변화에 따라 ConcreteHandler 역을 재편할 수 있다.

A → B → C 에서 B가 퇴사했을 때, A의 next를 C로 지정함으로서 A → C로 변경할 수 있다.

만약 이 패턴을 사용하지 않고 ‘이 요구에는 이 처리자’라는 식으로 대응 관계를 고정하면, 프로그램 실행 중에 처리자를 변경하기 어려워진다.

ex) 사용자가 앱 화면상에 컴포넌트(버튼이나 텍스트 입력 필드)를 자유롭게 추가할 수 있는 경우 이 패턴이 효과적이다.

 

3. 자기 일에 집중할 수 있다.

본인이 해결할 수 있는 범주 내의 문제라면 해결하고 아니라면 다음 사람에게 넘기면 된다. 이 패턴을 사용하지 않는다면 ‘자신이 처리하지 못하면 다른 사람에게 맡기고, 그래도 안되면 이 사람’과 같은 ‘일을 할당하는 책임’까지 개개의 ConcreteHandler 역에 부담시킬 수 밖에 없다.

 

4. 떠넘기기에 따른 지연

물론 누가 요구를 처리할지 미리 정해져 있고, 그 담당자가 바로 처리하는 것과 비교해서 이 패턴은 처리가 지연된다.

요구와 처리자의 관계가 고정적이고 처리 속도가 중요한 경우에는 해당 패턴을 사용하지 않는 것이 효과적일 수 있다.

요청이 들어오고 요청을 처리할 수 있으면 처리하고 없으면 다음 사람에게 떠넘긴다.