策略模式-通过枚举newInstance替代工厂

策略模式-使用枚举newInstance

  • 前言
  • 一、枚举类:MarkCheckDataTypeEnum
  • 二、抽象类:AbstractMarkChecker
  • 三、检查类:MarkPeopleChecker
  • 四、demo演示
  • 总结


前言

很久没写文章了~~
吐槽下:入职新公司后,基本在搬砖,我爱劳动我光荣~

遇到一个小需求:根据接口入参-不同类型,进行不同字段的检查。不想写if…else嵌套,就写了个最简单的策略模式。


一、枚举类:MarkCheckDataTypeEnum

创建一个枚举类,将业务实现类作为枚举的一个属性,
如:
STD_PEOPLE(“std_people”, MarkPeopleChecker.class)

public enum MarkCheckDataTypeEnum {
    /**
     * 主体-人
     */
    STD_PEOPLE("std_people", MarkPeopleChecker.class),
    /**
     * 主体-房屋
     */
    STD_HOUSE("std_house", MarkHouseChecker.class),
    /**
     * 主体-小区
     */
    STD_RESIDENTIAL("std_residential", MarkResidentialChecker.class),
    /**
     * 主体-商铺
     */
    STD_BUSINESS("std_business", MarkBusinessChecker.class),
    /**
     * 主体-企业
     */
    STD_ENTERPRISE("std_enterprise", MarkEnterpriseChecker.class),
    /**
     * 主体-区域
     */
    STD_PARK("std_park", MarkParkChecker.class),

    ;

    /**
     * 主体类型
     */
    private String dataType;
    /**
     * 主体的预检查类
     */
    private Class<?> checker;

    MarkCheckDataTypeEnum(String dataType, Class checker) {
        this.dataType = dataType;
        this.checker = checker;
    }

    public String getDataType() {
        return dataType;
    }

    public void setDataType(String dataType) {
        this.dataType = dataType;
    }

    public Class<?> getChecker() {
        return checker;
    }

    public void setChecker(Class<?> checker) {
        this.checker = checker;
    }

    /**
     * 根据主体获取检查类
     *
     * @param dataType 主体类型
     * @return 检查类
     * @throws Exception new实例异常
     */
    public static AbstractMarkChecker getMarkChecker(String dataType) throws Exception {
        for (MarkCheckDataTypeEnum markCheckDataTypeEnum : MarkCheckDataTypeEnum.values()) {
            if (markCheckDataTypeEnum.getDataType().equals(dataType)) {
                return (AbstractMarkChecker) markCheckDataTypeEnum.getChecker().newInstance();
            }
        }
        return MarkCommonChecker.class.newInstance();
    }
}

二、抽象类:AbstractMarkChecker

BusinessException这个是自定义异常,用于抛出检查类:检查不通过的原因。
1:有点编码基础的,也可以换成自己的异常类
2:或者把不通过的原因返回出来,如:

public abstract String check(List<String> assetFieldNameList);

我的代码如下:

import lobster.base.exception.BusinessException;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 保存标注时,进行必要信息检查
 * 人:
 * 未检测到【证件号】或者【姓名】+【手机号】标注字段,而有其他人员非必要信息字段标注的情况下
 * 提示:您的标注信息未包含人员必要信息字段【证件号】或【姓名+手机号】,可能导致人员信息数据无法入库,请仔细检查。
 * <p>
 * 房屋:
 * 未检测到【房屋地址】或者【楼栋+单元+楼层+房号】或者【房号】标注字段,而有其他房屋非必要信息字段标注的情况下
 * 提示:您的标注信息未包含房屋必要信息字段【房屋地址】或【楼栋+单元+楼层+房号】或【房号】,可能导致房屋信息数据无法入库,请仔细检查。
 * <p>
 * <p>
 * 小区:
 * 未检测到【小区名】标注字段,而有其他小区非必要信息字段标注的情况下
 * 提示:您的标注信息未包含小区必要信息字段【小区名】,可能导致小区信息数据无法入库,请仔细检查。
 * <p>
 * 商铺:
 * 未检测到【商铺名称+商铺地址】标注字段,而有其他商铺非必要信息字段标注的情况下
 * 提示:您的标注信息未包含商铺必要信息字段【商铺名称+商铺地址】,可能导致商铺信息数据无法入库,请仔细检查。
 * <p>
 * 企业:
 * 未检测到【企业名称+企业地址】标注字段,而有其他企业非必要信息字段标注的情况下
 * 提示:您的标注信息未包含企业必要信息字段【企业名称+企业地址】,可能导致企业信息数据无法入库,请仔细检查。
 * <p>
 * 区域:
 * 未检测到【区域名称】标注字段,而有其他区域非必要信息字段标注的情况下
 * 提示:您的标注信息未包含区域必要信息字段【区域名称】,可能导致区域信息数据无法入库,请仔细检查。
 *
 * @author lobster
 */
@Service
public abstract class AbstractMarkChecker {

