函数式接口实现策略模式

news2024/11/15 5:31:14

函数式接口实现策略模式

1.案例背景

我们在日常开发中,大多会写if、else if、else 这样的代码,但条件太多时,往往嵌套无数层if else,阅读性很差,比如如下案例,统计学生的数学课程的成绩:

  • 90-100分,打印【优秀A+】
  • 80-90分,打印【优秀A-】
  • 70-80分,打印【中等B+】
  • 60-70,打印【中等B-】
  • 60及以下,打印【同学还需努力!】
    我们会写如下代码:
 // 0<=grade<=100
 if (grade > 90 && grade <= 100) {
            System.out.println("【优秀A+】");
        } else if (grade > 80 && grade <= 90) {
            System.out.println("【优秀A-】");
        } else if (grade > 70 && grade <= 80) {
            System.out.println("【中等B+】");
        } else if (grade > 60 && grade <= 70) {
            System.out.println("【中等B-】");
        } else {
            System.out.println("【同学还需努力!】 ");
        }

毋庸置疑,上述代码完全正确,可以满足业务要求,但考虑到未来业务的扩展性与代码的可阅读性,大量的if、else语句使代码不够优雅,随着后续业务的增加,分类可能越来越细,岂不是要嵌套成百上千层。接下来考虑使用函数式接口+策略模式的思想完成代码改造。

2.代码改造

2.1 创建函数式策略接口

创建自定义函数式策略接口:

/**
 * 函数式策略接口
 */
@FunctionalInterface
public interface GradeFuncInterface {

    /**
     * 打印成绩方法
     * @param grade 实际成绩
     */
    void printStudentGrade(Integer grade);
}

2.2 创建策略方法类

创建策略方法类,相关注释已在代码中标注:

import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;

/**
 * 策略方法
 */
public class GradeStrategy {

    /**
     * 存储策略逻辑
     * 这里使用到了另外一个JDK提供的函数式接口,Predicate,里面几个方法很简单,大家感兴趣可以点进去阅读下底层源码
     */
    private final Map<Predicate<Integer>, GradeFuncInterface> gradeMap = new HashMap<>();

    /**
     * 无参构造
     */
    public GradeStrategy() {
        gradeMap.put(grade -> this.determineGrade(grade, 100, 90), ((grade) -> System.out.println("【优秀A+】")));
        gradeMap.put(grade -> this.determineGrade(grade, 90, 80), ((grade) -> System.out.println("【优秀A-】")));
        gradeMap.put(grade -> this.determineGrade(grade, 80, 70), ((grade) -> System.out.println("【中等B+】")));
        gradeMap.put(grade -> this.determineGrade(grade, 70, 60), ((grade) -> System.out.println("【中等B-】")));
        gradeMap.put(grade -> this.determineGrade(grade, 60, -1), ((grade) -> System.out.println("【同学还需努力!】")));
    }

    /**
     * 判断成绩的区间
     * @param grade 实际成绩
     * @param maxGrade 最大成绩
     * @param minGrade 最小成绩
     * @return
     */
    private boolean determineGrade(Integer grade, Integer maxGrade, Integer minGrade) {
        if (grade > minGrade && grade <= maxGrade) {
            return true;
        }
        return false;
    }

    /**
     * 获取成绩区间
     * @param grade
     */
    public void getStudentGrade(Integer grade) {
        // 遍历策略map
        for (Map.Entry<Predicate<Integer>, GradeFuncInterface> entry : gradeMap.entrySet()) {
            if (entry.getKey().test(grade)) {
                entry.getValue().printStudentGrade(grade);
                return;
            }
        }
        System.out.println("学生成绩为:" + grade + "无对应期间成绩,请维护!");
    }
}

3. 测试

3.1 创建测试类

测试类代码如下:

public class StrategyTest {
    public static void main(String[] args) {
        GradeStrategy gradeStrategy = new GradeStrategy();
        gradeStrategy.getStudentGrade(98);
        gradeStrategy.getStudentGrade(88);
        gradeStrategy.getStudentGrade(78);
        gradeStrategy.getStudentGrade(68);
        gradeStrategy.getStudentGrade(58);
        gradeStrategy.getStudentGrade(128);
        gradeStrategy.getStudentGrade(-18);
    }
  }

