[设计模式笔记]三. 行为型模式--15.Chain Of Responsibility(职责链模式)(二)

场景:


根据自己的理解和书上的例子假设了这样的场景

在一个程序中F1, 程序显示出鼠标所在的区域的帮助信息

例如鼠标在对话框的左上角区域则显示对话框的帮助信息XXX. 鼠标在对话框的左上角区域的按钮上时也是显示对话框的帮助信息XXX. (总之是在鼠标的左上角上无论在不在控件上)


角色:


CMyAPP 程序类控制整个程序的运行

CMyDialog 对话框类CMyAPPlive上实例化. CMyDialog中包含各种控件(CMyButton, CMyEdit)

CMyButton 按钮控件CMyDialog上实例化.

CMyEdit 编辑框控件CMyDialog上实例化.

显示帮助信息使用Chain Of Responsibility模式,  Chain Of Responsibility模式中, CMyDialog与控件之间的包含关系可以使用Composite模式.

如图:


图1


代码:


class HelpHandler
{
public:
	HelpHandler();
	virtual ~HelpHandler();
	virtual void HandleHelp();
	void SetNextHandleHelp(HelpHandler* pHelpHandler);
private:
	HelpHandler* m_pNextHelpHandler;
}

...
void HelpHandler::HandleHelp()
{
	if(m_pNextHelpHandler)
	{
		m_pNextHelpHandler->HandleHelp();
	}
}
void HelpHandler::SetNextHandleHelp(HelpHandler* pHelpHandler)
{
	m_pNextHelpHandler = pHelpHandler;
}

///

class CMyWnd
{
public:
	CMyWnd();
	virtual ~CMyWnd();
	virtual void HandleHelp();
}

...
void CMyWnd::HandleHelp()
{
	HelpHandler::HandleHelp();
}

///
class CMyDialog
{
public:
	CMyDialog();
	virtual ~CMyDialog();
	virtual void HandleHelp();
	void MyShowHelp1();
	void MyShowHelp2();
private:
	CMyButton* m_pCMyButton;
	CMyEdit* m_pCMyEdit;
}

CMyDialog::CMyDialog()
{
	// 生成责任链(m_pCMyButton -->>> m_pCMyEdit -->>> this)
	m_pCMyButton = new CMyButton;
	m_pCMyEdit = new CMyEdit;
	m_pCMyButton->SetNextHandleHelp(m_pCMyEdit);
	m_pCMyEdit->SetNextHandleHelp(this);
}

void CMyDialog::HandleHelp()
{
	// Show Help Information
	::MessageBox(.....);
	// 责任人链到这里结束.
	// 这里没有判断m_pNextHelpHandler, 让HandleHelp继续下去了.
}

// 触发
void CMyDialog::MyShowHelp1()
{
	m_pCMyButton->HandleHelp();
}

// 触发
void CMyDialog::MyShowHelp2()
{
	m_pCMyEdit->HandleHelp();
}

///

class CMyButton
{
public:
	CMyButton();
	virtual ~CMyButton();
}
...

class CMyEdit
{
public:
	CMyEdit();
	virtual ~CMyEdit();
}
...
///

在这里调用时如果鼠标触发到CMyDialog的调用时将会调用void CMyDialog::MyShowHelp1()void CMyDialog::MyShowHelp(), 如果直接触发到CMyButton或者CMyEdit, 则将会调用CMyWnd::HandleHelp()

// 


我的理解:


1. 在继承方向上(HelpHandler >>> CMyWnd >>> (CMyDialog, CMyButton, CMyEdit))通过重载HandleHelp, 可以在纵向把HandleHelp连接起来. 例如CMyButton::HandleHelp可以不做任何东西, 也可以做一些东西然后传递给它的父类CMyWnd::HandleHelp, 也可以不传递


2. 在责任链方向上这里是(CMyButton -->>> CMyEdit -->>> CMyDialog), 通过责任链横向的把HandleHelp连接起来. 例如CMyButton可以处理一些事情也可以不处理然后传递给它的下家而且通过责任链责任链上的对象并不需要和它的下家的类耦合在一起(CMyButton并不需要知道CMyEditCMyDialog)


3. 我理解是如果说继承链上的重载叫纵向重载责任链是不是可以叫"横向重载"(看一看图1)


4. 在该场景中责任链的责任关系是静态的因为代码把这种关系固定下来的了就是CMyDialog负责处理帮助信息, CMyButtonCMyEdit只负责传递给它的下家而不作其它任何处理当然责任链上的对象是可以动态的(例如运行时责任两CMyButton对象|CMyEdit对象|CMyButton对象|CMyDialog对象| )


5. 责任链的责任关系也可以使动态的增加请求类型即可在自己的HandleHelp判断请求类型来判断是否处理还是向下传递.


6. 注意责任链的构造(CMyDialog::CMyDialog()的实现)


7. 在这里没有使用上Composite模式因为责任链最终的处理都是在CMyDialog::HandleHelp()如果使用Composite模式就会死循环了.

例如Composite模式的话就是这样了

void CMyDialog::HandleHelp()
{
	m_pCMyButton->HandleHelp();
	m_pCMyEdit->HandleHelp();
}

只能说这个场景不适合使用Composite模式如果是最终是在CMyApp::HandleHelp处理的话就可以总之就是不能死循环.



8. 不使用继承使用包含可以吗

我的理解是这样:



图2

每个类多了一个HelpHandler在各个HelpHandler类中还是用到了继承关系HelpHandler类在各自对应的类中创建(使用某创建模式). 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值