六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 342|回复: 0

温故知新(7)——职责链模式

[复制链接]

升级  93.33%

58

主题

58

主题

58

主题

秀才

Rank: 2

积分
190
 楼主| 发表于 2013-1-6 08:21:28 | 显示全部楼层 |阅读模式
<div id="cnblogs_post_body">概述

  初次听到职责链这个名词,你或许会有一种高深莫测的感觉,我当时就是这样。但如果深入的看下去,发现职责链还真是顾名思义,就是一系列具有相同职责的对象构成一个对象链,由这个对象链去处理一个请求。发出请求的客户端只需知道这个链可以处理这个请求,无需知道这个链的构成和排列。照例给出GOF的意图描述:
  
   使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
  职责链模式有两个要点:
  1、存在多个请求的接收者;
  2、多个接收者依次处理请求,此处包含了顺序的要求;
  3、具体由哪个或哪些接收者处理这个请求可以在运行时决定;
  在我理解GOF的意图描述,暗含了接收者要嘛处理请求,要嘛转交请求,也就是所谓的纯职责链。但我认为实际环境中应用更多的应该是非纯职责链,也就是每个接收者对象完成自己的处理操作,然后转交给下一个接收者。就像switch语句中的defult一样,实现时我们也应该提供一个defult接收者,以防止没有接收者处理请求而出错。关于纯职责链与非纯职责链的描述可以参看(http://blog.csdn.net/lovelion/article/details/7420902)。
  职责链模式对发送请求的客户与接收请求的接收者进行的了解偶,同时为多个接收者的组织提供较大的灵活性。但是当职责链较长时应该考虑效率问题,实现时也应注意避免链闭合造成无限循环。
  结构

  职责链模式的类图:
  
  模式的参与者:
  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:
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表