温故知新(7)——职责链模式
<div id="cnblogs_post_body">概述初次听到职责链这个名词,你或许会有一种高深莫测的感觉,我当时就是这样。但如果深入的看下去,发现职责链还真是顾名思义,就是一系列具有相同职责的对象构成一个对象链,由这个对象链去处理一个请求。发出请求的客户端只需知道这个链可以处理这个请求,无需知道这个链的构成和排列。照例给出GOF的意图描述:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
职责链模式有两个要点:
1、存在多个请求的接收者;
2、多个接收者依次处理请求,此处包含了顺序的要求;
3、具体由哪个或哪些接收者处理这个请求可以在运行时决定;
在我理解GOF的意图描述,暗含了接收者要嘛处理请求,要嘛转交请求,也就是所谓的纯职责链。但我认为实际环境中应用更多的应该是非纯职责链,也就是每个接收者对象完成自己的处理操作,然后转交给下一个接收者。就像switch语句中的defult一样,实现时我们也应该提供一个defult接收者,以防止没有接收者处理请求而出错。关于纯职责链与非纯职责链的描述可以参看(http://blog.csdn.net/lovelion/article/details/7420902)。
职责链模式对发送请求的客户与接收请求的接收者进行的了解偶,同时为多个接收者的组织提供较大的灵活性。但是当职责链较长时应该考虑效率问题,实现时也应注意避免链闭合造成无限循环。
结构
职责链模式的类图:
http://images.cnblogs.com/cnblogs_com/zdy_bit/201209/201209111555386324.png
模式的参与者:
1、定义接受者共同职责的接口——IHandler;
2、接受者的具体实现——HandlerA,HandlerB;
3、客户端程序——Client;
注意IHandler上的自引用,IHandler通常会包含职责链下一环的引用。如果自引用的重数为1时,上图表示的就是经典的职责链;当重数为0…*时“职责链”就演化为“职责树”。关于职责树变体,读者可自行思考。
示例
本示例取自一个基金销售系统。为了吸引用户购买,系统通常需要为基金给出一些推荐标签,如果基金曾经获奖那么给出“获奖基金”的标签,如果业绩出色那么给出“业绩优秀”的标签;如果基金的规模比较大那么给出“规模大”的标签;如果某基金确实没有什么亮点,那么给一个默认的“在售”标签。这些标签的重要性依次降低。
考虑到,给出每种的标签的处理程序职责相同(给予或不给予标签)算法不不同,而且标签有顺序要求,未来这些处理程序可能有增减,因此使用职责链模式比较合适。
1、标签处理接口ILabelProcessor。
<div class="codearea linewrap"> 1:using System; 2: 3:namespace DesignPatterns.ChainOfResponsibility 4:{ 5: /// <summary> 6: /// 职责接口,所有处理者须实现 7: /// </summary> 8: public interface ILabelProcessor 9: {10: ILabelProcessor Successor { get; set; }11: void TakeLabel(Fund fund);12: }13:}14:
页:
[1]