【设计模式】策略模式与spring结合

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 在上一篇《【设计模式】策略模式》中,我们讲解了策略模式的基本概念和用法。策略模式是符合“开闭原则”的典型案例,但在上一篇文章中,我们发现,如果想调用其他的策略,虽然不用修改核心业务代码,但需要修改客户端代码。我们说,将策略的选择放在功能页面,当用户选择时,向后端传入策略,从数据库字典表中获取该策略对应的类的名字,再通过反射,获得对应的策略类。但如果不修改数据库,还有没有别的方法?当然有!

在上一篇《【设计模式】策略模式》中,我们讲解了策略模式的基本概念和用法。策略模式是符合“开闭原则”的典型案例,但在上一篇文章中,我们发现,如果想调用其他的策略,虽然不用修改核心业务代码,但需要修改客户端代码。我们说,将策略的选择放在功能页面,当用户选择时,向后端传入策略,从数据库字典表中获取该策略对应的类的名字,再通过反射,获得对应的策略类。但如果不修改数据库,还有没有别的方法?当然有!


使用spring注解!

我们将使用工厂+spring注解的方式实现!

1、工厂类

public class OrderIntegrateReadFactory {
    private final static Logger logger= LoggerFactory.getLogger(OrderIntegrateReadFactory.class);
    private Map<String,IVendeeContextStrategy> vendeeContextStrategyMap=new HashMap<String, IVendeeContextStrategy>();
    public Map<String, IVendeeContextStrategy> getVendeeContextStrategyMap() {
        return vendeeContextStrategyMap;
    }
    public void setVendeeContextStrategyMap(Map<String, IVendeeContextStrategy> vendeeContextStrategyMap) {
        this.vendeeContextStrategyMap = vendeeContextStrategyMap;
    }
    public boolean doAction(String strType, ReportDetail reportDetail, OrderDetail orderDetail){
        return this.vendeeContextStrategyMap.get(strType).getTicketContext(reportDetail,orderDetail);
    }
}


2、spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    <!--四种策略-->
    <bean id="orderIntegrateReadFactory" class="com.flight.inter.otaadapter.factory.OrderIntegrateReadFactory">
       <property name="vendeeContextStrategyMap">
           <map>
               <entry key="1" value-ref="ctripContextStrategy"/>
               <entry key="2" value-ref="qunarContextStrategy"/>
               <entry key="3" value-ref="aliquaContextStrategy"/>
               <entry key="4" value-ref="tongChengContextStrategy"/>
           </map>
       </property>
    </bean>
    <bean id="ctripContextStrategy" class="com.flight.inter.otaadapter.manage.cloudticket.CtripContextStrategy">
        <property name="huitiePiaoHao" ref="ctripHuiTieTicketNumber"/>
        <property name="redisManage" ref="policyRedis"/>
    </bean>
    <bean id="qunarContextStrategy" class="com.flight.inter.otaadapter.manage.cloudticket.QunarContextStrategy">
        <property name="huitiePiaoHao" ref="qunarHuiTieTicketNumber"/>
        <property name="redisManage" ref="policyRedis"/>
    </bean>
    <bean id="aliquaContextStrategy" class="com.flight.inter.otaadapter.manage.cloudticket.AliquaContextStrategy">
        <property name="huitiePiaoHao" ref="quaHuiTieTicketNumber"/>
        <property name="redisManage" ref="policyRedis"/>
    </bean>
    <bean id="tongChengContextStrategy" class="com.flight.inter.otaadapter.manage.cloudticket.TongChengContextStrategy">
        <property name="huitiePiaoHao" ref="TongChengHuiTieTicketNumber"/>
        <property name="redisManage" ref="policyRedis"/>
    </bean>
</beans>


3、接口类

public interface IVendeeContextStrategy {
    boolean getTicketContext(ReportDetail reportDetail, OrderDetail orderDetail);
}



4、具体实现类,以QunarContextStrategy策略为例

