行为型设计模式:关注对象与行为的分离
责任链模式:解决一个请求需要多个环节处理,环节还可能扩展 、变化、调整顺序等问题
下面是模拟一个审批的流程,context 是记录这一流程的上下文环境,如果按照最基本的写法为
1 //一个请假申请 2 ApplyContext context = new ApplyContext() 3 { 4 Id = 1098, 5 Name = "晓晓", 6 Hour = 128, 7 Description = "参加软谋线下沙龙上海站活动", 8 AuditRemark = "", 9 AuditResult = false 10 }; 11 { 12 //所有逻辑都写在上端 人家说什么 我就些什么,代码翻译机 13 //Console.WriteLine("****************************************"); 14 ////首先是项目经理审批 15 ////找项目经理审批 16 //Console.WriteLine("这里是项目经理 {0} 审批", "程序错误"); 17 //if (context.Hour <= 8) 18 //{ 19 // context.AuditResult = true; 20 // context.AuditRemark = "enjoy your vacation!"; 21 //} 22 //else 23 //{ 24 // //找主管审批 25 // Console.WriteLine("这里是主管 {0} 审批", "笔落闻声"); 26 // if (context.Hour <= 16) 27 // { 28 // context.AuditResult = true; 29 // context.AuditRemark = "enjoy your vacation!"; 30 // } 31 // //。。。 32 //} 33 }
这样写太low了,把所有的逻辑都写在了一个地方,下面把审批的逻辑提取出来,并抽象处理
调用
1 ////面向对象:封装一下业务细节;继承;多态;抽象 2 ////审批逻辑转移了 3 //AbstractAuditor pm = new PM() { Name = "程序错误" }; 4 //pm.Audit(context); 5 //if (!context.AuditResult) 6 //{ 7 // AbstractAuditor charge = new Charge() { Name = "笔落闻声" }; 8 // charge.Audit(context); 9 // if (!context.AuditResult) 10 // { 11 // AbstractAuditor manager = new Manager() { Name = "南南" }; 12 // manager.Audit(context); 13 // //... 14 // } 15 //}
但是这样违背了现实, 申请着没有资格去找那么多层审批,只能找到自己的直接领导,直接领导不行的话,直接领导再找上级
调用,转移审批步骤的逻辑,只写自己一层就好了
1 ////申请者--项目经理--转交到主管--主管转交经理。。。。 2 ////转移提交申请的逻辑 3 //AbstractAuditor pm = new PM() { Name = "程序错误" }; 4 //pm.Audit(context);
但是这样就把审批的步骤定死了,项目经理之后一定就是主管,主管之后一定就是总监,不方便应对变化,所以要把这部分逻辑转移,即交给上端去指定下一步由谁来审批
abstract
1 public abstract class AbstractAuditor 2 { 3 public string Name { get; set; } 4 public abstract void Audit(ApplyContext context); 5 6 7 private AbstractAuditor _Auditor = null; 8 public void SetNext(AbstractAuditor auditor) 9 { 10 this._Auditor = auditor; 11 } 12 13 public void AuditNext(ApplyContext context) 14 { 15 if (this._Auditor != null) 16 { 17 this._Auditor.Audit(context); 18 } 19 } 20 }
1 public class Charge: AbstractAuditor 2 { 3 public override void Audit(ApplyContext context) 4 { 5 Console.WriteLine("这里是主管 {0} 审批", this.Name); 6 if (context.Hour <= 16) 7 { 8 context.AuditResult = true; 9 context.AuditRemark = "enjoy your vacation!"; 10 } 11 else 12 { 13 base.AuditNext(context); 14 //AbstractAuditor manager = new Manager() { Name = "南南" }; 15 //manager.Audit(context); 16 } 17 } 18 }
1 public class Chief : AbstractAuditor 2 { 3 public override void Audit(ApplyContext context) 4 { 5 Console.WriteLine("这里是总监 {0} 审批", this.Name); 6 if (context.Hour <= 64) 7 { 8 context.AuditResult = true; 9 context.AuditRemark = "enjoy your vacation!"; 10 } 11 else 12 { 13 base.AuditNext(context); 14 } 15 } 16 }
调用
这样写的好处是能够配置流程的顺序
如果觉得这段组装的逻辑不爽可以拿到单独的类中去配置,这样调用的代码就清爽了点
调用
后续可以利用工厂和反射对build方法进行进一步的拆分
责任链模式的运用诠释了行为型设计模式的精髓,就是将可能对自己的类产生影响的行为(变化)分离出去,让其他人去处理,同时也可以将相对分散的逻辑提取出来形成统一