    /**
     * 检查主体必要字段
     *
     * @param assetFieldNameList 当前主体,标注时选择的字段
     * @throws BusinessException 业务异常
     */
    public abstract void check(List<String> assetFieldNameList) throws BusinessException;
}

三、检查类:MarkPeopleChecker

检查类和MarkCheckDataTypeEnum的checker对应。
这里只贴一个MarkPeopleChecker,检查类都差不多

import lobster.base.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 人:
 * 未检测到【证件号】或者【姓名】+【手机号】标注字段,而有其他人员非必要信息字段标注的情况下
 * 提示:您的标注信息未包含人员必要信息字段【证件号】或【姓名+手机号】,可能导致人员信息数据无法入库,请仔细检查。
 *
 * @author lobster
 */
@Slf4j
@Service
public class MarkPeopleChecker extends AbstractMarkChecker {
    private static final String NAME = "name";
    private static final String ID_CARD = "id_card";
    private static final String MOBILE = "mobile";

    @Override
    public void check(List<String> assetFieldNameList) throws BusinessException {
        boolean containsName = assetFieldNameList.contains(NAME);
        boolean containsIdCard = assetFieldNameList.contains(ID_CARD);
        boolean containsMobile = assetFieldNameList.contains(MOBILE);
        if (containsIdCard) {
            log.info("标注主体:std_people 存在【证件号】");
            return;
        }
        if (containsName && containsMobile) {
            log.info("标注主体:std_people 存在【姓名】+【手机号】");
            return;
        }
        throw new BusinessException(500, "您的标注信息未包含人员必要信息字段【证件号】或【姓名+手机号】,可能导致人员信息数据无法入库,请仔细检查");
    }
}

四、demo演示

直接执行main方法就行

代码如下(示例):

import com.example.springDemo.markprecheck.MarkCheckDataTypeEnum;
import com.google.common.collect.Lists;
import lobster.base.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController("mark/pre/check")
public class MarkPreCheckController {


    @GetMapping(value = "demo", name = "通过枚举实现策略")
    public static String demo() {
        try {
            MarkCheckDataTypeEnum.getMarkChecker("std_people").check(Lists.newArrayList("name", "sex"));
        } catch (BusinessException e) {
            log.error("出现业务异常:", e);
            return e.getMsg();
        } catch (Exception e) {
            log.error("出现系统异常:", e);
            return e.getMessage();
        }
        return "success";
    }
	//直接执行main方法就行
    public static void main(String[] args) {
        String errorMsg = demo();
        System.out.println(errorMsg);
    }
}

实例代码打印结果:
在这里插入图片描述


总结

总来的来,emm~~这个示例很简单,没啥说的。
主要是通过MarkCheckDataTypeEnum.getMarkChecker()来获取检查类实例,然后调用检查类的check方法。
通过扩展枚举类MarkCheckDataTypeEnum与具体的检查类,对代码进行解耦。但解耦不多,不如工厂+策略的方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/744418.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CppInsights: 学习C++模版的神器

CppInsights&#xff1a;深入理解C代码的利器 C是一门强大而复杂的编程语言&#xff0c;其复杂性主要体现在语言的多层次抽象和丰富的语法特性上。尽管这些特性使得C能够高效地处理复杂的任务&#xff0c;但也给开发者带来了理解和调试代码的巨大挑战。CppInsights正是在这一背…

RabbitMQ(消息队列)

RabbitMQ 它是消息中间件&#xff0c;是在消息的传输过程中保存消息的容器&#xff0c;实现应用程序和应用程序之间通信的中间产品。目前主流消息队列通讯协议是AMQP&#xff08;二进制传输&#xff0c;支持多种语言&#xff09;、JMS&#xff08;HTTP传输&#xff0c;只支持J…

【PyQt5】一文向您详细介绍 setSpacing() 的作用

【PyQt5】一文向您详细介绍 setSpacing() 的作用 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的普通本硕&am…

南昌服务器托管让数据存储更安全

南昌&#xff0c;作为长江中游地区的重要中心城市&#xff0c;近年来经济发展迅速&#xff0c;产业结构不断优化。随着大数据、云计算、人工智能等新一代信息技术的快速发展&#xff0c;南昌的信息化建设步伐不断加快&#xff0c;为企业提供了良好的发展环境。在这样的背景下&a…

LabVIEW技术交流-控件的禁用属性与Mouse Up事件的一个坑

问题来源 我们平时对控件Mouse Up事件触发使用场景不多&#xff0c;可能在按钮控件上会偶尔用到。在一些场景中&#xff0c;我们用按钮的Mouse Up触发事件&#xff0c;但是又希望在某些限制条件下&#xff0c;按钮会被禁用而不能触发事件。 可是当我们禁用按钮时&#xff0c;它…

P2实验室装修标准都有哪些

P2实验室&#xff08;也称为生物安全二级实验室&#xff0c;BSL-2实验室&#xff09;的装修标准需要满足一系列的设计和施工要求&#xff0c;以确保实验室的安全性和功能性。因此&#xff0c;P2实验室装修标准不仅要满足一般实验室的要求&#xff0c;还需符合生物安全的特殊规定…