public class QunarContextStrategy implements IVendeeContextStrategy{
    private final static Logger logger= LoggerFactory.getLogger(QunarContextStrategy.class);
    HandleManage<TicketContext> huitiePiaoHao;
    RedisManager redisManage;
    public RedisManager getRedisManage() {
        return redisManage;
    }
    public void setRedisManage(RedisManager redisManage) {
        this.redisManage = redisManage;
    }
    public HandleManage<TicketContext> getHuitiePiaoHao() {
        return huitiePiaoHao;
    }
    public void setHuitiePiaoHao(HandleManage<TicketContext> huitiePiaoHao) {
        this.huitiePiaoHao = huitiePiaoHao;
    }
    @Override
    public boolean getTicketContext(ReportDetail reportDetail, OrderDetail orderDetail){
       try {
           TicketContext ticketContextQunar = QunarTicketContext(reportDetail, orderDetail);
           if (ticketContextQunar != null) {
               TicketContext ticketContext=huitiePiaoHao.handle(ticketContextQunar);
               if (ticketContext.isHuitieresult()){
                   redisManage.add("vendee-"+ticketContext.getTtsorderno(),"true");
                   redisManage.expire("vendee-"+ticketContext.getTtsorderno(),600);
                   logger.info("orderintegrate huitie success data {}",JSONObject.toJSONString(ticketContext));
                   return true;
               }
           }
       }catch (Exception e){
           logger.error("orerintegrate read ticketcontext error {}",e);
            return false;
       }
        return false;
    }
 }



5、模拟客户端调用

public class StrategyPatternDemo{
   public static void main(String[] args){
     OrderIntegrateReadFactory  orderIntegrateReadFactory = new  OrderIntegrateReadFactory ();
     String type = "1";
     ReportDetail reportDetail = new ReportDetail();
     OrderDetail orderDetail = new OrderDetail();
     reportDetail.setXXX();
     orderDetail.setXXX();
     ... ...
     Boolean boolean = orderIntegrateReadFactory.doAction(strType, reportDetail,orderDetail);
  }
}



 当需求中有新的类时,我们可以在只添加策略类,修改spring的配置文件来实现啦!

代码借鉴:

https://blog.csdn.net/zlts000/article/details/54754789










相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
13天前
|
设计模式 算法 开发者
「全网最细 + 实战源码案例」设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,用于定义一系列可替换的算法或行为,并将它们封装成独立的类。通过上下文持有策略对象,在运行时动态切换算法,提高代码的可维护性和扩展性。适用于需要动态切换算法、避免条件语句、经常扩展算法或保持算法独立性的场景。优点包括符合开闭原则、运行时切换算法、解耦上下文与策略实现、减少条件判断;缺点是增加类数量和策略切换成本。示例中通过定义抽象策略接口和具体策略类,结合上下文类实现动态算法选择。
48 8
「全网最细 + 实战源码案例」设计模式——策略模式
|
2月前
|
设计模式 存储 缓存
前端必须掌握的设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,旨在将多分支复杂逻辑解耦。每个分支类只关心自身实现,无需处理策略切换。它避免了大量if-else或switch-case代码,符合开闭原则。常见应用场景包括表单验证、风格切换和缓存调度等。通过定义接口和上下文类,策略模式实现了灵活的逻辑分离与扩展。例如,在国际化需求中,可根据语言切换不同的词条包,使代码更加简洁优雅。总结来说,策略模式简化了多条件判断,提升了代码的可维护性和扩展性。
|
2月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
3月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
59 1
|
3月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
57 2
|
3月前
|
设计模式 算法 Kotlin
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
63 4
|
3月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
59 2
|
4月前
|
设计模式 算法 Kotlin
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
|
4月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与实践
【10月更文挑战第12天】 在软件开发的世界中,设计模式是解决常见问题的最佳实践。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理运用设计模式可以极大地提高代码的可维护性、扩展性和复用性。本文将深入探讨策略模式(Strategy Pattern)的原理、实现方式及其在PHP中的应用。通过具体示例,我们将展示如何利用策略模式来解耦算法与对象,从而让代码更加灵活和易于管理。
36 0
|
4月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
本教程详细讲解Kotlin语法,适合深入学习。快速入门可参考“简洁”系列教程。本文通过游泳运动员的案例,介绍策略模式及其在Kotlin中的改良应用,利用高阶函数简化代码结构,提高灵活性。
55 3

热门文章

最新文章