zoukankan      html  css  js  c++  java
  • 【Spring源码解析】—— 策略模式在Spring中的应用

    一、         什么是策略模式

    策略模式的定义/含义:策略本身就是为了实现某一个目标而采取的一种工作方式,因此只要能够达成目标,则采取哪一种策略都可以;因此多种实际的策略之间是相互平行的。

    注意:策略模式与模板模式是不同的,模板模式是定义了一个骨架(会有很多个步骤,其中可能包含必选和可选步骤,步骤之间可能会有一定的顺序,模板模式在顶级骨架中可能会有部分实现,也可将部分实现延迟到子类中,例如:TestCase的过程,一般都包含setUp、testCase、tearDown操作,testCase需要子类自行实现,setUp和tearDown可以直接通过super来进行调用;备注:模板模式后面会再专门整理,可能该部分内容会做更新),模板模式整体构成了一个完整的过程/算法,可对其中的某些步骤进行自行定制处理,而策略模式是调用者独立于具体的策略算法,每一种具体策略自身就是完整的,策略A与策略B之间可以自行替换,对调用者来说,不关注具体是通过策略A实现的还是B实现的,通过引用传入上下文,即可按照策略执行达到目标(策略可以理解为:殊途同归)

    因此,在很多场景下都可以使用到策略模式,以大家熟悉的业务场景为例:比如支付方式的选择。

    在Spring中,实例化对象的时候用到了Strategy模式,图示如下所示:

    在上图中:InstantiationStrategy为抽象接口,SimpleInstantiationStrategy实现接口,但是在方法instantiate中进行判断,针对bd中没有MethodOverrides的,直接通过jdk反射进行构造函数调用,而针对有需要针对方法做MethodOverrides的,则可以通过另一种方式处理,在SimpleInstantiationStrategy中是通过:instantiateWithMethodInjection()方法处理的,在CglibSubclassingInstantiationStrategy中对该方法做了override实现。CglibSubclassingInstantiationStrategy继承自SimpleInstantiationStrategy,对MethodInjection方法的实现如下:

    @Override
    
    protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
    
          @Nullable Constructor<?> ctor, Object... args) {
    // Must generate CGLIB subclass... return new CglibSubclassCreator(bd, owner).instantiate(ctor, args); }

    通过static的class类CglibSubclassCreator进行instantiate操作,剩下的就是cglib内中的细节了,此处不分析。

    策略模式中包含的部分是:(1)抽象策略InstantiationStrategy接口

    (2)具体策略SimpleInstantiationStrategy,被继承后子类CglibSubclassingInstantiationStrategy,实现自抽象策略接口(3)上下文对策略的引用,在AbstractAutowireCapableBeanFactory中是通过new CglibSubclassingInstantiationStrategy赋值给InstantiationStrateg的引用,进而进行具体的方法调用,具体见下方代码:

    public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
    
          implements AutowireCapableBeanFactory {
    
       /** Strategy for creating bean instances. */
       private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();}

    (注意:这里一般是通过对抽象策略接口的引用,之后通过多实现的根据当时具体选择的策略内容进行调用实现) 

    二、         自写demo示例

    根据上面提到的策略模式中需要的内容进行demo的编写,分别是:抽象接口、具体实现、上下文引用及效果展示:

    抽象接口定义:

    package strategytest.demo;
    
    public interface Strategy {
        PayInfo payForSometh();
    }

    其中PayInfo定义如下:

    package strategytest.demo;
    
    public class PayInfo {
        String payType;
        String payCode;
        String payDesc;
    
        public PayInfo(String payType, String payCode, String payDesc) {
            this.payType = payType;
            this.payCode = payCode;
            this.payDesc = payDesc;
        }
    
        public String getPayType() {
            return payType;
        }
    
        public String getPayDesc() {
            return payDesc;
        }
    
        public String getPayCode() {
            return payCode;
        }
    }

    具体策略接口实现:

    package strategytest.demo;
    public class ZhiFuBaoPay implements Strategy {
        @Override
        public PayInfo payForSometh() {
            System.out.println("调用支付宝支付功能,根据返回值进行PayInfo类信息的设置");
            PayInfo zhifubaoPayInfo= new PayInfo("支付宝", "0", "支付成功");
            return zhifubaoPayInfo;
        }
    }

    多个具体策略接口实现方式与上类似

    上下文引用:

    package strategytest.demo;
    public class StrategyUse {
        public static void main(String[] args) {
            Strategy strategy = new WeiXinPay();
            PayInfo payinfo = strategy.payForSometh();
            System.out.println(payinfo.getPayType() + "," + payinfo.getPayCode() + "," + payinfo.getPayDesc());
        }
    }

    结果如下:

    参考文章:Spring中的各种模式的介绍:https://www.jianshu.com/p/3ea48ecd7178  ——》这是策略模式的,然后也有其他的模式,都可作为参考

  • 相关阅读:
    有趣的机器学习视频-第四章.强化学习
    有趣的机器学习视频-第五章.进化算法
    有趣的机器学习视频-第二章.人工神经网络
    有趣的机器学习视频-第三章.如何评价/检验神经网络
    有趣的机器学习视频-第一章.什么是机器学习
    AlphaStar
    AlphaZero
    AlphaGo分析
    nfs自动挂载
    postfix简单记录
  • 原文地址:https://www.cnblogs.com/keke-xiaoxiami/p/11139563.html
Copyright © 2011-2022 走看看