책임 연쇄 패턴

1 개요[ | ]

chain-of-responsibility pattern
책임 연쇄 패턴, 책임 사슬 패턴
  • 책임을 넘기는 구조
  • 명령 객체와 일련의 처리 객체를 포함하는 디자인 패턴
  • 핸들러 체인에 요청을 전달한다.
  • 각 핸들러는 요청을 처리하거나 다음 핸들러로 넘겨준다.
  • 적용사례
    • 인증 - 체인(인증방법 핸들러) 중 하나만 성공하면 종료, 다 실패하면 실패
    • 로거 - 체인(출력채널 핸들러) 중 원하는 채널과 맞으면 출력

2 구조[ | ]

W3sDesign Chain of Responsibility Design Pattern UML.jpg

  • 클래스 다이어그램에서
    • Sender 클래스는 직접 개별 Receiver 클래스를 참조하지 않는 대신, 요청을 처리(handler.handleRequest())하는 Handler 인터페이스를 참조한다.
    • Receiver1, Receiver2, Receiver3 클래스는 Handler 인터페이스를 구현하며, 런타임 상황에 따라 요청을 처리하거나 전달한다.
  • 시퀀스 다이어그램은 런타임 상호작용을 나타낸다.
    • Sender 객체는 receiver1 객체의 handleRequest()를 호출하고, receiver1은 요청을 receiver2에 전달하며, 결국 receiver3까지 전달되어 요청을 처리한다.

3 예제 (java)[ | ]

abstract class Logger {
    public static int ERR = 3;
    public static int NOTICE = 5;
    public static int DEBUG = 7;
    protected int mask;
 
    // The next element in the chain of responsibility
    protected Logger next;
 
    public Logger setNext(Logger log) {
        next = log;
        return log;
    }
 
    public void message(String msg, int priority) {
        if (priority <= mask) {
            writeMessage(msg);
        }
        if (next != null) {
            next.message(msg, priority);
        }
    }
 
    abstract protected void writeMessage(String msg);
}
 
class StdoutLogger extends Logger {
    public StdoutLogger(int mask) { 
        this.mask = mask;
    }
 
    protected void writeMessage(String msg) {
        System.out.println("Writing to stdout: " + msg);
    }
}
 
 
class EmailLogger extends Logger {
    public EmailLogger(int mask) {
        this.mask = mask;
    }
 
    protected void writeMessage(String msg) {
        System.out.println("Sending via email: " + msg);
    }
}
 
class StderrLogger extends Logger {
    public StderrLogger(int mask) {
        this.mask = mask;
    }
 
    protected void writeMessage(String msg) {
        System.err.println("Sending to stderr: " + msg);
    }
}
 
public class ChainOfResponsibilityExample {
    public static void main(String[] args) {
        // Build the chain of responsibility
        Logger logger, logger1;
        logger1 = logger = new StdoutLogger(Logger.DEBUG);
        logger1 = logger1.setNext(new EmailLogger(Logger.NOTICE));
        logger1 = logger1.setNext(new StderrLogger(Logger.ERR));
 
        // Handled by StdoutLogger
        logger.message("Entering function y.", Logger.DEBUG);
 
        // Handled by StdoutLogger and EmailLogger
        logger.message("Step1 completed.", Logger.NOTICE);
 
        // Handled by all three loggers
        logger.message("An error has occurred.", Logger.ERR);
    }
}
실행결과
  Writing to stdout:   Entering function y.
  Writing to stdout:   Step1 completed.
  Sending via e-mail:  Step1 completed.
  Writing to stdout:   An error has occurred.
  Sending via e-mail:  An error has occurred.
  Writing to stderr:   An error has occurred.

4 같이 보기[ | ]

5 참고[ | ]

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}