티스토리 뷰

디자인 패턴

13. 책임연쇄패턴

jin-park 2022. 2. 10. 19:57

1. 책임연쇄패턴

  • 요청을 보내는 쪽(sender)과 요청을 처리하는 쪽(receiver)를 분리하는 패턴
    • 핸들러 체인을 사용해서 요청을 처리한다

2. 패턴 적용 전

  • 목적에 따라 매번 클라이언트는 새로 작성된 클래스를 변경해주는 코드변경을 감수해야만 한다
  • 또한, 여러 개의 목적을 복합적으로 처리해야될 경우 새로운 문제에 봉착할 수 있다.
  • 책임연쇄 패턴을 적용할 경우, 위의 문제점들을 해결해나갈 수 있다.
@Data
public class Request {
 
    private String body;
 
    public Request(String body) {
        this.body = body;
    }
}
public class RequestHandler {
    public void handler(Request request) {
        System.out.println(request.getBody());
    }
}
public class LoggingRequestHandler extends RequestHandler {
    @Override
    public void handler(Request request) {
        System.out.println("로깅");
        super.handler(request);
    }
}
public class AuthRequestHandler extends RequestHandler {
    @Override
    public void handler(Request request) {
        System.out.println("인증이 되었나?");
        System.out.println("이 핸들러를 사용할 수 있는 유저인가?");
        super.handler(request);
    }
}
public class Client {
    public static void main(String[] args) {
        Request request = new Request("무궁화 꽃이 피었습니다.");
        RequestHandler requestHandler = new LoggingRequestHandler();
        requestHandler.handler(request);
    }
}

3. 패턴 적용 후 코드

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 LoggingRequestHandler extends RequestHandler {
 
    public LoggingRequestHandler(RequestHandler nextHandler) {
        super(nextHandler);
    }
 
    @Override
    public void handle(Request request) {
        System.out.println("로깅");
        super.handle(request);
    }
}
public class AuthRequestHandler extends RequestHandler {
 
    public AuthRequestHandler(RequestHandler nextHandler) {
        super(nextHandler);
    }
 
    @Override
    public void handle(Request request) {
        System.out.println("인증이 되었는가?");
        super.handle(request);
    }
}
public class PrintRequestHandler extends RequestHandler {
 
    public PrintRequestHandler(RequestHandler nextHandler) {
        super(nextHandler);
    }
 
    @Override
    public void handle(Request request) {
        System.out.println(request.getBody());
        super.handle(request);
    }
}
public class Client {
 
    private RequestHandler requestHandler;
 
    public Client(RequestHandler requestHandler) {
        this.requestHandler = requestHandler;
    }
 
    public void doWork() {
        Request request = new Request("이번 놀이는 뽑기입니다.");
        requestHandler.handle(request);
    }
 
    public static void main(String[] args) {
        // chaining
        RequestHandler chain = new AuthRequestHandler(new LoggingRequestHandler(new PrintRequestHandler(null)));
        Client client = new Client(chain);
        client.doWork();
    }
}

4. 장점 및 단점

4.1. 장점

  • 클라이언트 코드를 변경하지 않고 handler를 추가하거나 순서를 변경할 수 있다.

4.2. 단점

  • 디버깅이 어려울 수 있다.

위글은 인프런의 코딩으로 학습하는 GoF의 디자인 패턴강의를 정리하였습니다.

백기선님의 수락으로 정리하였으며 더 자세한 내용은 강의를 수강하시기 바랍니다.

https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard

 

코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

www.inflearn.com

 

'디자인 패턴' 카테고리의 다른 글

15. 인터프리터 패턴  (0) 2022.02.10
14. 커맨드 패턴  (0) 2022.02.10
12. 프록시 패턴  (0) 2022.02.10
11. 플라이 웨이트 패턴  (0) 2022.02.10
10. 퍼사드 패턴  (0) 2022.02.10
댓글