策略模式结合SpringBoot

news/2025/2/27 4:05:14

一 定义策略类接口

在这里插入图片描述

java">
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nullable;

public interface ApprovalStrategy<T> {

    /**
     * 返回需要的类型 不能为空
     *
     * @return
     */
    @NotNull
    Class<T> getSupportedType();

    void handlePass(T businessId, @Nullable String comment);

    void handleReject(T businessId, String comment);
}

二 定义Context

java">import lombok.AllArgsConstructor;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;

import java.util.Map;

@AllArgsConstructor
@Component
public class ApprovalContext {

    private final Map<String, ApprovalStrategy<?>> strategies;


    public <T> void executePass(String type, T businessId, @Nullable String comment) {
        ApprovalStrategy<T> strategy = getStrategyWithValidation(type);
        strategy.handlePass(convertBusinessId(strategy, businessId), comment);
    }


    public <T> void executeReject(String type, T businessId, String comment) {
        ApprovalStrategy<T> strategy = getStrategyWithValidation(type);
        strategy.handleReject(convertBusinessId(strategy, businessId), comment);
    }

    private <T> ApprovalStrategy<T> getStrategyWithValidation(String type) {
        @SuppressWarnings("unchecked")
        ApprovalStrategy<T> strategy = (ApprovalStrategy<T>) strategies.get(type);
        if (strategy == null) {
            throw new IllegalArgumentException("未知的审批类型:" + type);
        }
        return strategy;
    }

    private <T> T convertBusinessId(ApprovalStrategy<T> strategy, Object businessId) {
        Class<T> supportedType = strategy.getSupportedType();
        if (supportedType == null) {
            throw new NullPointerException("supportedType 不能为空");
        }
        if (!supportedType.isInstance(businessId)) {
            if (supportedType == Integer.class && businessId instanceof String) {
                return supportedType.cast(Integer.valueOf((String) businessId));
            } else {
                throw new IllegalArgumentException(
                        "不支持的类型转换:" + businessId.getClass() + " 到 " + supportedType
                );
            }
        }
        return supportedType.cast(businessId);
    }


}


三 实现类

java">
@Component("TEST_REVIEW")
@RequiredArgsConstructor
public class TestApproval implements ApprovalStrategy<Integer> {

    @Override
    public void handlePass(Integer businessId, @Nullable String comment) {

    }

    @Override
    public void handleReject(Integer businessId, String comment) {

    }

    @NotNull
    @Override
    public Class<Integer> getSupportedType() {
        return Integer.class;
    }
}

这里TEST_REVIEW为ApprovalType枚举中的常量字符 利用spring将其收集到ApprovalContext类的strategies中

使用:

1 注入private final ApprovalContext approvalContext;
2 approvalContext.executePass(ApprovalType.TEST_REVIEW.name(), id, null);
|| approvalContext.executeReject(ApprovalType.TEST_REVIEW.name(), id, null);
这里可以用个枚举 来规范调用


http://www.niftyadmin.cn/n/5869428.html

相关文章

精准识别IP应用场景

基于全球领先的IP应用场景识别服务IPv4/IPv6全量数据库&#xff0c;为企业提供高精度、低延迟的场景化解析能力&#xff0c;助您构建更安全、智能的网络生态。 ​精准识别&#xff0c;毫秒响应 全量数据覆盖&#xff0c;依托全球最大的IP地址库&#xff0c;支持IPv4/IPv6双协…

科技改变生活:未来趋势与应用解析

虚拟现实VR&#xff09;技术在教育领域的应用正日益受到关注。VR通过创造一个沉浸式环境&#xff0c;让学生参与到学习中&#xff0c;激发他们的兴趣。沉浸式学习是指学生在虚拟环境中体验和学习&#xff0c;通过这种方式&#xff0c;他们能够更好地理解知识。 首先&#xff0…

Android Jetpack常用组件‌

Android Jetpack常用的组件&#xff1a;首先&#xff0c;Jetpack组件很多&#xff0c;得分类讲清楚&#xff0c;用户可能不太熟悉&#xff0c;所以需要分门别类&#xff0c;每个类别下有哪些主要组件&#xff0c;各自的作用是什么。 首先想到的是架构组件&#xff0c;比如Life…

视频字幕识别和翻译

下载的视频很多不是汉语的&#xff0c;我们需要用剪映将语音识别出来作为字幕压制到视频中去。 剪映6.0以后语音识别需要收费&#xff0c;但是低版本还是没有问题。 如果想要非汉语字幕转成中文&#xff0c;剪映低版本不提供这样功能。但是&#xff0c;用剪映导出识别字幕&am…

深入理解 Flink 中的 .name() 和 .uid() 方法

在 Apache Flink 中&#xff0c;.name() 和 .uid() 是两个常用的配置方法。虽然它们看起来相似&#xff0c;但它们各自有着不同的功能和用途&#xff0c;理解这两个方法的区别和各自的应用场景&#xff0c;能够帮助开发者更好地管理 Flink 作业&#xff0c;提升作业的可读性、可…

30 分钟从零开始入门 CSS

前言 最近也是在复习&#xff0c;把之前没写的博客补起来&#xff0c;之前给大家介绍了 html&#xff0c;现在是 CSS 咯。 30分钟从零开始入门拿下 HTML_html教程-CSDN博客 一、CSS简介&#xff1a;给网页“化妆”的神器 CSS&#xff08;层叠样式表&#xff09;就像“化妆“&a…

Spring 三级缓存机制(解决循环依赖)

文章目录 &#x1f504; 现实生活类比&#xff1a;开餐厅的过程&#x1f4a1; 结合到 Spring 三级缓存&#x1f6e0;️ Spring 解决循环依赖的步骤1️⃣ Spring 开始创建 A2️⃣ Spring 开始创建 B3️⃣ B 创建完成后&#xff0c;回过头来继续创建 A &#x1f4cc; 三级缓存的作…

Windows 图形显示驱动开发-WDDM 3.2-自动显示切换(四)

控制面板自我刷新 (PSR) ADS 功能使用 PSR 来避免切换过程中出现故障。 具体来说&#xff0c;使用 PSR1&#xff08;全屏更新模式&#xff09;时&#xff0c;GPU0 和 GPU1 无需协商使用哪种 PSR 模式。 即使在 PSR1 中&#xff0c;面板也需要支持以下的可选功能&#xff1a; …