穿越千年的智慧之光——唐宋时期的节能“黑科技”省油灯

唐宋时期&#xff0c;中国古代科技达到了一个高峰&#xff0c;许多创新发明不仅在当时引领潮流&#xff0c;甚至在今天看来也充满了智慧的光辉。其中&#xff0c;一项名为“省油灯”的发明&#xff0c;便是当时节能减排的杰出代表&#xff0c;连著名诗人陆游都为之倾倒&#xf…

123.网络游戏逆向分析与漏洞攻防-邮件系统数据分析-收邮件功能的完善与优化

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

最强开源模型来了!一文详解 Stable Diffusion 3 Medium 特点及用法

前言 最强开源模型来了&#xff01;一文详解 Stable Diffusion 3 Medium 特点及用法&#xff08;附模型资源包&#xff09; 大家好&#xff0c;我是AI绘画小33~ 备受期待的 Stable Diffusion 3&#xff08;以下简称 “SD3”&#xff09;终于向公众开放了&#xff0c;作为 S…

大厂薪资福利篇第四弹:字节跳动

欢迎来到绝命Coding&#xff01; 今天继续更新大家最关心的 大厂薪资福利系列&#xff01; 往期分享&#xff1a; 福利开水喝不完&#xff1f;大厂薪资福利篇&#xff01;美团 职场文化发源地&#xff1f;大厂薪资福利篇&#xff01;阿里巴巴 给这么多&#xff01;还能带宠物上…

用英文介绍纽约:NEW YORK, USA‘s MEGACITY

NEW YORK, USA’s MEGACITY | America’s Largest City Link: https://www.youtube.com/watch?vdzjQ-akB3BI&listPLmSQiOQJmbZ7TU39cyx7gizM9i8nOuZXy&index24 The story of New York City, America’s megalopolis. Summary Paragraph 1: The Historical Developm…

站在巨人的肩膀上 C语言理解和简单练习(包含指针前的简单内容)

1.格式化的输入/输出 1.1printf函数 printf函数你需要了解的就是转换说明&#xff0c;转换说明的作用是将内存中的二进制转换成你所需要的格式入%d就是将内存中存储的变量的二进制转化为十进制并打印出来&#xff0c;同时我们可以在%X的转换说明对精度和最小字段宽度的指定&a…

第 133 场 LeetCode 双周赛题解

A 使所有元素都可以被 3 整除的最少操作数 遍历 n u m s nums nums &#xff0c;每有一个不被 3 3 3 整除的数&#xff0c;则操作数加 1 1 1 class Solution {public:int minimumOperations(vector<int>& nums) {int res 0;for (auto x : nums)if (x % 3 ! 0)res…

基于JSP的在线教育资源管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果你对在线教育资源管理系统感兴趣或者有相关需求&#xff0c;欢迎在文末找到我的联系方式。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;JSP技术 工具&#xff1a;IDE、N…

excel表格加密:电脑文件加密的5个方法介绍【新手篇】

为了防止数据泄露&#xff0c;编辑好表格文件后一般都会加上密码。敏感数据的泄露会导致严重的商业损失和声誉损害。Excel表格加密方法有很多&#xff0c;包括金舟文件夹加密大师、金舟ZIP解压缩、工作簿密码设置等方法。 下面分享5个excel表格加密方法&#xff0c;希望能够帮到…

RuoYi-Vue教程

若依搭建 若依版本 官方 若依官方针对不同开发需求提供了多个版本的框架&#xff0c;每个版本都有其独特的特点和适用场景&#xff1a; 前后端混合版本&#xff1a;RuoYi结合了SpringBoot和Bootstrap的前端开发框架&#xff0c;适合快速构建传统的Web应用程序&#xff0c;其…

36.基于多目标螳螂优化算法的微电网优化matlab

微♥关注“电击小子程高兴的MATLAB小屋”获取资源 基于螳螂优化算法的多目标优化算法 求解微电网多目标优化调度 比较不同目标函数寻优对调度结果的影响 第1种.将两个目标函数值归一化相加&#xff0c;取相加后最小的目标值的粒子&#xff0c;即寻找折衷解并画图 第2种寻找…

代码随想录-Day39

62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&…

服务器硬件及RAID配置

目录 一、RAID磁盘阵列 1.概念 2.RAID 0 3.RAID 1 4.RAID 5 5.RAID 6 6.RAID 10 二、阵列卡 1.简介 2.缓存 三、创建 1.创建RAID 0 2.创建RAID 1 3.创建RAID 5 4.创建RAID 10 四、模拟故障 一、RAID磁盘阵列 1.概念 &#xff08;1&#xff09;是Redundant Array …

【Java毕业设计】基于JavaWeb的房屋出租系统

本科毕业设计论文 题目&#xff1a;房屋交易平台设计与实现 系 别&#xff1a; XX系&#xff08;全称&#xff09; 专 业&#xff1a; 软件工程 班 级&#xff1a; 软件工程15201 学生姓名&#xff1a; 学生学号&#xff1a; 指导教师&#xff1a; 导师1 导师2 文章目录 摘…