意圖
使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理他爲止。
示例代碼
//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