您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

三国演义:责任链模式

2024/5/22 17:39:52发布21次查看
大家好,今天我给大家分享设计模式中的责任链模式。用贴切的生活故事,以及真实项目场景来讲设计模式,最后用一句话来总结这个设计模式。
故事
前两天,没事又刷了一遍三国演义,看到关羽身在曹营心在汉,听说刘备在袁绍那里,然后就上演了“过五关,斩六将”。
关羽过五关斩六将主要内容:
第一关,东岭关,斩守将孔秀。
东岭关,守关将名叫孔秀,本是黄巾余党,归降曹操之后,带着五百人奉命防守东岭关。关羽车队从关前通过时,孔秀索要通关文牒,与关羽发生冲突,只一个回合,就被关羽斩杀。
第二关,洛阳关,孟坦和韩福。
关羽过了东岭关,在要过洛阳时,韩福、孟坦用鹿角拦住道路。先是孟坦挑战,与关羽说翻,交手不敌,孟坦拨马回跑,引关公来追,这样韩福就可以在后面射箭擒拿关公,可谁想到关公赤兔马快,从后面赶上孟坦,一刀就把孟坦给劈了。韩福慌得射了一箭,中关公左臂,关公忍住箭伤,也冲过鹿角,一刀斩杀韩福,于是过洛阳。
第三关,汜水关,卞喜。
在得知关羽过关斩将,东岭关孔秀、洛阳韩福、孟坦都被杀害,卞喜自思难以抵挡关公。于是就假意迎接关公,在镇国寺安排下刀斧手,准备伺机杀死关公。幸亏有镇国寺老方丈普净给警示,关公这才察觉出阴谋,与卞喜闹翻,一刀斩杀卞喜,于是关公过汜水关。
第四关,王植。
这王植是韩福的亲家,听说韩福被关公杀死,十分愤怒,于是就要为韩福报仇。在关公到达荥阳时,王植在馆驿设宴,宴请关公和二位皇嫂。却是暗中派从事胡班放火,想要烧死关公。但胡班因关公给父亲胡华带信的缘故,向关羽告了密。关羽和二位皇嫂得以提前逃离馆驿,胡班却假意放火,迷惑王植。不过王植后来察觉,杀了胡班,来追关羽时,被关羽斩杀,于是关公过荥阳。
第五关,黄河渡口,秦琪。
这秦琪不仅是夏侯惇的爱将,更是老将军蔡阳的外甥,奉命守卫黄河渡口,盘查过往船只。关公到黄河渡口时,要找船只渡河,被秦琪拦住,秦琪不仅不放关公等人渡河,反而口出狂言,终于激怒关公,被关公斩杀
这就是关羽过五关斩六将的全部过程。
这个故事情节让我想起了一个设计模式:责任链模式。
其实,我们生活中也有着非常多的责任链模式。比如:基本上每个公司都有自己的oa系统,主要是员工基本信息、请假、调休、报销等功能。如果,我有事需要请假两天,于是登录oa系统,发起请假审批。
由于,对于请假时间的长短公司有如下规定:
小于等于半天,审批环节:项目负责人
大于半天,小于等于1天的,审批环节:项目负责人+技术总监
超过1天,审批环节:项目负责人+技术总监+boss
可以看得出来,我请假审批流程为项目负责人+技术总监+boss。
到底什么是责任链设计模式?
什么是责任链模式呢 责任链模式英文解释为:
avoid coupling the sender of a request to its receiver bygiving more than one object a chance to handle the request.chainthe receiving objects and pass the request along the chain until anobject handles it.
责任链模式(chain of responsibility pattern)将链中每一个节点都看作一个对象,每个节点处理的请求均不同,且内部自动维护下一个节点对象。当一个请求从链式的首端发出时,会沿着责任链预设的路径依次传递到每一个节点对象,直至被链中的某个对象处理为止,属于行为型设计模式。
责任链模式通用代码java实现责任链设计模式如下:
public abstract class handler { protected handler nexthandler = null; public abstract void handle(); public handler getnexthandler() { return nexthandler; } public void setnexthandler(handler nexthandler) { this.nexthandler = nexthandler; }}public class handlera extends handler{ @override public void handle() { if(nexthandler == null){ system.out.println("handlera handle ..."); }else{ nexthandler.handle(); } }}public class handlerb extends handler{ @override public void handle() { if(nexthandler == null){ system.out.println("handlerb handle ..."); }else{ nexthandler.handle(); } }}public class handlerc extends handler{ @override public void handle() { if(getnexthandler() == null){ system.out.println("handlerc handle ..."); }else{ getnexthandler().handle(); } }}//测试public class client{ public static void main(string[] args) { handler handlera = new handlera(); handler handlerb = new handlerb(); handlera.setnexthandler(handlerb); handlera.handle(); }}
运行结果:
handlerc handle ...
从上面代码,我们可以画出uml图:
从uml图中,我们又可以看出,责任链模式中有两个非常重要的角色:
(1)、抽象处理者角色(handler)
定义处理请求的接口。接口可以也可以给出一个方法以设定和返回对下个对象引用。这个角色通常由一个java抽象类或者java接口实现。
(2)、具体处理者角色(handlera、handlerb、handlerc)
具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下个对象。由于具体处理者持有对下家的引用。
责任链模式的优缺点优点:请求和处理分开,两者解耦,提供系统的灵活性。缺点:性能能问,一个链非常长的时候,非常耗时。因为我们避免建立很长的链。生活中的案例 在日常生活中,责任链模式是比较常见的。我们平时处理工作中的一些事务,往往是各部门协同合作来完成某一个任务的。而每个部门都有各自的职责,因此,很多时候事情完成一半,便会转交到下一个部门,直到所有部门都审批通过,事情才能完成。
责任链模式主要解耦了请求与处理,客户只需将请求发送到链上即可,不需要关心请求的具体内容和处理细节,请求会自动进行传递,直至有节点对象进行处理。
责任链模式主要适用于以下应用场景:
多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。在不明确指定接收者的情况下,向多个对象中的一个提交请求。可动态指定一组对象处理请求。请假流程的代码实现 下面我们来对,前面的案例:oa上请假流程做一个java代码的实现。
抽象处理者:领导类
public abstract class leader { private leader next; public void setnext(leader next) { this.next = next; } public leader getnext() { return next; } //处理请求的方法 public abstract void handlerequest(double leavedays);}
项目负责人
public class projectleader extends leader { @override public void handlerequest(double leavedays) { if (leavedays <= 0.5) { system.out.println("项目负责人批准您请假" + leavedays + "天。"); } else { if (getnext() != null) { getnext().handlerequest(leavedays); } else { system.out.println("请假天数太多,没有人批准该假条!"); } } }}
技术总监
public class technicaldirectorleader extends leader { @override public void handlerequest(double leavedays) { if (leavedays <= 1) { system.out.println("技术总监批准您请假" + leavedays + "天。"); } else { if (getnext() != null) { getnext().handlerequest(leavedays); } else { system.out.println("请假天数太多,没有人批准该假条!"); } } }}
boss
public class bossleader extends leader { @override public void handlerequest(double leavedays) { if (leavedays >= 2 && leavedays <= 30) { system.out.println("boss批准您请假" + leavedays + "天。"); } else { if (getnext() != null) { getnext().handlerequest(leavedays); } else { system.out.println("请假天数太多,没有人批准该假条!"); } } }}
发起审批
public class leaveapproval { public static void main(string[] args) { //组装责任链 leader projectleader = new projectleader(); leader technicaldirectorleader = new technicaldirectorleader(); leader bossleader = new bossleader(); projectleader.setnext(technicaldirectorleader); technicaldirectorleader.setnext(bossleader); //请假两天,提交请假流程,开启审批环节, projectleader.handlerequest(2); }}
审批结果
boss批准您请假2.0天。
如果请假天数是31天,审批结果
请假天数太多,没有人批准该假条!
整个请假流程为:
把这张流程图改成纵向:
就这么一环套一环的,使用上面两个例子和两张图来理解责任链模式是不是就更轻松了?
自己吹牛逼,没什么用,下面来看看大神们是怎么使用责任链模式的。
大佬们是如何使用的 在spring、mybatis等框架中,都用使用到责任链模式,下面先来看在spring中是如何使用的。
在spring mvc中的org.springframework.web.servlet.dispatcherservlet类中:
gethandler 方法的处理使用到了责任链模式,handlermappings是之前 spring 容器初始化好的,通过遍历 handlermappings查找与request匹配的 handler, 这里返回 handlerexecutionchain 对象。这个 handlerexecutionchain对象到后面执行的时候再分析为什么返回的是这样一个对象。
@nullableprotected handlerexecutionchain gethandler(httpservletrequest request) throws exception { if (this.handlermappings != null) { for (handlermapping mapping : this.handlermappings) { handlerexecutionchain handler = mapping.gethandler(request); if (handler != null) { return handler; } } } return null;}
以上便是责任链模式在spring的具体使用
总结 本文通过关二爷的过五关斩六将和oa系统中的请假审批流程,完美的解释了责任链设计模式。
以上就是三国演义:责任链模式的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product