책임 연쇄 (Chainable Responsibility) 패턴

Lee InnJie·2022년 8월 31일
0

Design Pattern

목록 보기
13/22

책임 연쇄 패턴

여기서의 책임은 단일 책임 원칙 의 책임과 같다. 특정한 책임을 가진 클래스들이 연쇄적으로 처리하는 패턴이다. 그리고 요청과 처리를 분리하는 패턴이다.


Code Example

Client

public class RequestHandler {
	public static void main(String[] args) {
		Request request = new Request("text");
		RequestHandler requestHandler = new AuthRquestHandler();
		requestHandler.handler(request);
	}
}

RequestHandler

public class RequestHandler {
	public void handler(Request request) {
		System.out.println("text");
	}
}

AuthRequestHandler

public class AuthRequestHandler extends RequestHandler {
	public void Handler(Request request) {
		System.out.println("111");
		System.out.println("222");

		super.handler(request);
	}
}

이렇게 구성된 코드는 단일 책임 원칙을 위배하지 않는다. 다만 어떤 클래스를 사용할 지 Client가 선택해야하기 때문에 코드가 변경된다.

책임 연쇄 패턴은 Handler라는 공동의 인터페이스 / 추상 클래스가 존재하고, 연결된 형태로 구현하게 된다. 각 클라이언트들은 어떤 핸들러들이 어떻게 만들어져 있는지는 알 필요가 없고, 요청만 전달한다. 이때 연쇄적으로 구현된 핸들러들을 통과하면서 특정한 핸들러에서 처리 후 종료된다.


Code Example - 2

RequestHandler

public abstract class RequestHandler {
	private RequestHandler nextHandler;

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

PrintRequestHandler

public class PrintRequestHandler extends RequestHandler {
	public PrintRequestHandler(RequestHandler nextHandler) {
		super(nextHandler);
	}
	@Override
	public void handler(Request request) {
		System.out.println(request.getBodey());
		super.handler(request);
	}
}

AuthHandler

public class AuthRquestHandler extends RequestHandler {
	public AuthRequestHandler (RequestHandler nextHandler){
		super(nextHandler);
	}
	@Override
	public void handle (Request request) {
		System.out.println("text");
		super.handle(request);
	}
}

Client

public class Client {
	private RequestHandler requestHandler;
	public Client (RequestHandler requestHandler) {
		this.requestHandler = requestHandler;
	}
	public void doWork() {
		Request request = new Request("text");
		requestHandler.handle(request);
	}
	public static void main(String[] args) {
		RequestHandler chain = new AuthRequestHandler(new PrintRequestHandler(null));
		Client client = new Client(chain);
		client.doWork();
	}
}

실행 결과는 AuthRequestHandler -> PrintRequestHandler 로 이루어진다.


장단점

장점

  • Client 를 변경하지 않고 새로운 핸들러를 추가할 수 있다.

단점

  • 디버깅이 번거롭다 (코드의 흐름 증가)

Example

Servlet Filter

필터 인터페이스는 두 필터가 필요하다. Servlet filterContainer로 들어오는 요청을 필터링하는 용도이고, 실제 요청을 처리하는 Servlet에 도달하기 전 Filter들을 거치며 과정 중 필터를 사용하게 된다.
전처리, 후처리도 가능하다.

Spring Security Filter

기본 필터들이 체인을 구성하고 있고, 필터의 일부 설정을 변경하거나 임의의 필터를 추가할 수 있다.

profile
⌒_⌒

0개의 댓글