책임연쇄(chain-of-responsibility ) 패턴

책임 연쇄 패턴은 요청을 처리할 수 있는 객체의 연쇄를 구성하여 요청을 처리하는 디자인 패턴입니다. 이 패턴을 사용하면 요청을 보내는 객체와 요청을 처리하는 객체 사이의 결합도를 낮출 수 있으며, 요청 처리 과정을 유연하게 구성할 수 있습니다. 책임 연쇄를 통해 여러 객체에게 요청을 전달하고 처리할 수 있으며, 각 객체는 요청을 처리하거나 다음 객체로 전달할 책임을 가집니다.

구성 요소

핸들러(Handler): 요청을 처리하는 인터페이스를 정의하고, 다음 핸들러를 참조하는 역할을 수행합니다.
클라이언트(Client): 요청을 생성하고 핸들러 체인의 첫 번째 핸들러에게 요청을 전달합니다.

구현:

  1. 핸들러 인터페이스를 정의합니다. 이 인터페이스는 요청을 처리하는 메서드를 포함합니다.
  2. 다음 핸들러를 참조하는 멤버 변수를 가지는 핸들러 클래스를 생성합니다. 핸들러 클래스는 핸들러 인터페이스를 구현하며, 요청을 처리할 수 있는 메서드를 구현합니다.
  3. 클라이언트에서는 요청을 생성하고 첫 번째 핸들러에게 요청을 전달합니다.
  4. 핸들러는 다음 핸들러를 참조하는 멤버가 존재하면, 요청을 전달하고, 없으면 작업을 종료합니다.

장점

요청을 처리하는 객체의 연쇄를 구성하여 결합도를 낮출 수 있습니다.
요청 처리 과정을 유연하게 구성할 수 있으며, 동적으로 핸들러를 추가하거나 제거할 수 있습니다.
클라이언트와 요청 처리 객체 사이의 결합도를 낮추고, 유연한 상호작용을 가능하게 합니다.

단점

핸들러 체인이 길어지거나 핸들러의 수가 많아질 경우, 처리 과정이 복잡해질 수 있습니다.

예시

요청이 들어오면 인증/인가를 실행하고 로그를 남긴후 요청을 처리해야한다.

Handler

public abstract class RequestHandler {

    private final RequestHandler nextHandler;

    protected RequestHandler (RequestHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public void handler(Request request) {
        if(nextHandler != null){
            nextHandler.handler(request);
        }
    }
}

public class DefaultRequestHandler extends RequestHandler {

    public DefaultRequestHandler(RequestHandler requestHandler) {
        super(requestHandler);
    }

    public void handler(Request request) {
        System.out.println(request.getBody());
        super.handler(request);
    }
}

public class AuthRequestHandler extends RequestHandler {

    public AuthRequestHandler(RequestHandler requestHandler) {
        super(requestHandler);
    }

    public void handler(Request request) {
        System.out.println("인증이 되었나?");
        System.out.println("이 핸들러를 사용할 수 있는 유저인가?");
        super.handler(request);
    }
}

public class LoggingRequestHandler extends RequestHandler {

    public LoggingRequestHandler(RequestHandler requestHandler) {
        super(requestHandler);
    }

    @Override
    public void handler(Request request) {
        System.out.println("로깅");
        super.handler(request);
    }
}

Client

class RequestHandlerTest {

    @Test
    public void handler_test() {
        Request request = new Request("무궁화 꽃이 피었습니다.");
        RequestHandler requestHandler = new AuthRequestHandler(new LoggingRequestHandler(new DefaultRequestHandler(null)));
        requestHandler.handler(request);
    }

}

결론

책임 연쇄 패턴은 요청을 처리할 수 있는 객체의 연쇄를 구성하여 요청을 처리하는 디자인 패턴입니다. 이를 통해 요청 처리 과정을 유연하게 구성하고, 요청을 보내는 객체와 요청을 처리하는 객체 사이의 결합도를 낮출 수 있습니다.

예제는 이곳 에서 확인하실수 있습니다.