首页 > 代码库 > 编程模式之十四----行为型----职责链模式
编程模式之十四----行为型----职责链模式
定义
避免把一个请求的发送者和接收者耦合在一起,使多个对象都有机会处理请求。将这个请求的多个接收着连接成一条链,并让请求沿着这个链传递下去,只到有一个结点能处理请求。
职责链模式中,链形成后,不一定非要有一个结点能够处理请求,也就是说,所有结点都可以处理一下再往下传,也可以都不处理,这样说来就比较灵活了。
组成
抽象处理者: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
做这个笔记的目的是让自己的印象更深一些。写的有些仓促,万望提出宝贵意见,不论是表达方面,还是技能方面或者是文章组织方面。你的意见,对我很重要,谢谢~