3.2 运行结果

通过运行结果,可知输出结果正确。
在这里插入图片描述

4. 总结

通过策略模式的思想+函数式接口,我们将大量的if else判断分解出来,在调用端只需要调用策略类提供的方法,使代码更加优雅,当业务需要扩展时,我们只需要加上对应策略即可,使我们只用注重业务逻辑层的代码,让运维更加方便简洁。

备注:另外一种策略模式的使用见:工厂模式+策略模式

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微分方程(Blanchard Differential Equations 4th)中文版Section6.1

拉普拉斯变换 积分变换 在本章中&#xff0c;我们研究了一种工具——拉普拉斯变换&#xff0c;用于解微分方程。拉普拉斯变换是众多不同类型的积分变换之一。一般来说&#xff0c;积分变换解决的问题是&#xff1a;一个给定的函数 y ( t ) y(t) y(t) 在多大程度上“像”一个…

温馨网站练习运用

第二次与团队一起制作网页虽然不进行商用&#xff0c;但是练习一下还是好的&#x1f60a;&#x1f60a; 我主要负责后端部分&#xff0c;该项目用了SpringBoot框架、SpringSecurity的安全框架、结合MyBatis-Plus的数据库查询。如果想看看&#xff0c;网站&#xff1a;温馨网登…

Python基础性知识(中部分)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1、Python中的语句1.1 顺序语句1.2 条件语句1.3 循环语句1.3.1 while循环1.3.2 for循环1.3.3 break与continue语句 1.4 综合三大语句制作小游戏--人生重开模拟器…

opencv之形态学

文章目录 1. 什么是形态学2. 形态学操作2.1 腐蚀2.2 膨胀2.3 通用形态学函数2.4 开运算2.5 闭运算2.6 形态学梯度运算2.7 礼帽运算2.8 黑帽运算 1. 什么是形态学 在图像处理领域&#xff0c;形态学是一种基于形状的图像分析技术&#xff0c;用于提取和处理图像的形态特征。这包…

存储架构模式-分片架构和分区架构

分片架构 分片架构就可以解决主从复制存在的问题&#xff0c;如果主机能够承担写的性能&#xff0c;那么主从就够了&#xff0c;如果不能&#xff0c;那么就需要分片架构了。 分片架构设计核心 分片架构设计核心-分片规则 案例1&#xff1a;不合理&#xff0c;因为不同年龄是不…

echarts组件——饼图

echarts组件——饼图 饼图&#xff0c;环形图 组件代码 <template><div :class"classname" :style"{height:height,width:width}" /> </template><script> // 环形图 import * as echarts from echarts require(echarts/them…

计算机毕业设计PySpark+Scrapy农产品推荐系统 农产品爬虫 农产品商城 农产品大数据 农产品数据分析可视化 PySpark Hadoop

(1)能够根据计算机软硬件知识和数学知识给出复杂工程设计的基本思路和解决方案&#xff1b;在考虑社会、健康、安全、法律、文化以及环境等因素下可对设计方案及软硬件系统等在技术、经济等方面进行评价&#xff0c;确认其可行性&#xff1b; (2)能够建立软硬件系统、应用数学、…

【鸿蒙开发】02 复刻学习文档之待办列表

文章目录 一、前言叨叨二、创建应用三、项目初始化及代码分析1. 应用启动入口2. 解读Demo代码并Copy3、常量数据及静态资源文件AppStore下的resourcesentry下的resources 四、效果展示 一、前言叨叨 在考试内容看完之后&#xff0c;并且获取到了高级认证&#xff0c;但是在真正…

linux系统中USB模块鼠标驱动实现

各位开发者大家好,今天主要给大家分享一下,Linux系统中使用libusb的方法以及鼠标驱动实现。 第一:libusb概述 参考网址:* libusb GIT仓库:https://github.com/libusb/libusb.git * libusb 官网:https://libusb.info/ * libusb API接口:https://libusb.sourceforge.io/…

python中logging库使用

文章目录 1、前言2、日志的等级3、logging的基本应用4、logging的进阶应用5、logging的高阶应用6、简单调用7、参考 1、前言 编程代码中&#xff0c;日志的合理使用&#xff0c;能够很好地监控代码的运行过程&#xff1b;在业务部署中&#xff0c;通过日志的记录情况&#xff0…

