设计模式之对象行为型模式 — CHAIN OF RESPONSIBILITY (职责链)模式

来源:互联网 发布:2017全球华人网络春晚 编辑:程序博客网 时间:2024/05/06 22:22

意图

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。

示例代码

//test.h 文件  #pragma once#include <iostream>using namespace std;typedef int Topic;const Topic NO_HELP_TOPIC = -1;class HelpHandler{public:    //@successor    后继者      //@topic        主题    HelpHandler(HelpHandler* successor = NULL, Topic topic = NO_HELP_TOPIC);    virtual bool HasHelp();     //是否有帮助信息       virtual void SetHandler(HelpHandler * successor, Topic topic);    virtual void HandleHelp();private:    HelpHandler *m_successor;   //后继者    Topic m_topic;};// 所有的窗口组件都是Widget 抽象类的子类  // Widget是Helphandler 的子类,所有的窗口组件都有帮助文档class Widget:public HelpHandler{public:    //@parent 父窗口 也是 职责链中的 后继者     Widget(Widget *parent, Topic topic = NO_HELP_TOPIC);protected:private:    Widget *m_parent;};class Button:public Widget{public:    Button(Widget *parent, Topic topic = NO_HELP_TOPIC);    virtual void HandleHelp();protected:private:};//Dialog的后继者不是窗口组件,而是任意的帮助请求处理对象。//在我们这个应用中这个后继者将是Application的一个实例class Dialog :public Widget{public:    Dialog(HelpHandler * successor,Topic topic=NO_HELP_TOPIC);    virtual void HandleHelp();protected:private:};//链的末端是Application的一个实例,该应用不是一个窗口组件。当帮助请求//传到这一层时,该应用可提供一般的信息class Application :public HelpHandler{public:    Application(Topic topic);    virtual void HandleHelp();protected:private:};//test.cpp  文件 #include "test.h"HelpHandler::HelpHandler(HelpHandler* successor /*=0*/, Topic topic/*=NO_HELP_TOPIC*/):m_successor(successor), m_topic(topic){}bool HelpHandler::HasHelp(){    return m_topic != NO_HELP_TOPIC;}void HelpHandler::SetHandler(HelpHandler * successor, Topic topic){    m_topic = topic;    m_successor = successor;}void HelpHandler::HandleHelp(){    if (m_successor != NULL)   //如果有后继者,则把请求传递给后继者    {        m_successor->HandleHelp();    }}/************************************************************************/Widget::Widget(Widget *parent, Topic topic /*= NO_HELP_TOPIC*/):HelpHandler(parent,topic){    m_parent = parent;}/******************************************************************/Button::Button(Widget *parent, Topic topic /*= NO_HELP_TOPIC*/):Widget(parent,topic){}void Button::HandleHelp(){    if (HasHelp())   //如果有帮助文档,则显示;如果没有,则传递到他的父类 即他的后继者    {        cout << "按钮帮助文档\n" << endl;    }    else    {        HelpHandler::HandleHelp();        }}Dialog::Dialog(HelpHandler * successor, Topic topic/*=NO_HELP_TOPIC*/):Widget(0)   //后继者并不是Widget  {    SetHandler(successor, topic);}void Dialog::HandleHelp(){    //如果有帮助文档,则显示;如果没有,则传递到他的父类 即他的后继者    if (HasHelp())    {        cout << "Dialog 的帮助文档  \n" << endl;    }    else    {        HelpHandler::HandleHelp();    }}/**********************************************************/Application::Application(Topic topic):HelpHandler(0,topic)    //没有后继者   {}void Application::HandleHelp(){    cout << "帮助目录\n 1. 按钮帮助\n2. 窗口帮助 \n" << endl;}---------------------------------------//main.cpp#include "test.h"int main(){    const Topic ONE_TOPIC = 1;    const Topic TOW_TOPIC = 2;    const Topic THREE_TOPIC = 3;    Application *app = new Application(ONE_TOPIC);    Dialog *dialog = new Dialog(app, TOW_TOPIC);    Button *button = new Button(dialog,NO_HELP_TOPIC);    button->HandleHelp();    getchar();    return 0;}

思路:

app是dialog的后继者 ; dialog 是button的后继者;

button帮助消息的传递路径:
button ->dialog->app
button 的topic = NO_HELP_TOPIC 即没有帮助 所以向 dialog传递 。


表示请求

表示请求可以不用像示例代码一样 直接写成 HandleHelp( ); 可以使用处理函数来处理更多的请求

代码框架

virtual void HandleRequest(Request * request)    {        switch (request->GetKind())        {        case Help:            /* .........  */            break;        case Print:            /*............*/            break;        default:            break;        }    }

效果

  • 减低耦合度
  • 增强了给对象指派职责的灵活性
  • 不保证被接受

我的个人网站 http://www.breeziness.cn/
我的CSDN http://blog.csdn.net/qq_33775402

转载请注明出处 小风code www.breeziness.cn

阅读全文
0 0
原创粉丝点击