当前位置: 首页 > news >正文

SpringBoot中策略模式使用

✨重磅!盹猫的个人小站正式上线啦~诚邀各位技术大佬前来探秘!✨

这里有:

 

  • 硬核技术干货:编程技巧、开发经验、踩坑指南,带你解锁技术新姿势!
  • 趣味开发日常:代码背后的脑洞故事、工具测评,让技术圈不再枯燥~
  • 独家资源分享:开源项目、学习资料包,助你打怪升级快人一步!

👉 点击直达→ 盹猫猫的个人小站 👈
🌟 来逛逛吧,说不定能挖到你正在找的技术宝藏哦~

目录

简介 

策略结构

代码案例

定义类型枚举

 创建实体类

基础数据(抽象类)

点位数据(抽象类)

防火点(实体类)

水源点(实体类) 

创建服务

点位服务(接口)

点位服务(实现类) 

创建策略

策略工厂

策略服务(接口) 

防火点策略服务(实现)


欢迎来到 盹猫(>^ω^<)的博客

本篇文章主要介绍了

[SpringBoot中策略模式使用]
❤博主广交技术好友,喜欢文章的可以关注一下❤

简介 

        在日常开发中,总会遇到这种情况,需要根据数据类型,选择不同的服务进行执行,或者根据类型查询数据库不同表的数据. 有的人可能立刻想到了使用If else分支或者Switch进行类型的判断,然后调用不同的服务进行处理. 在一些简单应用中,其实是可以,但当分支较多时,这么设计就会使代码臃肿,并且处理速度会非常的慢. 这时候就可以考虑使用策略模式来进行代码的重构.

策略结构

        策略模式主要就是为解决多分支的选择,如上图所示,策略结构中核心为策略工厂,工厂中一般会维护着一个或多个Map(可以将这个工厂与switch分支或IF语句对等),Map中维护着多个策略,就是多个不同类型的处理服务实现(可以理解为分支内的具体逻辑).这样就保证了,在主服务(这里是PointDataService)可以直接使用工厂类通过类型,选择具体的处理策略进行处理.

代码案例

        在这个案例中,需要实现(防火点,水源点)类型的查询,因为都是点位数据(但又有不同的数据字段),所以用一个点位数据服务进行查询实现.

定义类型枚举

package com.uav.kunyv.entity;
/*** 该枚举类用于定义点位数据类型。*/
public enum PointDataTypeEnum {/*** 防火点类数据*/FIRE("Fire"),/*** 取水点类数据*/RESERVE("Reserve"),/*** 监控点类数据*/CAMERA("Camera"),/*** 其他类型点位数据*/OTHER("Other");String value;PointDataTypeEnum(String value) {this.value = value;}public String value() {return this.value;}public static PointDataTypeEnum fromValue(String value) {for (PointDataTypeEnum type : values()) {if (type.value.equals(value)) {return type;}}return OTHER; // 或抛出异常}
}

