1、意图
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
2、适用性
在以下条件下使用Responsibility链:
1)有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
2)你想在不明确指定接受者的情况下,向多个对象中的一个提交一个请求。
3)可处理一个请求的对象集合应被动态指定。
3、C++实例
// Test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
typedef int Topic;
const Topic NO_HELP_TOPIC = -1;
const Topic PRINT_TOPIC = 1;
const Topic PAPER_ORIENTATION = 2;
const Topic APPLICATIOIN_TOPIC = 3;
// 基类
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;
};
HelpHandler::HelpHandler( HelpHandler *h, Topic t ):_successor(h),_topic(t)
{
}
bool HelpHandler::HasHelp()
{
return _topic != NO_HELP_TOPIC;
}
void HelpHandler::HandleHelp()
{
if ( 0 != _successor )
{
_successor->HandleHelp();
}
}
void HelpHandler::SetHandler( HelpHandler *h, Topic t)
{
_successor = h;
_topic = t;
}
class Widget:public HelpHandler
{
protected:
Widget( Widget *parent, Topic t = NO_HELP_TOPIC );
private:
Widget *_parent;
};
Widget::Widget( Widget *w, Topic t /*= NO_HELP_TOPIC */ ):HelpHandler(w,t)
{
_parent = w;
}
class Button:public Widget
{
public:
Button(Widget *d, Topic t = NO_HELP_TOPIC );
virtual void HandleHelp();
};
Button::Button( Widget *h, Topic t /*= NO_HELP_TOPIC */ ):Widget( h, t)
{
}
void Button::HandleHelp()
{
if ( HasHelp() )
{
cout<<"Button::HandleHelp"<<endl;
}
else
{
HelpHandler::HandleHelp();
}
}
class Dialog:public Widget
{
public:
Dialog(HelpHandler *d, Topic t = NO_HELP_TOPIC );
virtual void HandleHelp();
};
Dialog::Dialog( HelpHandler *h, Topic t /*= NO_HELP_TOPIC */ ):Widget( 0 )
{
SetHandler( h, t );
}
void Dialog::HandleHelp()
{
if ( HasHelp() )
{
cout<<"Dialog::HandleHelp"<<endl;
}
else
{
HelpHandler::HandleHelp();
}
}
class Application:public HelpHandler
{
public:
Application( Topic t ):HelpHandler( 0, t ){}
virtual void HandleHelp();
};
void Application::HandleHelp()
{
cout<<"Application::HandleHelp"<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Application *application = new Application( APPLICATIOIN_TOPIC );
Dialog *dialog = new Dialog( application, PRINT_TOPIC );
Button *button = new Button( dialog, PAPER_ORIENTATION );
button->HandleHelp();
button->SetHandler( dialog, NO_HELP_TOPIC );
button->HandleHelp();
delete button;
delete dialog;
delete application;
return 0;
}