장점 : client 코드를 변경하지 않고 체인 추가 (OCP)
핸들러마다 자신이 해야할 코드 만 가지고있다. (SRP)
체인을 원하는대로 다양하게 조립할 수 있다.
단점 : 디버깅하기 번거롭다.
예시
client : Handler를 사용하는 객체 요청을 보낸다.
Handler : ConcreteHandler 의 공통 인터페이스를 정의한 클래스.
ConcreteHandler : 실제 Client가 사용하는 기능을 정의한 클래스로 Receiver(조립하는객체)가 조립하는 클래스
패턴 구현하기
public class Client {
private RequestHandler requestHandler;
public Client(RequestHandler requestHandler) {
this.requestHandler = requestHandler;
}
//요청 하는쪽 -> 실제 클라이언트
public void doWork() {//
Request request = new Request("Request Body");
requestHandler.handle(request);
}
}
public abstract class RequestHandler {
private RequestHandler nextHandler;
public RequestHandler(RequestHandler nextHandler) {
this.nextHandler = nextHandler;
}
public void handle(Request request) {
//다음 핸들러가 있을시에 실행하도록 함
if (nextHandler != null) {
nextHandler.handle(request);
}
}
}
public class AuthRequestHandler extends RequestHandler {
public AuthRequestHandler(RequestHandler nextHandler) {
super(nextHandler);
}
public void handle(Request request) {
System.out.println("인증");
super.handle(request);
}
}
public class Main {
public static void main(String[] args) {
//핸들러 조립
RequestHandler handler = new AuthRequestHandler(new LoggingRequestHandler(new PrintRequestHandler(null)));
Client client = new Client(handler);
client.doWork();
}
/**
*인증
*로깅
*Request Body
*/
}
@WebFilter(urlPatterns = "/hello") // 특정 url 서블릿에 접근할시 다음 필터를 적용
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("게임 참여");
chain.doFilter(request, response);
System.out.println("게임 끝");
}
}
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**
* 체인 필터를 설정하는 코드
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//모든 페이지의 접근권한을 인증없이 허가
http.authorizeRequests().anyRequest().permitAll();
//http.authorizeRequests().anyRequest().permitAll().and().addFilter(new MyFilter());
}
}
출처 : 백기선님의 디자인패턴