Chain of Responsibility (책임 연쇄 패턴)


> 특징

· 각각의 처리객체들이 명령객체들을 처리하는 연산 집합. 책임을 떠넘긴다.

· 체인 안의 처리객체가 핸들 하지 못하는 경우 다음 객체로 넘긴다. 체인 끝까지 반복.

· 복수의 객체를 chain으로 연결해 두면, 그 객체의 사슬을 차례로 돌아다니면서 목적한 객체를 결정하는 방법이다. 

사슬의 순서는 동적으로 변경 가능하다.

· 요구를 하는 사람(Client)와 요구를 처리하는 사람(ConcreteHandler)을 유연하게 연결.

· '이 요구는 이 사람이 처리해야 한다' 라는 정보를 중앙집권적으로 가지고 있지 않게 한다. 

· 요구를 하는 사람이 처리자들의 역할 분담까지 자세하게 알 필요가 없음.




> 패턴 구성자


1. Handler(처리자)

· 요구를 처리하는 API결정. 다음 처리객체를 가르키는 Next 변수 선언, setNext() 메소드구현. 

2. ConcreteHandler(구체적인 처리자)

· 각 요구에 대한 구체적인 처리 방법 명시, 구체화.

3. Client(요구자)





> 다이어그램


 





[예]

- 로그를 생성하는 로그 핸들러


1. 추상클래스(Handler)

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
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);
}
cs


2. stdoutLogger(concreteHandler)


1
2
3
4
5
6
7
8
9
class StdoutLogger extends Logger {
    public StdoutLogger(int mask) {
        this.mask = mask;
    }
 
    protected void writeMessage(String msg) {
        System.out.println("Writing to stdout: " + msg);
    }
}
cs

3. stderrLogger(concreteHandler)

1
2
3
4
5
6
7
8
9
class StderrLogger extends Logger {
    public StderrLogger(int mask) {
        this.mask = mask;
    }
 
    protected void writeMessage(String msg) {
        System.err.println("Sending to stderr: " + msg);
    }
}
cs


4. Client main()


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ChainOfResponsibilityExample {
    public static void main(String[] args) {
        
        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);
    }
}

cs



[참고]

https://ko.wikipedia.org/wiki/%EC%B1%85%EC%9E%84_%EC%97%B0%EC%87%84_%ED%8C%A8%ED%84%B4

'Design Pattern' 카테고리의 다른 글

Command 패턴  (0) 2018.02.08

+ Recent posts