前言 这里就不详细去介绍策略模式是怎么样的了,想了解的可以点击下面的链接 策略模式介绍的链接:策略模式的介绍 这里列出策略模式的好处 场景:某网页有个支付,其中包含了微信、支付宝等方式的支付方式,后续明确还会进行兼容其他的支付方式 用策略模式的好处:避免多次使用if判断具体是用哪种支付策略进行操作。因为每种策略(微信支付、支付宝支付)的内容都比较复杂。策略模式能将每种策略分离出来,方面后续维护管理 下面我们将使用Springboot运用策略模式,实现上面的需求环境配置JDK8Springboot2。3。7。RELEASE整合了springbootstarterweb实现目标 使用策略模式后,新加一种支付策略时,只需要在策略枚举中添加新加的策略信息,外加一个策略类即可,而不再需要添加新的if判断。准备策略接口和具体实现策略类支付策略接口支付策略publicinterfacePayStrategy{支付(参数就没具体写了,可以定义成每个支付必须要有的参数)returnbooleanpay();}复制代码微信支付策略类第三方微信支付(这里注意我修改了Bean的默认命名)Component(wechatPayStrategy)publicclassWeChatPayStrategyImplimplementsPayStrategy{支付returnOverridepublicbooleanpay(){进行微信的支付逻辑System。out。println(正在进行微信的支付逻辑);returntrue;}}复制代码支付宝支付策略类支付宝第三方支付(这里注意我修改了Bean的默认命名)Component(alipayStrategy)publicclassAliPayStrategyImplimplementsPayStrategy{支付宝支付returnOverridepublicbooleanpay(){进行支付宝支付逻辑System。out。println(进行支付宝支付逻辑);returntrue;}}复制代码 上述已将各自的策略的处理类进行了分离,接下来时使用支付策略工厂类和支付策略上下文将各自的策略类联系起来准备支付策略上下文Context和支付策略工厂类支付策略工厂类packagecom。example。springbootstrategy。strategy。factory;importcom。example。springbootstrategy。enums。PayStrategyEnum;importcom。example。springbootstrategy。strategy。PayStrategy;importorg。springframework。stereotype。Component;importjavax。annotation。Resource;importjavax。swing。plaf。synth。SynthTextAreaUI;importjava。util。Map;支付策略工厂类ComponentpublicclassPayStrategyFactory{通过Spring容器的方式注入ResourceprivateMapString,PayStrategypayStrategyMap;获取对应支付策略类parampayStrategyEnum支付策略枚举publicPayStrategygetPayStrategy(PayStrategyEnumpayStrategyEnum){if(!payStrategyMap。containsKey(payStrategyEnum。getClassName())){System。out。println(没有对应的支付策略,无法进行支付);returnnull;}returnpayStrategyMap。get(payStrategyEnum。getClassName());}}复制代码 这里工厂类的逻辑是利用了Spring容器的处理方式,如果有多种类同时实现了某个接口,那么可以使用Map集合接收,Map对应的泛型,String是Bean名称,PayStrategy是每个具体实现类,这样我们就可以使用Bean类型去指定具体的策略类了,然后建立一个支付策略枚举去管理这些Bean名称。同时,也可以将Bean名称与客户端定义的类型进行关联。支付策略枚举类支付策略类型publicenumPayStrategyEnum{WECHATPAY(wechat,wechatPayStrategy,微信支付),ALIPAY(alipay,alipayStrategy,支付宝支付);支付策略codeprivateStringcode;bean名称privateStringclassName;信息privateStringinfo;PayStrategyEnum(Stringcode,StringclassName,Stringinfo){this。codecode;this。classNameclassName;this。infoinfo;}publicStringgetCode(){returncode;}publicStringgetClassName(){returnclassName;}publicStringgetInfo(){returninfo;}}复制代码 上面枚举类中code代表的是客户端定义的类型(例如我从前端接收到的支付type,这个type可以是这个code),className顾名思义,指的是每种策略的bean名称,info是代表每种策略的内容支付策略上下文支付策略上下文ComponentpublicclassPayStrategyContext{AutowiredprivatePayStrategyFactorypayStrategyFactory;支付执行parampayDTO支付参数returnpublicbooleanpayHandle(PayDTOpayDTO){将某属性的值转换成具体的枚举。这里是根据payDTO的type字段对应枚举的code进行转换OptionalPayStrategyEnumpayStrategyEnumOptionalArrays。stream(PayStrategyEnum。class。getEnumConstants())。filter((e)e。getCode()。equals(payDTO。getType()))。findAny();if(!payStrategyEnumOptional。isPresent()){System。out。println(匹配不到具体支付策略);returnfalse;}PayStrategyEnumpayStrategyEnumpayStrategyEnumOptional。get();PayStrategypayStrategypayStrategyFactory。getPayStrategy(payStrategyEnum);进行payDto参数的处理。。。。。booleanpaypayStrategy。pay();支付后的记录处理。。returntrue;}}复制代码pageDto类支付DTOpublicclassPayDTO{支付类型privateStringtype;支付金额privateBigDecimalpayMoney;。。。。。。。。。。。publicStringgetType(){returntype;}publicvoidsetType(Stringtype){this。typetype;}publicBigDecimalgetPayMoney(){returnpayMoney;}publicvoidsetPayMoney(BigDecimalpayMoney){this。payMoneypayMoney;}}复制代码 这个策略上下文,则是选择策略的入口,这里会进行参数的处理,将这里我就将pageDTO类中的type字符串转换成对应的枚举类。 到这里使用策略模式的编写算是完成了,下面进行编写客户端的代码客户端代码支付控制器RestControllerRequestMapping(pay)publicclassPayController{AutowiredprivatePayStrategyContextpayStrategyContext;PostMappingpublicbooleanpay(RequestBodyPayDTOpayDTO){这里因为懒就没有加上Service层了,直接在控制器处理returnpayStrategyContext。payHandle(payDTO);}}复制代码效果 新需求 后续新增一个银联的支付方式,我们只需要添加银联的支付策略类和添加银联的支付枚举即可实现添加银联的支付策略类银联支付(这里注意我修改了Bean的默认命名)Component(unionPayStrategy)publicclassUnionPayStrategyImpimplementsPayStrategy{银联支付returnOverridepublicbooleanpay(){进行银联的支付System。out。println(进行银联的支付逻辑);returntrue;}}复制代码在枚举类中添加银联的支付枚举支付策略类型publicenumPayStrategyEnum{WECHATPAY(wechat,wechatPayStrategy,微信支付),ALIPAY(alipay,alipayStrategy,支付宝支付),UNIONPAY(unionpay,unionPayStrategy,银联支付);支付策略codeprivateStringcode;bean名称privateStringclassName;信息privateStringinfo;PayStrategyEnum(Stringcode,StringclassName,Stringinfo){this。codecode;this。classNameclassName;this。infoinfo;}publicStringgetCode(){returncode;}publicStringgetClassName(){returnclassName;}publicStringgetInfo(){returninfo;}}复制代码实现效果 以上是我使用Springboot运用策略模式实现的效果,如果有误人子弟的地方,望在评论区指出。