首页 > 代码库 > 编程模式之十四----行为型----职责链模式

编程模式之十四----行为型----职责链模式

 

 

 定义

   避免把一个请求的发送者和接收者耦合在一起,使多个对象都有机会处理请求。将这个请求的多个接收着连接成一条链,并让请求沿着这个链传递下去,只到有一个结点能处理请求。

  职责链模式中,链形成后,不一定非要有一个结点能够处理请求,也就是说,所有结点都可以处理一下再往下传,也可以都不处理,这样说来就比较灵活了。

 组成

   抽象处理者:AbstractHandler。维护一个对自身类型对象的引用,这个引用作为下一个具体的处理者。声明所有处理者都用到的方法,这个方法的作用是设置本处理者后面的一个处理者。另外声明一个处理请求的方法。

  具体处理者:Handler。实现设置下一个处理者的方法。实现处理请求的方法,也就是业务方法。

 一个例子

   以我们公司的请假过程为例子,我们公司的请假审批过程是这样的:请不多于1天,只用主管(Supervisor)审批就可以了;请不多于3天,而大于1天,就需要部门经理(DepartmentManager)审批;请假超过3天,就需要总经理(GeneralManager)审批了。

  抽象处理者设计为Manager,包含主管,经理和总经理。具体处理者就是上面三位:主管,经理,总经理。这里的请求就是请假这个事。  

  代码如下:

 1     /// <summary> 2     /// 抽象管理者类 3     /// </summary> 4     abstract class Manager 5     { 6         //维护下一个管理者的引用 7         public Manager manager = null; 8         /// <summary> 9         /// 设置下一个管理者的方法,也是下一个处理者10         /// </summary>11         /// <param name="manager"></param>12         public abstract void SetNextHandler(Manager manager);13         /// <summary>14         /// 业务方法,怎么处理请假这件事15         /// </summary>16         public abstract void HandlerLeave(int days);17     }18     /// <summary>19     /// 主管处理者20     /// </summary>21     class Supervisor : Manager22     {23         public override void SetNextHandler(Manager manager)24         {25             this.manager = manager;26         }27         public override void HandlerLeave(int days)28         {29             if (days <= 1)30             {31                 Console.WriteLine("主管处理了请假:允许");32             }33             else34             {35                 Console.WriteLine("主管没有权力,交给部门经理处理");36                 this.manager.HandlerLeave(days);37             }38         }39     }40     /// <summary>41     /// 部门经理处理者42     /// </summary>43     class DepartmentManager : Manager44     {45         public override void SetNextHandler(Manager manager)46         {47             this.manager = manager;48         }49         public override void HandlerLeave(int days)50         {51             if (days <= 3)52             {53                 Console.WriteLine("部门经理处理了请假:允许");54             }55             else56             {57                 Console.WriteLine("部门经理没有权力,交给总经理处理");58                 this.manager.HandlerLeave(days);59             }60         }61     }62     /// <summary>63     /// 总经理处理者64     /// </summary>65     class GeneralManager : Manager66     {67         public override void SetNextHandler(Manager manager)68         {69             this.manager = manager;70         }71         public override void HandlerLeave(int days)72         {73             if (days <= 10)74             {75                 Console.WriteLine("总经理处理了请假:允许");76             }77             else78             {79                 Console.WriteLine("总经理处理了请假:时间太长,不允许");80             }81         }82     }

   客户端代码如下:

 1        static void Main(string[] args) 2         { 3             Manager supervisor = new Supervisor(); 4             Manager departManager = new DepartmentManager(); 5             Manager generalManager = new GeneralManager(); 6             //设置主管的下一个处理者:部门经理 7             supervisor.SetNextHandler(departManager); 8             //设置总店经理的下一个处理者:总经理 9             departManager.SetNextHandler(generalManager);10             //职责链形成,开始处理11 12             int days1 = 1;13             int days2 = 2;14             int days3 = 3;15             int days4 = 4;16             int days5 = 11;17 18             supervisor.HandlerLeave(days5);//使用11天测试19             Console.Read();20         }

  使用11天测试,结果如下:

主管没有权力,交给部门经理处理
部门经理没有权力,交给总经理处理
总经理处理了请假:时间太长,不允许

  注意:链的创建是由客户端来完成的,客户端有能力改变处理者的处理次序。

 一些扩展

   其实,在上面的例子中,主管和部门经理都做了处理,无论处理的结果是怎么样的,总之是做了处理。这种有叫做不纯的职责链模式

如果主管和部门经理一看时间,只接不批示的话,也就是说不做处理的话,只让大boss处理,又叫做纯的职责链模式

  在实际做程序时,异常处理时,有时会用到以下过程:

1            try2             {3             }4             catch (Exception ex)5             {6                 Console.WriteLine(ex.Message);7                 throw new Exception(ex.Message + "某某处理错误");8             }

   在第一次捕获异常并显示异常后,又把异常交给下一任"捕捉--处理"过程来二次处理,这种算是不纯的职责链模式。

 使用环境

   不明确请求处理者是具体的哪一个对象,只知道对象是在一个对象群中时,可以使用此模式。

  当有多个对象都有可能处理请求时。

 PS

   做这个笔记的目的是让自己的印象更深一些。写的有些仓促,万望提出宝贵意见,不论是表达方面,还是技能方面或者是文章组织方面。你的意见,对我很重要,谢谢~