作者:京东物流钟磊1前言最近在梳理接口逻辑时,发现代码中使用的策略与责任链设计模式留下了很深的印象给我的印象很深。一个业务逻辑过程通常非常适合使用责任链和策略设计模式来实现,因为一个业务需求通常可以拆分成独立的逻辑处理单元并依次组装,责任链设计模式可以很好地衔接起来整个业务流程,策略设计模式可以抽取业务中变化的算法部分,复用主要的公共逻辑,灵活更换业务算法。使用这两种设计模式可以灵活扩展我们的代码以适应不同的业务需求。由于这两种设计模式都非常实用,下面简单介绍一下我对这两种设计模式的理解以及它们在Spring框架源码中的应用。2责任链设计模式的一般定义责任链设计模式是设计模式中的一种行为设计模式。它的基本结构类似于链条。整个链条由单个链接组成。每个环节在程序代码中都是一个独立的处理单元。每个处理单元都有自己独特的逻辑。当一个处理请求来到这条链之后,会顺着各个处理单元依次传递,直到请求处理完毕。2.1使用场景:1.一个业务请求需要经过一组处理单元进行处理。这种场景类似于在一个业务逻辑流程中设置了多个不同功能的处理单元,一个业务请求需要被这多个处理单元串行处理。2、程序中有多个处理单元可以处理同一个请求,但是决定使用哪个处理单元需要在程序运行时根据请求动态决定。2.2类图结构及在SpringAOP框架中的应用一:类图结构二:责任链设计模式在SpringAOP框架中的应用Spring框架中的AOP模块使用责任链设计模式对目标方法的调用过程进行封装成为增强目标方法的方法调用链。SpringAOP模块包括五个通知方法:Before、After、AfterReturning、AfterThrowing和Around。SpringAOP模块通过动态代理将这些通知方法和目标方法封装成一个调用链,分别执行各个通知模块的处理。逻辑,下面是SpringAOP的源码分析图。SpringAOP通过递归实现责任链的功能。首先对所有的通知方法进行排序,然后用一个List索引来控制整个执行过程的开始和结束。在整个责任链中,Before通知负责执行预处理。After通知负责执行后处理,AfterReturning方法负责执行目标方法成功返回后的处理逻辑,AfterThrowing方法负责执行目标方法执行异常后的处理逻辑。SpringAOP将通知方法包装到方法调用链的各个节点中,巧妙地利用责任链模型完成对目标方法的处理增强。3:广义责任链设计模式在日常代码编写中,责任链设计模式不需要这么严格的结构,只要整体代码流由独立的处理单元组成,并按照一定的顺序组合,那么就可以也可以看作是一种更通用的责任链设计模式,也可以满足开闭原则,比如下面这种比较常用的代码结构。上述结构也可以实现责任链处??理功能,也可以写得更简洁。也可以灵活修改扩展,维护代码的适用性会更明确。2.3责任链模型的优点:1.每个处理节点都有自己独特的处理逻辑,明确定义了各自在整个流程中的职责,符合类的单一职责原则。2.构建的责任链可以根据业务需要灵活变化,可以动态调整顺序,动态插拔,满足重要的开闭原则。3.减少请求发送者和请求处理者之间的耦合。3策略设计模式的一般定义策略设计模式也是设计模式中的一种行为设计模式。它的结构表现是将可变算法策略部分从业务代码逻辑中分离出来,并形成这些算法策略池,可以随时更换和更新,使我们的代码结构更加灵活,更容易扩展。3.1使用场景一:当代码需要根据上下文逻辑选择使用不同的业务算法时,我们可以使用策略设计模式来优化代码的判断结构,从而避免大量的if/else分支判断。2:当代码的主要处理逻辑大致相同,只有部分业务算法不同时,可以将这些不同的业务算法抽取出来,避免大量重复代码的编写,复用主要代码逻辑。3.2类图结构及在Spring框架中的应用一:类图结构二:在Spring框架中的应用Spring框架给我们开发者留下了很多扩展策略点,实现了可动态插拔的功能扩展。典型的策略扩展点是BeanPostProcessor接口。BeanPostProcessor接口允许我们在Bean初始化前后做一些逻辑处理策略来改变Bean的属性,允许我们对Bean进行改造和个性化。SpringAOP使用BeanPostProcessor策略扩展点实现动态代理bean的创建。下面是SpringAOP后处理器的源码分析。SpringAOP引入AspectJAwareAdvisorAutoProxyCreator,一个实现了BeanPostProcessor接口的后处理器,在Bean初始化后创建一个动态代理类。它在postProcessAfterInitaliztion方法中的WarpIfNecessary方法中实现了代理类的创建。Spring框架就是利用这种模板和策略的设计模式,让我们可以对框架的功能进行个性化和扩展,使得框架非常灵活和可扩展。我们也可以根据业务需要添加自己的BeanPostProcessor策略来实现自己独特的逻辑。非常好满足了重要的开闭设计原则。3:广义的策略设计模式同样,我们也不必严格按照定义好的策略设计模式来写,只要业务主体的逻辑整体保持不变,将变化的部分抽取出来形成策略即可可以按需扩展的想法。现在,我们以SpringBoot自动组装的源码来说明这个更通用的策略模式。SpringBoot自动装配机制是根据用户当前的代码运行环境,结合@Conditional注解动态加载我们需要使用的类。这种策略设计模式是一种更通用的策略设计模式,同时也满足策略设计模式。按需选择,动态插件设计原则。SpringBoot自动装配机制的原理如下:①SpringBoot使用@EnableAutoConfiguration注解中的@import注解导入EnableAutoConfigurationImportSelector类。②使用EnableAutoConfigurationImportSelector类的selectImports方法加载jar包中META-INF/spring.factories文件中配置的类。③最后结合各种@Conditional注解,实现按需加载的策略设计模式。SpringBoot的按需自动装配策略设计思想在结构上并没有严格遵循策略设计模式的结构,但其整体设计思想与策略设计模式非常一致。我们也可以通过配置文件在项目中灵活运用。切换代码中使用的策略算法。3.3策略设计模式的优点:1:可以在程序运行时动态选择和切换需要使用的独立业务算法。2:将可变业务算法与业务主逻辑分离,实现更灵活的维护和扩展。3:满足开闭原则,无需修改原有代码逻辑即可实现不同业务算法的灵活切换。4结合战略设计模式和责任链设计模式结合战略设计模式和责任链设计模式可以形成灵活、可扩展的流程结构,以应对不断变化的业务需求。下面是结合两者的结构图。当一个请求经过各个handler处理单元时,它会根据请求的上下文内容选择合适的策略进行处理,然后将所有的handler串联起来,形成一个完整的业务流程。5小结在日常的代码编写中,业务需求的变化总是不确定的,这会导致我们的代码经常随着需求的变化而调整。一不留神,我们的代码就会非常臃肿复杂,积累到一定程度就变得难以维护了。这时候,提前使用合适的代码设计模式,可以有效缓解这种情况。本文所描述的职责链和策略设计模式能够有效满足代码编写的开闭原则,能够更有效地应对随时变化的业务需求。
