책임 연쇄 패턴은 여러 객체들이 순차적으로 요청을 처리할 기회를 가지는 패턴이다.
각 객체는 처리할 수 있는 범위에 따라 요청을 처리할 수 있고, 처리하지 못하면 다음 객체로 요청을 넘겨 처리하도록 한다.
이를 통해 객체 간의 결합도를 낮추고, 유연한 요청 처리 구조를 제공할 수 있다.
보통 프로그램은 요청을 처리할 객체를 명확히 지정해야 하지만, 특정 객체에 요청을 고정시키면 유연성이 떨어진다.
예를 들어, 다양한 조건에 따라 여러 객체가 처리할 수 있는 상황이 있을 때, 요청을 처리할 객체를 고정시키면 코드가 복잡해지고 유지보수가 어려워질 수 있다.
책임 연쇄 패턴을 사용하면 다음과 같은 장점을 얻을 수 있다:
고객이 회사에 문의할 때, 문의 내용에 따라 다양한 부서에서 처리될 수 있다.
예를 들어, 일반적인 문의는 고객 상담 부서에서 처리하지만, 기술적인 문제는 기술 지원팀에서 처리하고, 재무 관련 문제는 재무팀에서 처리해야 한다.
이런 경우 책임 연쇄 패턴을 사용하면 각 부서가 요청을 처리할 수 있도록 연쇄적으로 연결하여, 각 부서가 적절히 문의를 처리하도록 만들 수 있다.
handleRequest()
메서드를 정의한다. 각 객체는 다음 처리 객체를 가리키는 참조를 갖고 있다.Client
└─ Handler (인터페이스)
├─ ConcreteHandler1
├─ ConcreteHandler2
└─ ConcreteHandler3
└─ 처리할 객체가 없을 때 요청이 종료됨
고객 문의를 처리하는 시스템을 예시로 책임 연쇄 패턴을 적용해 보겠다.
각 부서(일반 문의, 기술 지원, 재무팀)가 연쇄적으로 연결되어, 각 부서가 처리할 수 있는 범위 내에서 문의를 처리하거나, 다음 부서로 넘기게 된다.
// Handler 인터페이스
abstract class SupportHandler {
protected SupportHandler nextHandler;
public void setNextHandler(SupportHandler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(String request);
}
// ConcreteHandler: 일반 문의 처리
class GeneralSupportHandler extends SupportHandler {
@Override
public void handleRequest(String request) {
if (request.equals("일반 문의")) {
System.out.println("일반 문의 처리: 고객 상담 부서에서 처리합니다.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// ConcreteHandler: 기술 지원 처리
class TechnicalSupportHandler extends SupportHandler {
@Override
public void handleRequest(String request) {
if (request.equals("기술 지원")) {
System.out.println("기술 지원 처리: 기술 지원팀에서 처리합니다.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// ConcreteHandler: 재무 문제 처리
class FinancialSupportHandler extends SupportHandler {
@Override
public void handleRequest(String request) {
if (request.equals("재무 문제")) {
System.out.println("재무 문제 처리: 재무팀에서 처리합니다.");
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 클라이언트 코드
public class Main {
public static void main(String[] args) {
// 핸들러 체인 설정
SupportHandler generalSupport = new GeneralSupportHandler();
SupportHandler technicalSupport = new TechnicalSupportHandler();
SupportHandler financialSupport = new FinancialSupportHandler();
generalSupport.setNextHandler(technicalSupport);
technicalSupport.setNextHandler(financialSupport);
// 요청 처리
generalSupport.handleRequest("일반 문의"); // 출력: 일반 문의 처리: 고객 상담 부서에서 처리합니다.
generalSupport.handleRequest("기술 지원"); // 출력: 기술 지원 처리: 기술 지원팀에서 처리합니다.
generalSupport.handleRequest("재무 문제"); // 출력: 재무 문제 처리: 재무팀에서 처리합니다.
}
}
setNextHandler()
메서드를 통해 체인을 설정하고, handleRequest()
메서드에서 요청을 처리한다.일반 문의 처리: 고객 상담 부서에서 처리합니다.
기술 지원 처리: 기술 지원팀에서 처리합니다.
재무 문제 처리: 재무팀에서 처리합니다.
책임 연쇄 패턴은 여러 객체들이 요청을 처리할 기회를 가지는 패턴으로, 객체 간의 결합도를 줄이고 요청 처리 과정을 유연하게 만들 수 있다.
각 객체는 자신이 처리할 수 있는 요청만 처리하고, 그렇지 않으면 다음 객체로 넘기며, 클라이언트는 어느 객체가 요청을 처리할지 알 필요 없이 체인만 설정하면 된다.
아래 글에서 다른 디자인 패턴들을 확인할 수 있다.
디자인 패턴 모음