[디자인 패턴] 책임 연쇄(Chain Of Responsibility) 패턴
책임 연쇄 패턴
책임 연쇄란, 핸들러의 체이닝을 따라서 요청을 전달해 주는 패턴이다. 각 핸들러가 요청을 받으면 요청을 처리할지 아니면 다음 체인의 핸들러로 전달할지 결정하여 실행됩니다. 흔히 커맨드 체이닝으로 불린다.
장점
클라이언트에서 체인 집합 내부를 알 필요가 없다. 각 체인은 자신이 할일만 하고 요청을 넘기기 때문에 처리 객체 생성이 편리하다. 또한, 처리 순서를 변경하거나 동적으로 체인을 추가할 수 있어 유연한 확장이 가능하다.
단점
실행 시 코드 흐름이 계속 전달되기 때문에 디버깅과 테스트가 쉽지 않다. 최악의 경우 무한 사이클이 일어날 수 있다. 요청이 수행되지 않을 수 있다. (마지막 체인에서 처리되지 않는다면…) 책임 연쇄로 인해 지연이 있을 수 있다.
위 장단점을 고려했을 때 처리 방식이 고정적이고, 속도가 중요한 시스템에서는 사용하지 않는 것이 좋다.
구현
우선 핸들러가 여러가지 존재하는데, 가독성을 위해 First, Second, 순으로 네이밍하였다.
public class Client {
public static void main(String[] args) {
Request request = new Request("");
RequestHandler requestHandler = new LogginRequestHandler();
requestHandler.handler(request);
}
}
public class RequestHandler {
public void handler(Request request) {
System.out.println(request.getBody());
}
}
위와 같이 클라이언트와 요청 핸들러가 존재하고, 아래와 같이 요청을 넘기고 실행하는 Handler 인터페이스를 구현한 핸들러에서 요청을 넘기게 된다.
public interface Handler {
void setNext(Handler handler); // 다음으로 Handler 지정
void handleRequest(Request request); // 할일하고 요청 넘긴다.
}
public class FirstHandler implements Handler {
private Handler nextHandler;
@Override
public void setNext(Handler handler) {
nextHandler = handler;
}
@Override
public void handleRequest(Request request) {
//할일 코드를 작성
System.out.println("1번 할일 끝!");
if(nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
public class SecondHandler implements Handler {
@Override
public void setNext(Handler handler) {
nextHandler = handler;
}
@Override
public void handleRequest(Request request) {
//할일 코드를 작성
System.out.println("2번 할일 끝!");
if(nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
이렇게 된 코드를 실제로 실행 시키면…
public class Main {
public static void main(String[] args) {
Handler firstHandler = new FirstHandler();
Handler secondHandler = new SecondHandler();
firstHandler.setNext(secondHandler);
Requst request = new Request();
firstHandler.handleRequest(request);
}
}
//출력
//1번 할일 끝!
//2번 할일 끝!
만약 request에 있는 인자에 접근하려면 각 핸들러 코드에서 request.getType()
등을 이용해서 가져올 수 있다.
Leave a comment