spring boot策略模式实用: 告警模块为例

spring boot策略模式实用: 告警模块

0 涉及知识点

策略模式, 模板方法, 代理, 多态, 反射

1 需求概括

  • 场景: 每隔一段时间, 会获取设备运行数据, 如通过温湿度计获取到当前环境温湿度;
  • 需求: 对获取回来的进行分析, 超过配置的阈值需要产生对应的告警

2 方案设计

告警的类别往往容易变化, 比如今天只有温度过高告警, 明天可能就要增加一个温度过低告警, 所以设计最好可以满足开闭原则, 方便后续对功能进行删减;

整体思路如下:

  • 顶层接口Handler 定义了两个方法, check 用于校验是否应该产告警, 入参可以选择传入告警配置和需要判定对象, handle方法主要用于告警的具体处理过程, 如之前是否存在告警等;
  • 统一抽象类AbstractHandler 中, 重写handle 方法, 作为模版方法, 一般不同的告警处理流程是相近的, 可以抽象处理, 如都要判断进行判断当前是否已存在告警等; 抽象类中还可以抽象出通用的方法和声明通用属性;
  • 各个具体实现类, 如TemperatureHandler 等, 各类告警的具体实例对象, 如果告警判定方式或处理流程上有不同, 可以选择性的重写check 方法或handle方法, 由于java的多态, 程序运行时会选择正确处理方式;

为了保证模块的完整性, 增加代理类屏蔽告警的内部处理逻辑, 外部统一通过代理类调用;

3 代码实现

  • 接口

    java 复制代码
    /**
     * 顶级接口
     * @author lixiyuan
     */
    public interface Handler {
    
        boolean check(AlarmConfig config, Object data);
    
        void handle(AlarmConfig config, Integer id, Object data);
    }
  • 抽象类

    java 复制代码
    /**
     * 抽象类, 抽取通用字段/方法, 实现模板方法
     * @author lixiyuan
     */
    public class AbstractHandler implements Handler {
    
        @Autowired
        private CurrentAlarmService currentAlarmService;
    
        @Override
        public boolean check(AlarmConfig config, Object data) {
            return false;
        }
    
        @Override
        public void handle(AlarmConfig config, Integer id, Object data) {
            // 获取当前存在的告警
            CurrentAlarm current = currentAlarmService.getCurrentAlarmById();
            // 比较阈值
            boolean check = check(config, data);
    
            // 为true发生告警
            if (check) {
                if (current == null) {
                    // 创建告警
                    currentAlarmService.save();
                } else {
                    // 更新告警
                    currentAlarmService.update();
                }
            } else {
                if (current != null) {
                    // 结束告警
                    currentAlarmService.finish();
                }
            }
        }
    
        /**
         * 反射获取属性值
         */
        protected String getValueByField(Object obj, String fieldName) {
            if (obj == null) {
                return "";
            }
            try {
                Field field = obj.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                Object value = field.get(obj);
                return value == null ? "" : value.toString();
            } catch (NoSuchFieldException | IllegalAccessException e) {
                System.out.println();
                throw new RuntimeException(e);
            }
        }
    
        /**
         * 如果判定方法比较通用, 也可以在这里定义好, 各个子类调用一下就行
         */
        protected boolean commonCompare() {
            return false;
        }
    }
  • 实现子类

    java 复制代码
    /**
     *
     * @author lixiyuan
     */
    @Component
    public class HumidityHandler extends AbstractHandler {
    
        @Override
        public boolean check(AlarmConfig config, Object data) {
            // 通过反射获取实时数据
            String humidity = getValueByField(data, "humidity");
            // 拿到配置中的阈值,然后比较, 略
            return false;
        }
    }
    
    
    /**
     *
     * @author lixiyuan
     */
    @Component
    public class TemperatureHandler extends AbstractHandler {
    
        @Override
        public boolean check(AlarmConfig config, Object data) {
            // 通过反射获取实时数据
            String humidity = getValueByField(data, "temperature");
            // 拿到配置中的阈值,然后比较, 略
            return false;
        }
    }

    代码详见: [完成代码](nanqiangli/wushixian (github.com))

相关推荐
bjzhang7517 分钟前
SpringBoot开发——Maven多模块工程最佳实践及详细示例
spring boot·maven·maven多模块工程
chusheng184036 分钟前
Java项目-基于SpringBoot+vue的租房网站设计与实现
java·vue.js·spring boot·租房·租房网站
计算机毕设孵化场1 小时前
计算机毕设-基于springboot的高校网上缴费综合务系统视频的设计与实现(附源码+lw+ppt+开题报告)
java·spring boot·计算机外设·音视频·课程设计·高校网上缴费综合务系统视频·计算机毕设ppt
代码吐槽菌2 小时前
基于SSM的毕业论文管理系统【附源码】
java·开发语言·数据库·后端·ssm
豌豆花下猫2 小时前
Python 潮流周刊#78:async/await 是糟糕的设计(摘要)
后端·python·ai
YMWM_2 小时前
第一章 Go语言简介
开发语言·后端·golang
码蜂窝编程官方2 小时前
【含开题报告+文档+PPT+源码】基于SpringBoot+Vue的虎鲸旅游攻略网的设计与实现
java·vue.js·spring boot·后端·spring·旅游
hummhumm2 小时前
第 25 章 - Golang 项目结构
java·开发语言·前端·后端·python·elasticsearch·golang
J老熊2 小时前
JavaFX:简介、使用场景、常见问题及对比其他框架分析
java·开发语言·后端·面试·系统架构·软件工程
AuroraI'ncoding3 小时前
时间请求参数、响应
java·后端·spring