2023.08.25

책임 연쇄 패턴

책임 연쇄란, 핸들러의 체이닝을 따라서 요청을 전달해 주는 패턴이다. 각 핸들러가 요청을 받으면 요청을 처리할지 아니면 다음 체인의 핸들러로 전달할지 결정하여 실행됩니다. 흔히 커맨드 체이닝으로 불린다.


장점

클라이언트에서 체인 집합 내부를 알 필요가 없다. 각 체인은 자신이 할일만 하고 요청을 넘기기 때문에 처리 객체 생성이 편리하다. 또한, 처리 순서를 변경하거나 동적으로 체인을 추가할 수 있어 유연한 확장이 가능하다.


단점

실행 시 코드 흐름이 계속 전달되기 때문에 디버깅과 테스트가 쉽지 않다. 최악의 경우 무한 사이클이 일어날 수 있다. 요청이 수행되지 않을 수 있다. (마지막 체인에서 처리되지 않는다면…) 책임 연쇄로 인해 지연이 있을 수 있다.


위 장단점을 고려했을 때 처리 방식이 고정적이고, 속도가 중요한 시스템에서는 사용하지 않는 것이 좋다.


구현

우선 핸들러가 여러가지 존재하는데, 가독성을 위해 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