当前位置: 首页 > news >正文

Java 函数式编程

声明式编程(Declarative Programming)是一种编程风格,我们说明想要完成什么(what),而不是指明怎么做(how)。 --《On Java》
与之相对的是命令式编程(Imperative Programming),后者关注具体的步骤和操作顺序。声明式编程通常更简洁、更易于理解和维护。

Java 8 引入了新特性:
● 函数式编程:包括Lambda 表达式、函数式接口、方法引用等
● 接口默认方法和静态方法:增强接口的功能,支持函数式编程。
Stream API、Optional 提高了代码的简洁性和可读性,开发中用的比较多。
但是 Javaer 常常忽略了函数式编程带来的影响或者它的作用,也就是代码风格的改变。这里抛砖引玉,不讲原理,直讲开发的中的改变。

Java 8 提供了一些常用的内置函数式接口:
● Function<T, R>:接受一个参数,返回一个结果。
● Predicate:接受一个参数,返回一个布尔值。
● Supplier:不接受参数,返回一个结果。
● Consumer:接受一个参数,不返回结果。

一、命令式编程

在web编程里,良好的编程习惯式不能把底层的实体类(DO)直接返回给请求接口,常常涉及到一些类型转换。
JDK 8 之前类型转换一般有几种做法:
● 类型直接写在业务代码里
● 把类型转换代码放到 private 方法里
● 把类型转换代码放到一个类型转换类中
这样做的缺点:
● 可读性差:代码冗长,不适合给代码审核人员/其他开发快速了解业务逻辑

 public void saveTask(WarningTaskAddCriteria req) {// 存储预警任务基本信息SysWarningTaskEntity taskEntity = new SysWarningTaskEntity().setWarningEventId(req.getTaskEventInfo().getWarningEventId()).setWarningEventName(req.getTaskEventInfo().getWarningEventName()).setTaskStatus(TaskStatus.SAVED.getCode()).setAddAttributes();BeanUtils.copyProperties(req,taskEntity);final int taskInsertAffectedRows = taskMapper.insert(taskEntity);// 省略其他操作
}

二、声明式(函数式)编程

函数式接口可以作为参数、返回结果,也可以组合使用。
举个简单的例子 类型转化类 。个人习惯是封装一层,团队统一代码风格。

类型转化类:

import java.util.function.Function;public class TypeConverter {public static <T, R> R convert(T t, Function<T, R> function) {if (t == null || function == null) {throw new IllegalArgumentException("Arguments cannot be null");}return function.apply(t);}
}

改造后的代码:

public void saveTask(WarningTaskAddCriteria req) {// 存储预警任务基本信息SysWarningTaskEntity taskEntity = TypeConverter.convert(req.getTaskEventInfo(), info -> {SysWarningTaskEntity entity = new SysWarningTaskEntity().setWarningEventId(info.getWarningEventId()).setWarningEventName(info.getWarningEventName()).setTaskStatus(TaskStatus.SAVED.getCode()).setAddAttributes();SpringBeanUtils.copyProperties(req, entity);return entity;});final int taskInsertAffectedRows = taskMapper.insert(taskEntity);// 省略其他操作
}// 更极端一些
public void saveTask(WarningTaskAddCriteria req) {// 存储预警任务基本信息final int taskInsertAffectedRows = taskMapper.insert(TypeConverter.convert(req.getTaskEventInfo(), info -> {SysWarningTaskEntity entity = new SysWarningTaskEntity().setWarningEventId(info.getWarningEventId()).setWarningEventName(info.getWarningEventName()).setTaskStatus(TaskStatus.SAVED.getCode()).setAddAttributes();SpringBeanUtils.copyProperties(req, entity);return entity;}));// 省略其他操作
}

改造后的优点:
● 可读性更强:虽然代码看起来只是放到不同的地方,但是 其他开发人员看到 TypeConverter.convert就会明白这个是要做什么(what) 而不是 怎么做(how)。
● 更易于维护:在实际工作中见到过太多情况,前面声明一个类,然后后面的代码又对这个对象进行更改。一般来讲 final 的对象更加安全可靠。

三、风格改变会有什么影响吗?

3.1 事务是否会有影响?

答案是不会有影响。

@Transactional
public void saveTask(WarningTaskAddCriteria req) {SysWarningTaskEntity taskEntity = new SysWarningTaskEntity().setWarningEventId(req.getTaskEventInfo().getWarningEventId()).setWarningEventName(req.getTaskEventInfo().getWarningEventName()).setTaskStatus(TaskStatus.SAVED.getCode()).setAddAttributes();BeanUtils.copyProperties(req, taskEntity);// 这里仅仅是为了演示,没必要这么写Consumer<SysWarningTaskEntity> save = entity -> {taskMapper.insert(entity);};save.accept(taskEntity);// 强制抛出异常测试回滚throw new RuntimeException("Test rollback");
}

http://www.mrgr.cn/news/48437.html

相关文章:

  • Python编程学习第一篇——Python零基础快速入门(六)(7)模块
  • 深兰科技|“武汉市AI心理热线医工交叉研发合作基地”正式揭牌
  • 如何在算家云搭建SVHN-Recognition(门牌号识别)
  • 【数学分析笔记】第5章第1节 微分中值定理(1)
  • 分布式储能监控在实际项目中的应用
  • 如何在Vue项目中封装axios
  • GC9512为什么能替代DRV8837的原因分析
  • 半导体激光其中 量子阱和包层之间的 barrier层是什么作用
  • 根据请求错误的状态码判断代理配置问题
  • centos系统安装后配置GitLab
  • 智能网联汽车安全隐患,如何化解?
  • 【编译原理】绪论(基础知识+习题)
  • 利用session机制造测试账号,无需前端也可以测试后端接口
  • JavaScript Set 必备指南:深入理解 Set 的特性和方法
  • -bash gcc command not found解决方案(CentOS操作系统)
  • 探索 Python 的函数与模块
  • 从丢失到找回只需一步:2024年TOP4超级硬盘恢复软件推荐
  • 【论文速读】| AutoSafeCoder:通过静态分析和模糊测试保障LLM代码生成安全的多智能体框架
  • GWAS揭示酸性磷酸酶ACP2在缺磷条件下通过丝氨酸代谢调节水稻光合作用
  • 基于STM32的太阳跟踪系统设计