现在的位置: 首页 > 综合 > 正文

设计模式入门学习 职责链模式

2018年01月11日 ⁄ 综合 ⁄ 共 1887字 ⁄ 字号 评论关闭

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

  组成:

  抽象处理者:它定义了一个处理请求的接口。

  具体处理者:实现抽象处理者的接口,并处理它所负责的请求,如果不能处理则请问它的后继者。

  纯的职责链模式,规定一个具体处理者对请求只能做两种动作:自己处理,传给下家。这里根据编码需求可以做些调整,比如:处理者可以对请求做部分处理,将其余部分传给下家处理。

  这种设计模式比较简单也比较常用,比如:UI框架中的事件处理,事件最先传给最子层的当前焦点控件,调用其处理事件的接口,不处理向其父节点传递,这样逐层链式传递形成一个职责链。

  代码示例:

class HelpHandler
	{
public:
	enum THelpTopic
		{
		EPRINT_HELP_TOPIC, 
		ECONFIRM_HELP_TOPIC,
		EAPPLICATION_HELP_TOPIC,
		ENO_HELP_TOPIC
		};
public:
	HelpHandler(HelpHandler* aHandler = NULL, THelpTopic aTopic = ENO_HELP_TOPIC)
	: iSuccessor(aHandler), 
	  iTopic(aTopic)
		{
	
		}
	
	virtual bool HasHelp() { return iTopic != ENO_HELP_TOPIC; }
	virtual void SetHandler(HelpHandler* aHandler, THelpTopic aTopic) 
		{ 
		iSuccessor = aHandler;
		iTopic = aTopic;
		}
	virtual void HandleHelp() 
		{ 
		if (iSuccessor) 
			iSuccessor->HandleHelp();
		}
	
private:
	THelpTopic iTopic;
	HelpHandler* iSuccessor;//后继
	};

class Widget : public HelpHandler
	{
protected:
	Widget(Widget* aParent, THelpTopic aTopic = ENO_HELP_TOPIC)
	: HelpHandler(aParent, aTopic),
	  iParent(aParent)
		{
	
		}
	
private:
	Widget* iParent;
	};

class Button : public Widget
	{
public:
	Button(Widget* aParent, THelpTopic aTopic = ENO_HELP_TOPIC)
	: Widget(aParent, aTopic)
		{
	
		}
	
	void HandleHelp()
		{
		if (HasHelp())
			{
			//显示自己help信息的代码,即链传递停止
			}
		else
			{
			HelpHandler::HandleHelp();//留给它的successor去处理
			}
		}
	};

class Dialog : public Widget
	{
	Dialog(HelpHandler* h, THelpTopic aTopic = ENO_HELP_TOPIC)
	: Widget(NULL)
		{
		SetHandler(h, aTopic);
		}
	
	void HandleHelp()
		{
		if (HasHelp())
			{
			//显示自己help信息的代码,即链传递停止
			}
		else
			{
			HelpHandler::HandleHelp();//留给它的successor去处理
			}
		}
	};

class Application : public HelpHandler
	{
public:
	Application(THelpTopic aTopic)
	: HelpHandler(NULL, aTopic){}
	
	void HandleHelp()
		{
		//显示自己help信息的代码,不再向下传递
		}
	};

//简单使用代码
Application* app = new Application(HelpHandler::EAPPLICATION_HELP_TOPIC);
Dialog* dialog = new Dialog(app, HelpHandler::EPRINT_HELP_TOPIC);
Button* button = new Button(dialog, HelpHandler::ECONFIRM_HELP_TOPIC);

//想要显示谁的help,只需要如下调用HandleHelp即可
button->HandleHelp();

  看了代码应该就很清晰了。职责链模式常与Composite组合模式一起使用。

抱歉!评论已关闭.