 创建实体类

基础数据(抽象类)

package com.uav.kunyv.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** @author xh* 2025/7/31 10:17*/
@Data
public abstract class BaseEntity implements Serializable {/*** id*/@TableId@JsonSerialize(using = ToStringSerializer.class)private Long id;/*** 创建者*/@TableField(fill = FieldFill.INSERT)private Long creator;/*** 创建时间*/@TableField(fill = FieldFill.INSERT)private Date createDate;
}

点位数据(抽象类)

package com.uav.kunyv.entity;import lombok.Data;/*** 所有点位类型数据的抽象类* 防火点、水库、摄像头等都可以继承此类* 继承后 id,lon,lat,dictId,dataType可不用重写*/
@Data
public abstract class BasePointDataEntity extends BaseEntity{/*** 经度*/private Double lon;/*** 纬度*/private Double lat;/*** 类型ID*/private Long dictId;/*** 数据类型ID*/private PointDataTypeEnum dataType;}

防火点(实体类)

package com.uav.kunyv.entity;import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;/*** create by 2023/12/18** @author Mr.Cat* @since 1.0**/
@Data
@TableName("tb_fire_data")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class FireDataEntity extends BasePointDataEntity implements IPointData{/** 名称 */private String name;/** 负责人 */private String charge;/** 人员列表 */private Long personnel;/** 负责人联系方式 */private String chargePhone;/** 设备 */private String device;/** 责任人 */private String duty;/** 车辆 */private String vehicle;@Overridepublic PointDataTypeEnum getPointType() {return PointDataTypeEnum.FIRE;}
}

水源点(实体类) 

package com.uav.kunyv.entity;import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;/*** create by 2024/1/16* 水源地实体类* @author Mr.Cat* @since 1.0**/
@Data
@TableName("tb_reservoir")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Reservoir extends BasePointDataEntity implements IPointData {/** 类型 */private String type;/** 村庄名 */private String village;/** 容量 */private String capacity;/** 深度 */private String depth;/** 平均深度 */private String avgDepth;/** 面积 */private String area;@Overridepublic PointDataTypeEnum getPointType() {return PointDataTypeEnum.RESERVE;}
}

创建服务

点位服务(接口)

package com.uav.kunyv.service;import com.uav.kunyv.common.page.PageData;
import com.uav.kunyv.entity.IPointData;import java.util.Map;public interface PointDataService {//分页查询点位数据PageData<IPointData> page(Map<String,Object> params);void add(IPointData pointData);
}

点位服务(实现类) 

package com.uav.kunyv.service.impl;import com.uav.kunyv.common.page.PageData;
import com.uav.kunyv.common.service.impl.BaseService;import com.uav.kunyv.dao.PointDataDao;
import com.uav.kunyv.entity.*;
import com.uav.kunyv.service.PointDataService;
import com.uav.kunyv.service.strategy.PointDataStrategyFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;@Service
@Slf4j
public class PointDataServiceImpl implements PointDataService {@AutowiredPointDataStrategyFactory pointDataStrategyFactory;@Overridepublic PageData<IPointData> page(Map<String, Object> params) {PointDataTypeEnum pointType = PointDataTypeEnum.fromValue((String) params.get("pointType"));return pointDataStrategyFactory.getStrategy(pointType).page(params);}@Overridepublic void add(IPointData pointData) {pointDataStrategyFactory.getStrategy(pointData.getPointType()).add(pointData);}}

创建策略

策略工厂

package com.uav.kunyv.service.strategy;import com.uav.kunyv.entity.PointDataTypeEnum;
import com.uav.kunyv.exception.SysException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.EnumMap;
import java.util.Map;@Service
public class PointDataStrategyFactory {private final Map<PointDataTypeEnum, PointDataStrategy> strategyMap = new EnumMap<>(PointDataTypeEnum.class);@Autowiredpublic PointDataStrategyFactory(FireDataPointStrategy fireDataPointStrategy) {strategyMap.put(PointDataTypeEnum.FIRE, fireDataPointStrategy);}public PointDataStrategy getStrategy(PointDataTypeEnum type) {PointDataStrategy strategy = strategyMap.get(type);if (strategy == null) {throw new SysException("不支持的点位类型: " + type);}return strategy;}
}

策略服务(接口) 

package com.uav.kunyv.service.strategy;import com.uav.kunyv.common.page.PageData;
import com.uav.kunyv.entity.IPointData;import java.util.Map;public interface PointDataStrategy {PageData <IPointData> page(Map<String, Object> params);void add(IPointData pointData);void del(Long[] ids);void update(IPointData pointData);
}

防火点策略服务(实现)

package com.uav.kunyv.service.strategy;import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uav.kunyv.common.constant.Constant;
import com.uav.kunyv.common.page.PageData;
import com.uav.kunyv.common.service.impl.BaseService;
import com.uav.kunyv.common.util.ConvertUtils;
import com.uav.kunyv.dao.FireDataDao;
import com.uav.kunyv.entity.FireDataEntity;
import com.uav.kunyv.entity.IPointData;
import com.uav.kunyv.exception.SysException;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@Service
public class FireDataPointStrategy extends BaseService<FireDataDao,FireDataEntity> implements PointDataStrategy{@Overridepublic PageData<IPointData> page(Map<String, Object> params) {String[] orderFields = {Constant.CREATE_DATE};boolean[] asc = {false};IPage<FireDataEntity> page = getPage(params, orderFields, asc);List<FireDataEntity> list = baseDao.list(params);return new PageData<>(new ArrayList<>(list),page.getTotal());}@Overridepublic void add(IPointData pointData) {if (pointData == null){throw new SysException("pointData is null");}FireDataEntity entity = ConvertUtils.sourceToTarget(pointData, FireDataEntity.class);insert(entity);}@Overridepublic void del(Long[] ids) {deleteBatchIds(Arrays.asList(ids));}@Overridepublic void update(IPointData pointData) {if (pointData == null){throw new SysException("pointData is null");}FireDataEntity entity = ConvertUtils.sourceToTarget(pointData, FireDataEntity.class);updateById(entity);}
}

在上述代码中,核心代码为策略工厂的实现,通过创建策略工厂和实现相关策略,可以保证在点位服务的实现类中可以通过工厂类进行不同策略的调用.从而减少了传统的判断分支方法的实现,同时整个系统的可扩展性和运行速度得到了优化.

速度优化主要原因是通过Map选择比传递的分支判读速度更快.


如果你对区块链内容感兴趣可以查看我的专栏:小试牛刀-区块链

感谢您的关注和收藏!!!!!!

http://www.dtcms.com/a/316209.html

相关文章:

  • tcp 确认应答和超时时间
  • mq_timedsend系统调用及示例
  • Lua语言程序设计1:基础知识、数值、字符串与表
  • DDOS攻击和CC攻击对服务器的伤害有哪些?
  • 蘑兔音乐:音乐创作的神奇钥匙​
  • AI产品经理手册(Ch9-11)AI Product Manager‘s Handbook学习笔记
  • Linux系统交叉编译:依赖、构建与实践
  • makefile的使用与双向链表
  • 使用YOLOv8-gpu训练自己的数据集并预测
  • 多传感器融合
  • 2025暑期作业
  • 企业如何用现代数仓架构挖掘新业务盈利点?AllData产品从目标、路径、结果给出答案
  • 分布式文件系统06-分布式中间件弹性扩容与rebalance冲平衡
  • 集成学习与随机森林:从原理到实践指南
  • 解决VScode无法打开本地文件夹及远程连接后无反应的问题
  • Maven和Gradle在构建项目上的区别
  • 范式集团与海博思创成立合资公司,杀入“AI+储能”赛道
  • 机器学习之KNN、贝叶斯与决策树算法
  • 【题解】P3172 [CQOI2015] 选数(倍数莫反做法)
  • 深圳多奥500KG磁力锁(DAIC-MJ-500S)技术解析与产品优势报告,应用到门禁系统坚若磐石!
  • 计算机网络 第2章通信基础(竟成)
  • Pycaita二次开发基础代码解析:参数化模板创建与设计表驱动建模
  • 【Java面试题】注解,异常相关知识
  • Go语言的gRPC教程-错误处理
  • Android AppSearch 深度解析:现代应用搜索架构与实践
  • Elasticsearch向量库
  • 【web应用】前后端分离项目基本框架组成:Vue + Spring Boot 最佳实践指南
  • 深度解析 TCP 三次握手与四次挥手:从原理到 HTTP/HTTPS 的应用
  • 微服务—OpenFeign
  • Spring中七种Propagation类的事务属性详解