标签:style class blog code ext color
定义
避免把一个请求的发送者和接收者耦合在一起,使多个对象都有机会处理请求。将这个请求的多个接收着连接成一条链,并让请求沿着这个链传递下去,只到有一个结点能处理请求。
职责链模式中,链形成后,不一定非要有一个结点能够处理请求,也就是说,所有结点都可以处理一下再往下传,也可以都不处理,这样说来就比较灵活了。
组成
抽象处理者: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 : Manager 22 { 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 else 34 { 35 Console.WriteLine("主管没有权力,交给部门经理处理"); 36 this.manager.HandlerLeave(days); 37 } 38 } 39 } 40 /// <summary> 41 /// 部门经理处理者 42 /// </summary> 43 class DepartmentManager : Manager 44 { 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 else 56 { 57 Console.WriteLine("部门经理没有权力,交给总经理处理"); 58 this.manager.HandlerLeave(days); 59 } 60 } 61 } 62 /// <summary> 63 /// 总经理处理者 64 /// </summary> 65 class GeneralManager : Manager 66 { 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 else 78 { 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 try 2 { 3 } 4 catch (Exception ex) 5 { 6 Console.WriteLine(ex.Message); 7 throw new Exception(ex.Message + "某某处理错误"); 8 }
在第一次捕获异常并显示异常后,又把异常交给下一任"捕捉--处理"过程来二次处理,这种算是不纯的职责链模式。
使用环境
不明确请求处理者是具体的哪一个对象,只知道对象是在一个对象群中时,可以使用此模式。
当有多个对象都有可能处理请求时。
PS
做这个笔记的目的是让自己的印象更深一些。写的有些仓促,万望提出宝贵意见,不论是表达方面,还是技能方面或者是文章组织方面。你的意见,对我很重要,谢谢~
编程模式之十四----行为型----职责链模式,布布扣,bubuko.com
标签:style class blog code ext color
原文地址:http://www.cnblogs.com/ddx-deng/p/3791755.html