2020년 7월 7일 화요일

GOF Design Pattern - Chain of Responsibility





설명


메시지 송신 측과 수신 측을 분리 하는 것.

누가 결과적으로 메시지를 처리할 것인지는 모르기 때문에 상호작용이 단순화되고, 클래스당 책임을 할당하는데 유연해짐.

문제는 메시지 수신이 보장되도록 구조를 짜는게 힘듬.




예제 코드

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
typedef int Topic;
const Topic NO_HELP_TOPIC = -1;
 
class HelpHandler
{
public:
    HelpHandler(HelpHandler* h = 0, Topic t = NO_HELP_TOPIC) : _successor(h), _topic(t) {}
    
    virtual bool HasHelp() { return _topic != NO_HELP_TOPIC; }
    virtual void SetHandler(HelpHandler* h, Topic t) { _topic = t; _successor = h; }
    virtual void HandleHelp() { if (_successor != 0) _successor->HandleHelp(); }
 
private:
    HelpHandler* _successor;
    Topic _topic;
};
 
class Widget : public HelpHandler
{
protected:
    Widget(Widget* w, Topic t = NO_HELP_TOPIC) : HelpHandler(w, t) { }
};
 
class Button : public Widget
{
public:
    Button(Widget* d, Topic t = NO_HELP_TOPIC) : Widget(d, t) {}
 
    virtual void HandleHelp() 
    {
        std::cout << "Button Send Topic" << std::endl;
        if (HasHelp())
            std::cout << "Button Handle Help" << std::endl;
        else HelpHandler::HandleHelp(); 
    }
};
 
class Dialog : public Widget
{
public:
    Dialog(HelpHandler* h, Topic t = NO_HELP_TOPIC) : Widget(0) { SetHandler(h, t); }
    virtual void HandleHelp() 
    {
        std::cout << "Dialog Send Topic" << std::endl;
        if (HasHelp())
            std::cout << "Dialog Handle Topic" << std::endl;
        else HelpHandler::HandleHelp(); }
};
 
class Application : public HelpHandler
{
public:
    Application(Topic t) : HelpHandler(0, t) {}
 
    virtual void HandleHelp() { std::cout << "App Handle Topic" << std::endl; }
};
cs


1
2
3
4
5
6
7
8
9
10
void main()
{
    const Topic Application_Topic = 3;
 
    Application* application = new Application(Application_Topic);
    Dialog* dialog = new Dialog(application, NO_HELP_TOPIC);
    Button* button = new Button(dialog, NO_HELP_TOPIC);
 
    button->HandleHelp();
}
cs

HelpHander 나 Widget 은 사실상 같은 것임. 

Application 을 Widget 이라고 말하기 뭐해서 클래스를 분리해놓은 것.

main 을 보면 알겠지만, Application 가 부모노드인 리스트 형태를 띄고 있음.



HandlerHelp() 함수의 의미는 도움말 창을 띄어달라는 것임.

위 상황은 Application 외에는 NO_HELP_TOPIC 으로 HandlerHelp() 를 혼자 처리 못함.

즉 버튼 대화상자 모두 처리를 할 수 없으니 Application 이 처리할 것임.


이렇게.





추가 설명

 Composite 패턴과 같이 잘 쓰임.

 이 경우 Composite 들의 후속 처리자가 Component 가 될 것임.





댓글 없음:

댓글 쓰기

List