Post

Behavioral_Chain Of Responsibility

โœ…

  • use the handler chain to handle request

  • client will only make request to the Interface Handler
  • inside the chain of concrete handlers, it will handle the request
  • ๐Ÿ‘๐Ÿป client will not know the logic behind request
  • even if logic changes, client does not have to be modified

  • ๐Ÿ‘๐Ÿป client(the class that makes the request) and the request handler is decoupled

  • the handler will
  • 1๏ธโƒฃ handle the request
  • 2๏ธโƒฃ pass it to the next handler in the chain

  • ๐Ÿ‘Ž๐Ÿป difficult to debug, we do not know in which handler the error is occuring

๐Ÿ‘€ Chain of Responsibility

Screenshot-2026-02-26-at-00-21-44.png

  • abstract class Request Handler
  • class PrintRequestHandler, LoggingRequestHandler, AuthRequestHandler extends Request Handler
  • ๐Ÿ™‹๐Ÿปโ€โ™€๏ธ Client: I want my request to be 1๏ธโƒฃ check authentication, if ok 2๏ธโƒฃ then log 3๏ธโƒฃ then print
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//step 1. Abstract class Request Handler
public abstract class RequestHandler {
    private RequestHandler nextHandler; //create chain of handlers

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

    public void handle(Request request){
        if(nextHandler != null){ //if next handler exsits
            nextHandler.handle(request); //call next handler
        }
    }
}

//step 2. create all the concrete handlers
public class AuthRequestHandler extends RequestHandler{
    public AuthRequestHandler(RequestHandler nextHandler) {
        super(nextHandler);
    }

    @Override
    public void handle(Request request) {
        System.out.println("Check authentication");
        super.handle(request);
    }
}

public class LoggingRequestHandler extends RequestHandler{
    //handle logic
}

public class PrintRequestHandler extends RequestHandler{
  //handle logic
}
  • client code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Client {
    private RequestHandler requestHandler;

    public Client(RequestHandler requestHandler) {
        this.requestHandler = requestHandler;
    }

    public void doWork(){
        Request request = new Request("Hello request");
        requestHandler.handle(request); //client does not know what the handler will do
    }

    public static void main(String[] args) {
        //create chain of handlers
        RequestHandler chain = new AuthRequestHandler(new LoggingRequestHandler(new PrintRequestHandler(null)));
        Client client = new Client(chain);
        client.doWork();
    }
}

  • result
1
2
3
4
5
Check authentication
Logging
Hello request

AuthRequestHandler ๐Ÿ‘‰๐Ÿป LoggingRequestHandler ๐Ÿ‘‰๐Ÿป PrintRequestHandler

๐Ÿ‘€ Simple example

  • logger class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//step 1. Logger class(handler)
abstract class Logger {
    protected int level;
    protected Logger nextLogger;

    public void setNextLogger(Logger nextLogger){
        this.nextLogger = nextLogger;
    }

    public void logMessage(int level, String message){
    }

    protected abstract void write(String message);
}

//step 2. concrete handlers
class ConsoleLogger extends Logger {
}
class ErrorLogger extends Logger {
}
1
2
3
4
5
6
7
8
9
10
11
12
13
//step 3. create the chain
public class Main {
    public static void main(String[] args) {

        Logger errorLogger = new ErrorLogger(Logger.ERROR);
        Logger consoleLogger = new ConsoleLogger(Logger.INFO);

        errorLogger.setNextLogger(consoleLogger);

        errorLogger.logMessage(Logger.INFO, "This is an info message.");
        errorLogger.logMessage(Logger.ERROR, "This is an error message.");
    }
}
  • client sends reqeust to errorLogger
  • errorLogger calls consoleLogger

๐Ÿ› ๏ธ

  • ๐Ÿ‘€ servlet filter
  • @WebFilter๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ /hello controller์— ๋“ค์–ด์˜ค๊ธฐ ์ „์— ๋ฏธ๋ฆฌ servelet component scan filter๋ฅผ ๊ฑฐ์น˜์„ธ์š”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// "/hello" ์ „์— ์ด WebFilter๋ฅผ ๊ฑฐ์ณ๋ผ
@WebFilter(urlPatterns = "/hello")
public class MyFilter implements Filter{
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException{
    chain.doFilter(request, response);
  }
}
//controller code
@RestController
public class HelloController{
  @GetMapping("/hello")
  public String hello(){
    return "hello";
  }
}
  • ๐Ÿ‘€ Security config
  • create filter chain
  • to http.autorizeRequest().anyRequest().permitAll().addFilter()...

โœ…

1๏ธโƒฃ

2๏ธโƒฃ

3๏ธโƒฃ

4๏ธโƒฃ

  • 1๏ธโƒฃ
  • 2๏ธโƒฃ
  • 3๏ธโƒฃ
  • 4๏ธโƒฃ ๐Ÿ‘๐Ÿป ๐Ÿ‘Ž๐Ÿป
1
2
3
โญ๏ธโญ๏ธโญ๏ธ EXAM โญ๏ธโญ๏ธโญ๏ธ
โ“
๐Ÿ‘‰๐Ÿป
This post is licensed under CC BY 4.0 by the author.