策略模式和Spring的结合在项目中的应用

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 一、策略模式          策略模式的定义: 策略模式是对算法的封装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。
一、策略模式

    
    策略模式的定义:

策略模式是对算法的封装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。策略模式通常把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。

这里写图片描述

    

二、解决了我的什么问题?

    
    在实际的项目中,完成一项任务,可以有多种不同的方式,对于新手来说我们是怎么来用的,很经典的 if…else if…else…,正如下面的这段代码,每一个平台都有自己的HuiTieTicketNumber

if (vendeeId==1){   //携程
        TicketContext ticketContextCtrip=CtripTicketContext(reportDetail,orderDetail);
        if (ticketContextCtrip!=null){
            huitiePiaoHao=new CtripHuiTieTicketNumber();
            huitiePiaoHao.handle(ticketContextCtrip);
        }
    }else if (vendeeId==2){  //去哪
        TicketContext ticketContextQunar=QunarTicketContext(reportDetail,orderDetail);
        if (ticketContextQunar!=null){
            huitiePiaoHao=new QunarHuiTieTicketNumber();
            huitiePiaoHao.handle(ticketContextQunar);
        }
    }else if (vendeeId==3){  //阿里
        TicketContext ticketContextQua=QuaTicketContext(reportDetail,orderDetail);
        if (ticketContextQua!=null){
            huitiePiaoHao=new QuaHuiTieTicketNumber();
            huitiePiaoHao.handle(ticketContextQua);
        }
    }else if (vendeeId==4){  //同程
        TicketContext ticketContextTongCheng=QunarTicketContext(reportDetail,orderDetail);
        if (ticketContextTongCheng!=null){
            huitiePiaoHao=new TongChengHuiTieTicketNumber();
            TicketContext ticketContext=huitiePiaoHao.handle(ticketContextTongCheng);
            if (ticketContext.getStatus()==2){

            }
        }
    }
}

    当然,如果只是为了完成功能,这样做确实是可行的,但是,这样也会被局限住,如果新增一个平台呢,就需要再来修改代码,这就违背了对内修改关闭,对外扩展开放的原则。所以在这个地方应用了策略模式。把每一个平台的HuiTie当成一种策略封装到独立的类中进行处理。

    

三、代码实现

    
    策略工厂类,具体的策略类是在spring注入的。

/**
 * 平台策略模式工厂类
 * Created by ling.zhang on 2017/1/21.
 */
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);
    }
}

    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>

    接口类:

/**
 * Created by ling.zhang on 2017/1/21.
 */
public interface IVendeeContextStrategy {

    boolean getTicketContext(ReportDetail reportDetail, OrderDetail orderDetail);
}

    具体的实现类:

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;
    }
 }

    每个平台都会有上面的这个Strategy类,就不一一列举了。这样的话,当你的需求中在来一个新的平台的时候,只需要新建一个类,并在spring中注入上,那么就可以用了。也符合设计原则。当你的代码中大量的出现if else的话,就说明你的代码需要进行重构了,不然的话你只会被局限在这个一个小的空间里面,当你把它解耦出来后,你面对的视野和高度就不一样了,你所能做的事情就会超出原来的很多倍。

相关实践学习
基于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
相关文章
|
1月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
158 1
|
25天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
97 62
|
23天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
12天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
25 2
|
1月前
|
设计模式 前端开发 Java
Spring MVC——项目创建和建立请求连接
MVC是一种软件架构设计模式,将应用分为模型、视图和控制器三部分。Spring MVC是基于MVC模式的Web框架,通过`@RequestMapping`等注解实现URL路由映射,支持GET和POST请求,并可传递参数。创建Spring MVC项目与Spring Boot类似,使用`@RestController`注解标记控制器类。
37 1
Spring MVC——项目创建和建立请求连接
|
1月前
|
Java 关系型数据库 MySQL
Maven——创建 Spring Boot项目
Maven 是一个项目管理工具,通过配置 `pom.xml` 文件自动获取所需的 jar 包,简化了项目的构建和管理过程。其核心功能包括项目构建和依赖管理,支持创建、编译、测试、打包和发布项目。Maven 仓库分为本地仓库和远程仓库,远程仓库包括中央仓库、私服和其他公共库。此外,文档还介绍了如何创建第一个 SpringBoot 项目并实现简单的 HTTP 请求响应。
129 1
Maven——创建 Spring Boot项目
|
1月前
|
Java 关系型数据库 MySQL
如何使用 maven 创建一个 Spring Boot项目
Maven 是一个强大的项目管理工具,通过配置 `pom.xml` 文件自动获取所需的 jar 包,提高开发效率。其核心功能包括项目构建和依赖管理。项目构建支持编译、测试、打包和发布等流程,而依赖管理则通过中央仓库、本地仓库和私有服务器获取和管理项目依赖。示例中展示了如何创建第一个 SpringBoot 项目并实现简单接口。
28 1
如何使用 maven 创建一个 Spring Boot项目
|
23天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
41 2
|
1月前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。
|
1月前
|
Java Apache Maven
Java/Spring项目的包开头为什么是com?
本文介绍了 Maven 项目的初始结构,并详细解释了 Java 包命名惯例中的域名反转规则。通过域名反转(如 `com.example`),可以确保包名的唯一性,避免命名冲突,提高代码的可读性和逻辑分层。文章还讨论了域名反转的好处,包括避免命名冲突、全球唯一性、提高代码可读性和逻辑分层。最后,作者提出了一个关于包名的问题,引发读者思考。
Java/Spring项目的包开头为什么是com?
下一篇
无影云桌面