java设计模式之策略模式实操

Java设计模式之策略模式示例详解 现实生活中我们到商场买东西的时候,卖场往往根据不同的客户制定不同的报价策略,比如针对新客户不打折扣,针对老客户打9折,针对VIP客户打8折...现在我们要做一个报价管理的模块,简要点就是要针对不同的客户,提供不同的折扣报价。如果是有你来做,你会怎么做?if ("新客户".equals(customType)) {System.out.println("抱歉!新客户没有折扣!");}else if ("老客户".equals(customType)) { 阅读详情

一、背景
临床服务项目流向规则匹配,比如说医生开一个“CT”检查,该检查应该由哪个科室来执行,是通过流向规则配置来决定的,具体配置如下图:
在这里插入图片描述
通过相关的条件匹配,最终找到流向科室。
二、设计思路
有几个注意的点:
(1)条件可能会变化,比如增加条件,减少条件;
(2)条件可以单选、多选、输入字符串,也就是说条件值可能是等于、包含、不等于、不包含、大于、小于、自定义输入值;
如何来设计更好的满足以上需求,从以下几个方面:
(1)表结构层面:既然条件有可能变化,那么条件名称和条件值不能设计成一个个固定的字段,这样如果如果增减或者减少条件就不必要去修改表结构;那么具体怎么设计呢?表结构设计成通用结构,包含三个主要字段:条件类型编码、条件名称、条件值;如果一个条件配置来两个或以上值,那么在表里面就对应了多条记录;
(2)代码设计模式:工厂模式+策略模式,每个配置的条件都需要去匹配,而每个条件的匹配可能相同或者不同,所以可以定义一个抽象类作为父类,每一个条件创建一个类,继承这个抽象类,抽象类主要有三个抽象方法:获取匹配器的类型代码、获取传入对象参数中该匹配器对应的入参值、条件匹配;通过工厂模式将所有匹配器进行初始化;
三、相关类定义
1、匹配器抽象类:获取匹配器的类型代码、是否自定义匹配算法、获取传入对象参数中该匹配器对应的入参值、条件匹配;
2、匹配器实现类一,配置了单个条件值;
3、匹配器实现类二,配置了多个条件值;
4、匹配器实现类三,自定义解析条件值并返回;
5、工厂类:批量创建匹配器实例;
6、匹配器持有类:对匹配器进行相关调度操作;
7、工具类:条件匹配;
四、类的详解
1、匹配器抽象类:CliFlowRuleMatcher

    /**
     * 获取条件类型代码,表示我是哪个条件,由子类去实现
     * @return
     */
    protected abstract Long getConditionTypeCode();
    /**
     * 是否自定义匹配器
     * @return bool值
     */
    public boolean isCustomMatcher();
/**
     * 规则匹配
     * @param valueSet 配置值
     * @param regularOperationCode 运算符
     * @param condition 入参对象
     * @return 匹配结果
     */
    public boolean matchDefaultValue(Collection<Long> valueSet, FlowRuleCoreExtInputDTO condition, Long regularOperationCode) {
        // 先匹配单值
        Long value = singleValueGetter().apply(condition);
        if (Objects.nonNull(value)) {
            return MatchUtil.match(valueSet, value, regularOperationCode);
        }

        // 单值没实现再匹配多值
        Collection<Long> values = multiValueGetter().apply(condition);
        if (CollectionUtil.isNotEmpty(values)) {
            return MatchUtil.match(valueSet, values, regularOperationCode);
        }
        return true;
    }

/**
     * 自定义结果 规则匹配
     * @param customizeValSet
     * @param condition
     * @param regularOperationCode
     * @return
     */
    public boolean matchCustomizeValue(Collection<String> customizeValSet, FlowRuleCoreExtInputDTO condition, Long regularOperationCode) {

        // 先匹配单值
        Collection<String> value = singleCustomizeValueGetter().apply(condition);
        if (CollectionUtil.isNotEmpty(value)) {
            return MatchUtil.matchCustomizeValue(customizeValSet, value, regularOperationCode);
        }

        // 单值没实现再匹配多值
        Collection<String> values = multiCustomizeValueGetter().apply(condition);
        if (CollectionUtil.isNotEmpty(values)) {
            return MatchUtil.matchCustomizeValue(customizeValSet, values, regularOperationCode);
        }
        return true;
    }

2、条件匹配实现类一(单个条件值):BuIdMatcher

@Component
public class BuIdMatcher extends CliFlowRuleMatcher {

    @Override
    public Long getConditionTypeCode() {
        return ConditionDeShortNameEnum.PRESCRIBED_BU_ID.getValue();
    }

    @Override
    public Function<FlowRuleCoreExtInputDTO, Long> singleValueGetter() {
        return FlowRuleCoreExtInputDTO::getBuId;
    }
}

3、条件匹配实现类二(多个条件值):CsTypeCodeMatcher

@Component
public class CsTypeCodeMatcher extends CliFlowRuleMatcher {

    @Override
    public Long getConditionTypeCode() {
        return ConditionDeShortNameEnum.CS_TYPE_CODE.getValue();
    }

    @Override
    protected Function<FlowRuleCoreExtInputDTO, Collection<Long>> multiValueGetter() {
        return FlowRuleCoreExtInputDTO::getCsTypeCodeList;
    }
}

4、条件匹配实现类三(自定义获取配置的条件):RealIPMatcher

@Component
public class RealIPMatcher extends CliFlowRuleMatcher {

    @Override
    public boolean isCustomMatcher() {
        return true;
    }

    @Override
    public Long getConditionTypeCode() {
        return ConditionDeShortNameEnum.REAL_IP.getValue();
    }

    @Override
    protected Function<FlowRuleCoreExtInputDTO, Collection<String>> singleCustomizeValueGetter() {
        return this::getRealIp;
    }

    private Collection<String> getRealIp(FlowRuleCoreExtInputDTO ruleConditionDTO){
        if (StringUtil.isNotEmpty(ruleConditionDTO.getRealIp())){
            return Arrays.asList(ruleConditionDTO.getRealIp().split(";"));
        }
        return ListUtil.emptyList();
    }
}

5、工厂类:CliFlowRuleMatcherFactory

@Component
public class CliFlowRuleMatcherFactory {

    private final Map<Long, CliFlowRuleMatcher> execDefinitionMatcherMap = new HashMap<>();

    @Autowired(required = false)
    public CliFlowRuleMatcherFactory(List<CliFlowRuleMatcher> execDefinitionMatchers) {
        if (CollectionUtil.isNotEmpty(execDefinitionMatchers)) {
            execDefinitionMatchers.forEach(execDefinitionMatcher ->
                execDefinitionMatcher.getConditionDeShortNames().forEach(conditionDeShortName ->
                    execDefinitionMatcherMap.put(conditionDeShortName, execDefinitionMatcher)
                )
            );
        }
    }

    public CliFlowRuleMatcher getByConditionDeShortName(Long conditionDeShortName) {
        return execDefinitionMatcherMap.get(conditionDeShortName);
    }
}

6、策略对象的持有类:xXxService

private boolean matchCondition(FlowRuleCoreExtInputDTO condition, CliFlowRuleOutputDTO clinicalOrderFlowRule){
        int successCount = 0;
        // 若匹配条件不存在,等于直接匹配上
        Map<Long, List<CliFlowConditionOutputDTO>> flowConditionMap = clinicalOrderFlowRule.getClinicalOrderFlowConditionList().stream().collect(Collectors.groupingBy(CliFlowConditionOutputDTO::getConditionDeShortName));
        for (Map.Entry<Long, List<CliFlowConditionOutputDTO>> entry : flowConditionMap.entrySet()) {
            CliFlowRuleMatcher matcher = this.cliFlowRuleMatcherFactory.getByConditionDeShortName(entry.getKey());
            if (Objects.isNull(matcher)) {
                // 没有匹配器
                successCount++;
                continue;
            }
            if (matcher.isCustomMatcher()) {
                Set<String> valueSetDesc = entry.getValue().stream().map(CliFlowConditionOutputDTO::getConditionValueName).collect(Collectors.toSet());
                if (matcher.matchCustomizeValue(valueSetDesc, condition, RegularOperationCodeEnum.LIKE.getCode())) {
                    // 每个元短名配置匹配成功后加1
                    successCount++;
                }
            }else{
                Set<Long> valueSet = entry.getValue().stream().map(CliFlowConditionOutputDTO::getConditionValue).collect(Collectors.toSet());
                if (matcher.matchDefaultValue(valueSet, condition, RegularOperationCodeEnum.CONTAIN.getCode())) {
                    // 每个元短名配置匹配成功后加1
                    successCount++;
                }
            }
        }
        return successCount == flowConditionMap.size();
    }

7、工具类:MatchUtil

/**
     * 配置值是否包含匹配值
     * @param configValues 配置值
     * @param matchValue 匹配值
     * @param regularOperationCode 运算符
     * @return 是否匹配
     */
    public static boolean match(Collection<Long> configValues, Long matchValue, Long regularOperationCode) {
        if (CollectionUtil.isEmpty(configValues) || Objects.isNull(matchValue) || Objects.isNull(regularOperationCode)) {
            return false;
        }

        // 等于
        if (Objects.equals(RegularOperationCodeEnum.EQUAL.getCode(), regularOperationCode)) {
            if (configValues.size() > 1) {
                return false;
            }
            return Objects.equals(configValues.iterator().next(), matchValue);
        }
        // 不等于
        if (RegularOperationCodeEnum.NOT_EQUAL.getCode().equals(regularOperationCode)) {
            if (configValues.size() > 1) {
                return false;
            }
            return !Objects.equals(configValues.iterator().next(), matchValue);
        }
        // 包含
        if (RegularOperationCodeEnum.CONTAIN.getCode().equals(regularOperationCode)) {
            return configValues.contains(matchValue);
        }
        // 不包含
        if (RegularOperationCodeEnum.NOT_CONTAIN.getCode().equals(regularOperationCode)) {
            return !configValues.contains(matchValue);
        }

        return false;
    }
策略模式的Java实现 策略模式是一种行为型设计模式,它允许在运行时选择算法的行为。这种模式将算法封装在独立的策略类中,并使得它们可以互相替换。在本文中,我们将详细介绍如何使用Java实现策略模式,并提供相应的源代码示例。通过使用策略模式,我们可以轻松地在运行时切换不同的算法,并且可以方便地扩展和维护代码。策略模式使得算法的实现与使用代码分离,提高了代码的可读性和灵活性。首先,我们需要定义一个策略接口,该接口定义了算法的抽象方法。最后,我们可以使用策略模式来选择并执行不同的算法。在上述示例中,我们首先创建了具体的策略对象。 阅读详情

相关推荐

【重温设计模式】策略模式及其Java示例

生活充满了选择,而这些选择往往会塑造我们的命运。策略模式就是这样一种设计模式,它帮助我们在面对多种算法或策略时,能够做出灵活的选择,而无需改变代码的结构。这种设计模式在很多实际的开发场景中都发挥了重要的作用。策略模式的优点是显而易见的,它可以避免使用多重条件选择语句,提高算法的复用性和灵活性。然而,它也有其缺点,主要是客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这无疑增加了客户端的复杂性,尤其是在策略类数量较多的情况下。然而,我们要明白,没有哪一种设计模式是完美的,它们都有自己的优点和缺点。

万猫学社 2057

Java设计模式——策略模式

策略模式 1.策略模式简介 策略模式:策略模式是一种行为型模式,它将对象和行为分开,将行为定义为 一个行为接口 和 具体行为的实现。策略模式最大的特点是行为的变化,行为之间可以相互替换。每个if判断都可以理解为就是一个策略。本模式使得算法可独立于使用它的用户而变化 2.模式结构 策略模式包含如下角色: Strategy: 抽象策略类:策略是一个接口,该接口定义若干个算法标识,即定义了若干个抽象方法(如下图的algorithm()) Context: 环境类 /上下文类: 上下文是依赖于接口的类(

涛涛的个人博客 9万+

大聪明教你学Java | 策略模式的进阶实现方式

之前我们讲解过设计模式中的策略模式,相信各位小伙伴对策略模式也都有了一定的了解。不过,之前我们讲到的策略模式的实现方式是简单实现,那么在实际的开发过程中我们该如何去实现策略模式呢🧐 今天我们就以支付场景为例,讲讲策略模式的进阶实现方式。

不肯过江东丶 902

[设计模式- 行为模式(11种)-03策略模式]

[设计模式- 行为模式(11种)-03策略模式]

m0_61164038的博客 569

别再死记硬背窗函数公式了!用MATLAB实战汉宁窗FIR滤波器,从频谱图看懂‘主瓣’和‘旁瓣’

本文通过MATLAB实战演示汉宁窗FIR滤波器的设计过程,帮助读者从频谱图直观理解主瓣与旁瓣的特性。文章详细对比了矩形窗与汉宁窗的频谱差异,并提供了高通滤波器设计的完整代码示例,适用于数字信号处理学习和工程应用。

weixin_30555125的博客 490

ComfyUI破限版全中文AI绘画环境搭建与工作流实战指南

节点式工作流是AI绘画领域的核心技术架构,通过将图像生成过程拆分为可配置的模块化节点,实现了对Stable Diffusion模型的精细化控制。其技术原理基于数据流编程范式,每个节点负责特定功能处理,如文本编码、采样器配置和VAE解码等。这种设计在工程实践中的核心价值在于提供了可追溯、可复用的可视化工作流,特别适合需要参数调优和批量生产的商业场景。ComfyUI作为典型的节点式AI绘画工具,在破限版中针对中文用户优化了界面支持和显卡兼容性,显著降低了技术门槛。在实际应用中,结合ControlNet和LoRA

weixin_29038155的博客 447

设计模式之策略模式(Java实现)

文章目录前言一、认识策略模式二、实现策略模式2.1、 简单实现策略模式2.2、实际小案例实现策略模式总结参考资料 前言 本篇博客是关于策略模式的实现,若文章中出现相关问题,请指出! 对应代码地址:Gitee(demo-exer/ java-Lear23designpatterns)、Github(java-demo/ java-Lear23designpatterns) 所有博客文件目录索引:博客目录索引(持续更新) 一、认识策略模式 策略模式定义:定义了算法族,将其封装起来,让它们直接可以互相替换,此模式

每个人都是独一无二的,把握好自己的节奏,跟着自己的心走。 3156

RTAB-MAP实战:用Realsense D435i在ROS中搭建室内3D地图(附避坑指南)

本文详细介绍了如何在ROS环境下,使用Intel Realsense D435i深度相机和RTAB-MAP算法进行室内3D地图构建的完整实战流程。内容涵盖环境配置、核心节点数据流解析、关键参数调优、地图保存与重定位,并提供了实用的避坑指南,帮助机器人开发者和研究者快速实现稳定的视觉SLAM应用。

weixin_29095049的博客 490

Java设计模式之《策略模式》

策略模式是一种行为设计模式,通过封装不同算法为独立策略类,使它们可以动态切换。该模式的优点包括避免多重条件判断、易于扩展且符合开闭原则,但缺点是需要客户端了解所有策略类。与工厂模式相比,策略模式侧重算法选择而非对象创建。文中以计算器应用为例,展示了如何通过策略接口、具体策略实现和上下文类实现加减乘除运算的动态切换。这种模式特别适用于需要频繁变更算法的场景,提高了代码的灵活性和可维护性。

weixin_50055999的博客 1075

RU.EXE实用指南:从基础操作到高级调试技巧

本文是RU.EXE(RW Everything)的实用指南,详细介绍了这款硬件调试工具从基础操作到高级技巧的全过程。文章阐述了RU.EXE作为直接读写硬件寄存器、内存和PCI配置空间的强大工具,如何帮助硬件工程师和开发人员高效进行底层系统调试与故障排查,并强调了安全操作的重要性。

weixin_29228203的博客 278

论文必备 - YOLOv11热力图可视化,支持指定模型,指定显示层,设置置信度,以及10种可视化实现方式

本文带来的是YOLOv11热力图可视化功能,支持,以及。我们经常看到一些论文里绘制了不同的热力图,一方面能够直观的感受其模型的有效性,另一方面也丰富了论文内容。特别是在使用了注意力模块的网络中,热力图就可以验证注意力机制是否真正聚焦到了预期的重要特征上,以便对模型的有效性和合理性进行评估。例如这篇文章中展示的,就很能够表达作者改进后的模型相比之前模型的优越性。

Limiiiing的博客 5504

Java设计模式之策略模式详解

《Java策略模式详解》摘要:策略模式是一种行为型设计模式,用于封装可互换的算法实现(如排序、支付方式等),使其可在运行时动态切换。该模式由三部分组成:策略接口定义算法契约,具体策略类实现不同算法,上下文类负责策略的选择和执行。文章以电商促销为例,展示了固定金额、百分比、满减三种折扣策略的实现,并分析了该模式的优点(灵活性高、扩展性强)与缺点(策略类增多)。典型应用场景包括排序算法、支付系统和游戏行为等。

季鸢的博客 1012

保姆级教程:ABAP 通过 HTTP POST 调用 OData 服务创建业务数据的具体例子

笔者之前的文章发布之后,有朋友在评论区留言,询问 ABAP 除了 Web Service 之外,是否也支持 HTTP 呢?ABAP 这么强大的语言,支持 HTTP 当然不在话下。网上有很多在 ABAP 系统基于 CL_HTTP_CLIENT 工具类,通过 HTTP 协议和第三方系统交互的代码例子。本文介绍笔者项目中一个实际例子,实现的是在 ABAP 系统 A 通过 HTTP 调用 OData 服务,在 ABAP 系统 B 创建业务数据的需求。下面我们按照这个套路来一步步实现。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 697

Java设计模式之策略模式

Spring AOP 提供了不同的切面(aspect)实现类,而调用者可以通过配置来指定不同的切面策略,例如通过切面实现类实现事务管理、日志记录等功能。总之,策略模式是一种常用的设计模式,在 Java 中有很多使用策略模式的代码。这些代码的共同点是它们将不同的算法或者行为封装到不同的策略类中,并且允许调用者根据需要选择不同的策略实现类来实现不同的行为。在Java中,策略模式经常被用于解决业务中的问题,例如根据不同的用户类型提供不同的价格计算策略,或者根据不同的排序方式对一组数据进行排序等。

swadian2008的博客 1110

SAR合成孔径雷达成像及处理(附带Matlab源代码)

总结:本文介绍了SAR合成孔径雷达的基本原理,并提供了使用Matlab实现SAR成像和处理的源代码示例。然后,在慢时间域进行方位压缩处理,通过计算每个接收通道的延迟和频移,将多次接收的信号叠加得到最终的成像结果。SAR成像的基本原理是通过接收雷达发射的脉冲信号的回波,并利用多次接收的信号进行叠加处理。以多普勒频移校正为例,根据雷达飞行速度和方位角,计算实际的多普勒频率,并对每个接收通道的数据进行频移校正,以消除因目标运动引起的频率偏移。通过调整参数和算法,可以实现不同的SAR成像和处理效果。

ByteJolt的博客 689

Autosar Configuration(十四)SomeIP之配置SoAd

本文主要介绍SomeIp协议栈中的SoAd在Configurator中的详细配置

king110108的专栏 2600

【设计模式】策略模式 在java中的应用

策略模式 在java中的应用

qq_42320804的博客 1094

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Java 设计模式——策略模式

本文介绍了策略模式的相关知识。

代码星辰的博客 1493

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

java策略模式_Java设计模式之策略模式详解

本文实例为大家分享了Java策略模式,供大家参考,具体内容如下1、策略模式(Strategy Pattern)是一种比较简单的模式,也叫做政策模式(PolicyPattern)。定义如下:Define a family of algorithms,encapsulate each one,and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且使它们之...

weixin_42355744的博客 1959

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【设计模式】Java设计模式 - 策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

qq_43843951的博客 776

Java设计模式-策略模式

最近学习到设计模式,现总结个人学习策略模式内容【结果一样关注过程,即注重的是行为】。 上一篇:Java设计模式-适配器模式 文章目录定义优缺点优点缺点实现代码测试 定义 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。定义好各种不同行为【策略不同】,但是其最求目的相对稳定 优缺点 优点 扩展性好,不用添加策略对原有系统无影响。 策略可以自由选择。...

cc_百川 402

Java设计模式--策略模式:从菜鸟到大神

本文深入解析Java策略模式,通过旅行出行方式和电商支付折扣等生活化案例,生动阐释策略模式的核心概念。文章首先定义了策略模式的基本原理,即通过封装一系列可互换的算法,使它们可以独立变化而不影响客户端。随后详细介绍了策略模式的三大角色:策略接口(定义行为规范)、具体策略类(实现特定算法)和上下文类(管理策略引用与切换)。通过图形绘制和支付系统等代码示例,展示了策略模式如何提高代码的灵活性和可维护性。全文采用生活化类比与专业解析相结合的方式,帮助读者从应用场景到实现细节全面理解策略模式的设计思想和使用方法。

m0_73590302的博客 601

JAVA设计模式之策略模式

JAVA设计模式之策略模式说明 说明 策略模式的定义:    定义一组算法,将每个算法都封装起来,使得它们之间可以相互替换。策略模式让算法独立于调用它的客户端而独立变化。    大白话:我有你需要的所有,你给我暗号我就给你对应的 策略模式具体实现: (1)给策略对象(枪) 定义一个公共接口 public interface Weapon { public void gun(); ...

FOREVER_DO 254
上一篇: SpringBoot的starter原理及如何自定义starter
hnlcwx2917
博客等级 码龄12年 42粉丝 55原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值