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

意图

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

示例代码

//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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值