意图:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
适用性:
1有多个的对象可以处理一个请求,哪个独享处理该请求运行时刻自动决定
2在不确定接受者的情况下,向多个对象中的一个提交一个请求
3处理一个请求的对象集合被动态指定
效果:
1降低耦合度 使得一个对象无需知道是其他哪一个对象处理请求。接收方和发送方都没有对方的明确信息,且链中对象不需知道链的结构
2增强了给对象指派职责的灵活性 当在对象中分派职责时,职责链给你更大的灵活性,可以通过在运行时刻对该链进行动态的增加或修改来增加或改变处理一个请求的那些职责
3不保证被接受
Chain.h
- typedef int Topic;
- const Topic NO_HELP_TOPIC = -1;
- class HelpHandler
- {
- public:
- HelpHandler(HelpHandler* = 0,Topic = NO_HELP_TOPIC);
- virtual bool HasHelp();
- virtual void SetHandler(HelpHandler*,Topic);
- virtual void HandleHelp();
- private:
- HelpHandler* _successor;
- Topic _topic;
- };
- class Widget:public HelpHandler
- {
- protected:
- Widget(Widget* parent,Topic t = NO_HELP_TOPIC);
- private:
- Widget* _parent;
- };
- class Button: public Widget
- {
- public:
- Button(Widget* d,Topic t = NO_HELP_TOPIC);
- virtual void HandleHelp();
- };
- class Dialog:public Widget
- {
- public:
- Dialog(HelpHandler* h,Topic t =NO_HELP_TOPIC);
- virtual void HandleHelp();
- };
- class Application:public HelpHandler
- {
- public:
- Application(Topic t):HelpHandler(0,t){}
- virtual void HandleHelp();
- };
Chain.cpp
- #include "Chain.h"
- #include <iostream>
- #include <string>
- using namespace std;
- HelpHandler::HelpHandler(HelpHandler* h,Topic t):_successor(h),_topic(t)
- {
- }
- void HelpHandler::HandleHelp()
- {
- if (_successor != 0)
- {
- _successor->HandleHelp();
- }
- }
- bool HelpHandler::HasHelp()
- {
- return _topic != NO_HELP_TOPIC;
- }
- void HelpHandler::SetHandler(HelpHandler* h,Topic t)
- {
- _successor = h;
- _topic = t;
- }
- Widget::Widget(Widget* parent,Topic t ):HelpHandler(parent,t)
- {
- _parent = parent;
- }
- Button::Button(Widget* parent,Topic t):Widget(parent,t){}
- void Button::HandleHelp()
- {
- if (HasHelp())
- {
- cout<<"Provide Button Level Help"<<endl;
- }
- else
- {
- HelpHandler::HandleHelp();
- }
- }
- Dialog::Dialog(HelpHandler* h,Topic t):Widget(0)
- {
- SetHandler(h,t);
- }
- void Dialog::HandleHelp()
- {
- if (HasHelp())
- {
- cout<<"Provide Dialog Level Help"<<endl;
- }
- else
- {
- HelpHandler::HandleHelp();
- }
- }
- void Application::HandleHelp()
- {
- cout<<"Show a list of Help topics"<<endl;
- }
main.cpp
- #include "Chain.h"
- #include <iostream>
- #include <string>
- using namespace std;
- int main()
- {
- const Topic PRINT_TOPIC = 1;
- const Topic PAPER_ORIENTATION_TOPIC = 2;
- const Topic APPLICATION_TOPIC = 3;
- Application* application = new Application(APPLICATION_TOPIC);
- Dialog* dialog1 = new Dialog(application,PRINT_TOPIC);
- Button* button1 = new Button(dialog1,PAPER_ORIENTATION_TOPIC);
- Button* button2 = new Button(dialog1,NO_HELP_TOPIC);
- Dialog* dialog2 = new Dialog(application,NO_HELP_TOPIC);
- button1->HandleHelp();
- button2->HandleHelp();
- //button3->HandleHelp();
- dialog1->HandleHelp();
- dialog2->HandleHelp();
- return 0;
- }