函数式接口实现策略模式

函数式接口实现策略模式

1.案例背景

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

  • 90-100分,打印【优秀A+】
  • 80-90分,打印【优秀A-】
  • 70-80分,打印【中等B+】
  • 60-70,打印【中等B-】
  • 60及以下,打印【同学还需努力!】
    我们会写如下代码:
 // 0<=grade<=100if (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) {// 遍历策略mapfor (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.mzph.cn/bicheng/53370.shtml

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

相关文章

idea添加本地环境执行模版

用Flink的环境执行时&#xff0c;因为最后会打包放服务器&#xff0c;所以有些jar包将不会打包上传&#xff0c;这些jar包用<scope>provided</scope>标记 所以这些jar包在本地运行时也会不提供&#xff0c;为了程序在本地能跑&#xff0c;我们每次执行是需手动添加…

JAVA-接口(一万四千字讲解)

目录 一、接口的概念 二、语法规则 三、接口使用 四、接口特性 五、实现多个接口 六、接口间的继承 七、接口使用实例 1.Comparable 2.写一个自己的sort 3.Comparator 八、类的克隆Clonable 1.Clonable接口 2.浅拷贝 3.深拷贝 九、抽象类和接口的区别 十、 Obje…

芯片时钟树评估的关键性能参数

前面有很多文章都介绍了PI性能的影响&#xff0c;也介绍了PSIJ对信号或时钟性能的影响&#xff0c;对于SOC设计&#xff0c;为了更好的理解电源完整性在芯片设计中的重要作用&#xff0c;对芯片的时钟树设计需要足够理解才能更好的明白电源完整性的影响。 时钟分布网络设计一直…

最基本的SELECT...FROM结构

第0种&#xff1a;最基本的查询语句 SELECT 字段名&#xff0c;字段名 FROM 表名 SELECT 1&#xff1b; SELECT 11,3*2&#xff1b; FROM SELECT 11,3*2 FROM DUAL&#xff1b;#dual&#xff1a;伪表 我们可以用它来保持一个平衡 这里我们的值不需要在任何一个表里&#xf…

9、类和对象

9.1 封装 9.1.1 封装的例子 class Student { public:string name;int age; public:void setName(string name_) {name name_;} }; int main() {Student s1;s1.setName("zhangsan");return 0; }类中的行为都叫做成员&#xff0c;例如成员属性&#xff0c;成员变量&…

飞速(FS)S5800-48T4S:如何使用MLAG?

MLAG&#xff08;多机箱链路聚合组&#xff09;可实现无缝故障转移并优化带宽利用率&#xff0c;从而增强网络冗余和提高可扩展性。它允许多台交换机作为一个统一实体运行&#xff0c;从而降低停机风险并确保网络运行不中断。飞速&#xff08;FS&#xff09;S5800-48T4S是一款支…

二维高斯函数的两种形式

第一种形式很常见 多元正态分布 多元正态分布&#xff08;Multivariate Normal Distribution&#xff09;&#xff0c;也称为多变量正态分布或多维正态分布&#xff0c;是统计学中一种重要的概率分布&#xff0c;用于描述多个随机变量的联合分布。 假设有 n n n 个随机变量…

【LabVIEW学习篇 - 18】:人机界面交互设计02

文章目录 错误处理函数简单错误处理器通用错误处理器清楚错误合并错误错误代码至错误簇转换查找第一个错误 鼠标指针 错误处理函数 在LabVIEW中&#xff0c;是通过错误输入簇和错误输出簇来传递错误信息&#xff0c;可以将底层错误信息传递到上层VI。设计人员需要对不同程度的…

2024 数学建模高教社杯 国赛(C题)| 农作物的种植策略 | 建模秘籍文章代码思路大全

铛铛&#xff01;小秘籍来咯&#xff01; 小秘籍团队独辟蹊径&#xff0c;运用等多目标规划等强大工具&#xff0c;构建了这一题的详细解答哦&#xff01; 为大家量身打造创新解决方案。小秘籍团队&#xff0c;始终引领着建模问题求解的风潮。 抓紧小秘籍&#xff0c;我们出发…

高并发内存池(一):项目介绍与定长内存池的实现

