设计模式-责任链设计模式
程序员文章站
2022-12-22 12:30:50
责任链设计模式,是行为型设计模式的巅峰之作。 现在有一个场景,请假申请。请假时间的长短,需要不同级别的领导才能审批。 万物皆对象嘛,请假需要工号、姓名、原因、时长、结果等等,那我们来定义一个请假的类。其实其就是一个上下文环境(Context),保存业务处理中参数 中间结果 最终结果。行为型设计模式重 ......
责任链设计模式,是行为型设计模式的巅峰之作。
现在有一个场景,请假申请。请假时间的长短,需要不同级别的领导才能审批。
万物皆对象嘛,请假需要工号、姓名、原因、时长、结果等等,那我们来定义一个请假的类。其实其就是一个上下文环境(context),保存业务处理中参数-----中间结果-----最终结果。行为型设计模式重用的标配,把行为转移。
public class applycontext { public int id { get; set; } public string name { get; set; } /// <summary> /// 请假时长 /// </summary> public int hour { get; set; } public string description { get; set; } public bool auditresult { get; set; } public string auditremark { get; set; } }
请假需要new一个实例:
applycontext context = new applycontext() { id = 506, name = "bingle", hour = 100, description = "世界那么大,我想去看看!", auditresult = false, auditremark = "" };
第一种方式,审批逻辑都卸载上端,直接就是需求翻译,没有任何加工,谈不上什么扩展,面向国产:
if (context.hour <= 8) { console.writeline("pm审批通过"); } else if (context.hour <= 16) { console.writeline("主管审批通过"); } else { console.writeline("************"); }
第二种方式,面向对象:封装--继承--多态,转移业务逻辑,也只是一个翻译机,翻译完+面向对象,其实完全没有涉及加工没有思考。
领导类s:
public class pm { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 8) { context.auditresult = true; context.auditremark = "允许请假!"; } } } public class charge { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 16) { context.auditresult = true; context.auditremark = "允许请假!"; } } } public class manager { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 24) { context.auditresult = true; context.auditremark = "允许请假!"; } } } public class chief { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 48) { context.auditresult = true; context.auditremark = "允许请假!"; } } } public class ceo : abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 96) { context.auditresult = true; context.auditremark = "允许请假!"; } } } public class chiarman : abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 1000000) { context.auditresult = true; context.auditremark = "允许请假!"; } } }
下面进行逻辑的翻译:
abstractauditor pm = new pm() { name = "bingle1" }; pm.audit(context); if (!context.auditresult) { abstractauditor charge = new charge() { name = "bingle2" }; charge.audit(context); if (!context.auditresult) { abstractauditor manager = new manager() { name = "bingle3" }; manager.audit(context); if (!context.auditresult) { //找下一环节 } } }
不要直接翻译的逻辑,需要涉及,现在的场景分析是,1、权限范围内,审批通过;2、权限范围外,交给下一环节审批,写的代码又多了一个,指定洗衣环节,甩锅大法开始。
首先定义一个抽象父类:
public abstract class abstractauditor { public string name { get; set; } public abstract void audit(applycontext context); private abstractauditor _nextauditor = null; public void setnext(abstractauditor auditor) { this._nextauditor = auditor; } protected void auditnext(applycontext context) { if (this._nextauditor != null) { this._nextauditor.audit(context); } else { context.auditresult = false; context.auditremark = "不允许请假!"; } } }
领导类需要继承这个抽象类:
public class pm : abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 8) { context.auditresult = true; context.auditremark = "允许请假!"; } else { abstractauditor charge = new charge() { name = "象扑君" }; charge.audit(context); } } }
其他的领导类以此类推.....
调用的时候,只需要找最低权限的人,去审批
abstractauditor pm = new pm() { name = "bingle" }; pm.audit(context);
以上,转移了申请提交的逻辑,这次符合实际情况,有了自己的思考和设计在里面。
甩锅大法开始了,一样,领导类需要实现抽象父类,不过在audit方法中稍作了改动
public class pm : abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 8) { context.auditresult = true; context.auditremark = "允许请假!"; } else { base.auditnext(context); } } } public class manager : abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 24) { context.auditresult = true; context.auditremark = "允许请假!"; } else { base.auditnext(context); } } } public class chief : abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 48) { context.auditresult = true; context.auditremark = "允许请假!"; } else { base.auditnext(context); } } } public class chiarman : abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 1000000) { context.auditresult = true; context.auditremark = "允许请假!"; } else { base.auditnext(context); } } } public class charge: abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 16) { context.auditresult = true; context.auditremark = "允许请假!"; } else { base.auditnext(context); } } } public class ceo : abstractauditor { public override void audit(applycontext context) { console.writeline($"this is {this.gettype().name} {this.name} audit"); if (context.hour <= 96) { context.auditresult = true; context.auditremark = "允许请假!"; } else { base.auditnext(context); } } }
下面需要找领导审批了:
abstractauditor pm = new pm() { name = "bingle1" }; abstractauditor charge = new charge() { name = "bingle1" }; abstractauditor manager = new manager() { name = "bingle1" }; abstractauditor chief = new chief() { name = "bingle1" }; abstractauditor ceo = new ceo() { name = "bingle1" }; //pm.setnext(charge); //charge.setnext(manager); pm.setnext(manager); manager.setnext(chief); chief.setnext(ceo); ceo.setnext(new chiarman() { name = "bingle1" }); //流程的可扩展 pm.audit(context); if (!context.auditresult) { console.writeline("不干了!"); }
以上,把流畅环节逻辑从业务类转移了。