5G NR 辅同步信号SSS介绍 MATLAB实现

5G NR辅同步信号SSS&#xff0c;和PSS一起包含了小区的全部ID信息&#xff0c;跟NBIOT 和LTE不一样&#xff0c;PSS和SSS并不携带任何的帧信息&#xff0c;只携带帧头同步信息&#xff0c;所以搜索完成PSS和SSS并不知道当前的slot号和帧号&#xff0c;在5G NR中&#xff0c;PSS…

Clion 使用

1. 使用CLion进行ROS开发 安装基本的ROS环境 ROS环境的安装请参考安装ROS。 安装CLion 下载CLion Linux的下载地址如下&#xff1a;CLion 解压CLion 将下载的CLion复制到/opt目录下&#xff08;你可以解压到适合自己的文件夹&#xff0c;只要保证后续使用的路径一致即可…

黑神话悟空-用签名检查以允许加载 mod .pak(安装MOD可以不用再使用“ -fileopenlog “命令)

安装 下载并解压到 BlackMythWukong\b1\Binaries\Win64 位置参考&#xff1a; 安装此 mod 后&#xff0c;再安装.pak类型MOD时就可以不再使用" -fileopenlog "命令也可以生效了.因为该命令可能会导致在具有常规 HDD 的低配置计算机上卡顿。 下载地址&#xff1a;h…

macos 10.15 Catalina 可用docker最新版本 Docker Desktop 4.15.0 (93002) 下载地址与安装方法

按照docker官方的4.16.0版本发行日志"4.16.0: (2023-01-12 Minimum OS version to install or update Docker Desktop on macOS is now macOS Big Sur (version 11) or later.)" , 这个4.16.0版本就必须要求最低版本os为 11版本, 所以 旧版本的macos 10.15 Catalina …

为了支持XR,3GPP R18都做了哪些增强?

这篇是R18 XR enhancement的第二篇,主要看下从NAS->L3->L2->L1针对XR都做了哪些增强。 1 PDU set QoS 在UL和DL中,XR-Awareness有助于优化gNB无线资源调度,但是这里就依赖于 PDU set和data burst。这两个东西是什么意思?其实PDU set就是由一个或多个 PDU组成,这…

【 OpenHarmony 系统应用源码解析 】-- Launcher 桌面布局

前言 阅读本篇文章之前&#xff0c;有几个需要说明一下&#xff1a; 调试设备&#xff1a;平板&#xff0c;如果你是开发者手机&#xff0c;一样可以加 Log 调试&#xff0c;源码仍然是手机和平板一起分析&#xff1b;文章中的 Log 信息所显示的数值可能跟你的设备不一样&…

C语言中的“#”和“##”

目录 开头1.什么是#?2.什么是##?3.#和##的实际应用输出变量的名字把两个符号连接成一个符号输出根据变量的表达式…… 下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。在今天&#xff0c;我们要学一下关于C语言中的#和##的一些知识。 1.什么是#? #&#xff0…

Datawhale X 李宏毅苹果书 AI夏令营-深度学入门task2:线性模型

1.线性模型 把输入的特征 x 乘上一个权重&#xff0c;再加上一个偏置就得到预测的结果&#xff0c;这样的模型称为线性模型&#xff08;linear model&#xff09; 2.分段线性模型 线性模型也许过于简单&#xff0c;x1 跟 y 可能中间有比较复杂的关系。线性模型有很大的限制&…

上书房信息咨询:商标相似性评估调研

商标相似性评估调研可以帮助确定商标之间的相似性程度&#xff0c;为商标注册、商标权利维护和商标侵权案件提供参考依据。以下是进行商标相似性评估调研的一般步骤&#xff1a; 1、收集商标信息&#xff1a;收集相关商标的注册证书、商标注册申请、商标注册公告等信息&#x…

【测试】——开发模型与测试模型

&#x1f4d6; 前言&#xff1a;在软件开发过程中&#xff0c;理解和应用合适的开发模型与测试模型至关重要。本文将详细介绍几种常见的开发模型&#xff0c;如瀑布模型、螺旋模型、增量模型和敏捷过程&#xff0c;以及测试模型如V模型和W模型。 目录 &#x1f552; 1. 开发模型…