目录​​​​​​​ 项目介绍 池化技术 内存池 内存碎片 malloc工作原理 定长内存池 申请内存 释放内存 定位new VirtualAlloc函数 封装VirtualAlloc 定长内存池的最终代码 项目介绍 项目原型&#xff1a;goole的开源项目tcmalloc&#xff08;Thread-Caching Mal…

CIOE中国光博会&电巢科技即将联办“智能消费电子创新发展论坛”

在科技浪潮汹涌澎湃的当下&#xff0c;从通信领域的高速光传输&#xff0c;到消费电子中的高清显示与先进成像技术&#xff0c;光电技术的应用范围不断拓展且日益深化。而AIGC 凭借其丰富的内容供给与个性化反馈能力&#xff0c;正为新一代消费电子及智能穿戴产品开辟崭新的发展…

前端请求的路径baseURL怎么来的 ?nodejs解决cors问题的一种方法

背景&#xff1a;后端使用node.js搭建&#xff0c;用的是express 前端请求的路径baseURL怎么来的 &#xff1f; 前后端都在同一台电脑上运行&#xff0c;后端的域名就是localhost&#xff0c;如果使用的是http协议&#xff0c;后端监听的端口号为3000&#xff0c;那么前端请求…

S3C2440开发板:时钟,PWM定时器控制蜂鸣器发声

时钟 时钟和电源管理模块由三部分组成&#xff1a;时钟控制&#xff0c;USB 控制和电源控制。 S3C2440A 中的时钟控制逻辑可以产生必须的时钟信号&#xff0c;包括 CPU 的 FCLK&#xff0c;AHB 总线外设的 HCLK 以及 APB 总线外设的 PCLK。S3C2440A 包含两个锁相环&#xff08…

VBA进行excel坐标转换

在Excel里利用坐标绘图时&#xff0c;可以比较容易想到采用数据透视表&#xff0c;但是数据透视表生成的图不可更改&#xff0c;因此本案例采用VBA进行坐标变换而不改变原始值来转换图像&#xff0c;即实现图像的左右翻转和上下翻转&#xff0c;如下图所示&#xff0c;选择map的…

fastadmin 文件上传腾讯云

1-安装腾讯云SDK composer require qcloud/cos-sdk-v5 2-腾讯云配置 <?phpnamespace app\common\controller;use Qcloud\Cos\Client; use think\Controller; use think\Db;class Tencent extends Controller {/*** 上传文件* param $config* param $key* return array*/p…

Linux下快速判断当前终端使用的是bash or csh

在Linux下设置环境变量的时候&#xff0c;可能你也遇到过export: Command not found一类的错误。这是因为当前终端使用的不是bash&#xff0c;如何快速判断当前终端使用的是哪种类型的shell呢&#xff1f; echo $0判断shell类型 最简单的方法就是在终端输入echo $0&#xff0…

每日一题,零基础入门FPGA——工程师在线精讲来咯

传送门&#xff1a;zzfpga.com/StudentPlatform/Train/StudentArticleDetails?id149

M3U8工作原理以及key解密视频流详解

文章目录 前言一、M3U8是什么&#xff1f;二、HLS—M3U8的工作原理1.分段视频流2.生成播放列表3.客户端请求和解析4.片段下载和播放 三、.m3u8文件内部是什么样的&#xff1f;四、简单介绍下AES-128算法五、拿到KEY后如何去解密&#xff1f;1.手动解密.ts文件2.前人栽树&#x…

spring security 如何解决跨域的

一、什么是 CORS CORS(Cross-Origin Resource Sharing) 是由 W3C制定的一种跨域资源共享技术标准&#xff0c;其目就是为了解决前端的跨域请求。在JavaEE 开发中&#xff0c;最常见的前端跨域请求解决方案是早期的JSONP&#xff0c;但是JSONP 只支持 GET 请求&#xff0c;这是一…

深度学习从入门到精通——基于unet++算法实现细胞分割

模型定义 import torch from torch import nn__all__ [UNet, NestedUNet]class VGGBlock(nn.Module):def __init__(self, in_channels, middle_channels, out_channels):super().__init__()self.relu nn.ReLU(inplaceTrue)self.conv1 nn.Conv2d(in_channels, middle_channe…