意图
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。
示例代码
//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