前端设计模式之责任链模式
责任链模式
什么是责任链模式
责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。(此处引自 gof 设计模式)
在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,所以责任链将请求的发送者和请求的处理者解耦了。
责任链模式是一种对象行为型模式,其主要优点如下:
1.降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
2.增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
3.增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
4.责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
5.责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
其主要缺点如下。
1.不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
2.对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
3.职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。
其他说明
责任链模式,总的一个核心就是请求者不必知道是谁哪个节点对象处理的请求,由于处理请求的可以在不同对象下处理,所以请求者跟接受者是解耦的。
纯的责任链:要求请求在这些对象链中 必须被处理 ,而且一个节点处理对象,要么只处理请求,要么把请求转发给下个节点对象处理;
不纯的责任链:要求在责任链里 **不一定会有处理结构 **,而且一个节点对象,即可以处理部分请求,并把请求再转发下个节点处理;
javascript 中介者模式
责任链模式对前端开发来说可能有点陌生,但是看了前面的描述又感觉似曾相识
实际上 express、redux 里的 middleware 都可以简单理解为责任链模式的运用
要实现中间件模式,最重要的实现细节是:
1.可以通过调用 use() 函数来注册新的中间件
2.当接收到需要处理的新数据时,注册的中间件在执行流程中被依次调用。每个中间件都接受上一个中间件的执行结果作为输入值
3.每个中间件都可以停止数据的进一步处理,只需要简单地不调用它的回调函数或者将错误传递给回调函数。当发生错误时,通常会触发执行另一个专门处理错误的中间件
项目实战
通用中间件开发
通用中间件使用 ajax
如上我们在发送请求之前加入了类型转换、数据校验,将数据的业务处理使用中间件模式剥离,使得处理过程模块化,维护性提升。
中间件升级-事件回调
每个中间件的过程都是不可控制的,全部都交由中间类去统一调用,我们可以加入事件回调,方便我们在中间件处理过程中拥有额外的逻辑能力
将上述的使用方法再改造一下,方便实际业务中使用
上述的项目实例是采用 ajax 来演示,实际通用的中间件类,可以在业务中将一些 **流程化执行的任务 **拆分出来,例如表单验证、多重条件判断等等
多种条件判断
将流程化执行的多种条件判断通过中间件解耦,可以使得条件判断方法更加清晰。一般当你需要使用中介者来改造业务逻辑的时候,前端的项目确实有点复杂了。
现在STAR现在是在腾讯课堂里面分享自己的经验,感谢兴趣的朋友可以加Q群:1146649671
中获取STAR在腾讯课堂分享的链接,还可以获取学习资料 面试文档等
责任链模式是将请求的处理对象像一条链条组合起来,形成对象链。这样做的好处就是请求并不需要知道处理对象是哪一个,实现了请求和处理对象的解耦。
首先先看使用责任链经典的三个地方
1.servlet中的Filter
FilterChain执行第一个filter时,执行filter.doFilter方法时会把下一个filter通过参数传递形式传入。如何维护filter链式关系,可以通过一个集合或者数组。比如说ApplicationFilterChain就维护了一个List<FilterConfig>数组,每次调用可以外部控制条用或者通过参数传递形式。
2.dubbo中的Filter(ProtocolFilterWrapper)
原理就是新建一个invoker包装Filter,Filter.invoke方法会传入前一个invoker,循环调用就会形成一个调用链条。新建的invoker担任的角色就是包装filter,并且设置包装filter后置处理器。实际初始invoker就是执行终点。
3.mybatis中的interceptor
mybatis通过动态代理来实现责任链模式。Mybatis支持对Executor、StatementHandler、PameterHandler和ResultSetHandler 接口进行拦截,也就是说会对这4种对象进行代理。mybatis会生成被拦截接口对象的动态代理类,动态代理类相当于是被拦截对象和拦截器的包装类,动态代理类有个target属性保存被拦截对象,执行时先执行拦截器方法,执行成功调用被拦截对象。动态代理类还可以被拦截再次生成新的动态代理类,每次生成新的都会保存上一个动态代理类,从而实现链式调用。
mybatis的分页就是通过拦截器的形式实现的。
拦截器比较重要的两个方法plugin、intercept。
plugin是对哪些情况进行拦截,拦截时会生成被拦截对象的动态代理类,intercept是实际拦截执行的操作,这个方法会最终调用invocation.proceed执行操作。
构成链式调用的关键是 Plugin interceptor.intercept(new Invocation(target, method, args)) 动态代理类会将被代理对象传入拦截器方法,实际调用就是被拦截对象,当多次包装时,被代理对象仍然是个代理类,就构成了链式调用。
从上面三个例子可以看出来,实现责任链模式关键在于两个角色抽象处理类和具体处理类,类图如下
下面以一个审批金额例子来简单说明这个模式的应用
员工审批金额不能超过500,领导审批金额不能超过1000,经理审批金额不能超过10000。
抽象员工处理类
职员处理类
领导具体处理类
经理具体处理类
Client类 设置具体处理类的后继关系
目前自己还没有动手实现责任链场景,等以后遇到这边继续更新
社会治理现代化体系要形成自治、法治、德治是新时代社会治理的基本方式的社会治理责任链条,体现了“民主治理、依法治理、以德治理”的现代治理逻辑。
自治,即“民事民议、民事民办、民事民管”,要求尊重和保障群众知情权、参与权,以民主为基础发挥群众自治作用,通过集民意、汇民智、聚民力充分调动群众的积极性、主动性、创造性,强化社会治理现代。
2、责任链模式由两个角色组成:
1) 抽象处理者角色(Handler):它定义了一个处理请求的接口。当然对于链子的不同实现,也可以在这个角色中实现后继链。
2) 具体处理者角色(Concrete Handler):实现抽象角色中定义的接口,并处理它所负责的请求。如果不能处理则访问它的后继者。
至于类图不放也罢。毕竟就是一个继承或者实现。
3、从名字上大概也能猜出这个模式的大概模样——系统中将会存在多个有类似处理能力的对象。当一个请求触发后,请求将在这些对象组成的链条中传递,直到找到最合适的“责任”对象,并进行处理。
《设计模式》中给它的定义如下:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
从定义上可以看出,责任链模式的提出是为了“解耦”,以应变系统需求的变更和不明确性。
下面是《设计模式》中给出的适用范围:
1) 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
2) 你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3) 可处理一个请求的对象集合应被动态指定。
1、领导者:
①表里不一,我行我素。
②争权夺利,相互攻击。
③固执偏狭,顾此失彼。
④表面繁荣,内部空虚。
2、干部队伍
①思想上私。
②行动上差。
③作风上软。
④品德上贪。
3、员工:“四缺六不”(辞退之变)
四缺:
①缺乏主人翁责任感。
②缺乏认真负责精神。
③缺乏团队精神。
④缺乏创造精神。
六不:
①工作标准不高。
②精神状态不佳。
③工作落实不力。
④小事不愿干,大事干不了。
⑤不愿意接受领导交办的工作。
⑥纪律观念不强
二、责任心不强的根源。
1、源于人的懒惰天性。
2、源于学习教育的缺失。
3、源于制度不完善。
4、源于监督不力。
5、源于管理者缺乏经验、能力和技巧。
有人说是利润,还有人说是权力,其实,利润和权力都具有随意性和不可持续性,它们不可能成为企业发展的长久驱动力。
企业中环环相扣的“责任链”才是企业发展的动力。
在企业中,一切关系都是“责任的关系”,每一个看似独立的责任都与上下、左右的关联者构成“责任链”。比如,横向的岗位与岗位之间是责任关系,纵向的上级与下级之间也是责任关系,等等,他们之间形成了环环相扣、相互依存的“责任链”,每一个责任和岗位都被其相关联的责任驱动着,由此形成了企业发展源源不断的动力。如果哪一环的责任或岗位出现了混乱,应该承担的责任没有被承担起来,企业里的“责任链”就会像多米诺骨牌一样轰然倒塌。
为了避免责任链的断裂,每一位员工都要坚守自己的责任,落实好自己的责任。
有一家企业频频出现产品不合格的问题,管理者几经商讨,最后提出了一种前所未有的方法来解决产品的质量问题。
这个方法就是推行上下工序的索赔制度,简单说来就是,当一道工序出现问题的时候,处于这一工序的员工有权向上一道工序的员工追究责任,直到找到问题为止。所以,每一道工序的员工都有责任去监督上一道工序的质量问题。为保证这一制度的顺利进行,企业还专门成立了以工人为主题的索赔仲裁委员会,专门处理员工的责任纠纷问题,处理到最后,70%的纠纷都由员工自己处理了。
从这个案例我们可以看到,每一个责任或者岗位都不是独立存在的,都与上下左右的责任关联者构成相互的责任承担。对上一道工序来说,它承担着考核与监督的责任;对于下一道程序来说,它又是责任的承担者,如果它不能很好地落实自己的责任,下一道工序就要受自己的影响,从而完不成任务,就会向它索赔。于是,责任就是在这样的环环相扣中,实现了“责任链”的构建。
员工坚守自己的责任,落实自己的责任,不让任何一根“责任链”断裂,从而保障企业的运营安全,为企业这艘大船顺利运行保驾护航。