博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用 functional interface 和 lambda 表达式来优化代码
阅读量:6236 次
发布时间:2019-06-22

本文共 3057 字,大约阅读时间需要 10 分钟。

========================================

原始代码
========================================
RoleService 类有删除角色和锁定角色两个函数.

@Servicepublic class RoleService {    @Autowired    RoleDao roleDao;    /**     * 删除指定的角色     * @param roleId     */    public void deleteRole(Long roleId) {        Optional
oldRole = roleDao.getRole(roleId); if (oldRole.isPresent()) { roleDao.delete(roleId); //1: 不同点 } else { throw new BusinessException(String.format("Cannot find the role record for id [%d]", roleId)); } } /** * 锁定指定的角色 * @param roleId */ public void lockRole(Long roleId) { Optional
oldRole = roleDao.getRole(roleId); if (oldRole.isPresent()) { roleDao.lock(roleId) //2: 不同点 } else { throw new BusinessException(String.format("Cannot find the role record for id [%d]", roleId)); } }}

问题分析:

可以看到上面这两个函数逻辑完全一致, 仅仅是最终调用的函数不同, 应该能优化, 一个思路是: 将框架部分封装为一个公用函数,  deleteRole() 和 lockRole() 函数调用该公共函数, 并将最终的 action 想法儿传进去.
如果是 C#, 因为有 delegate, 很容易做到; 如果是 Python的话, 那就更容易了, 直接将函数作为参数即可. 但 Java 不允许以函数作为参数, 处理起来要麻烦一些.

Java具体优化思路:虽然 Java 不允许以函数作为实参, 但是我们先将函数封装为类, 然后将类对象作为实参传进去.
具体实现方式有:
1. Java  8 之前,  利用 Runnable 或 Callable 接口作为公共函数的形参, 实参可以用真实的实现类, 也可以使用匿名类. 
2. Java 8 , 可以使用 java.util.function.Consumer 等接口作为公共函数的形参, 实参可以用真实的实现类, 也可以使用匿名类, 也可以使用 lambda 表达式.

显然最简洁的组合是: 使用 Java 8 中 java.util.function.Consumer 等接口作为公共函数的形参, 使用 lambda 做实参.

 

 

========================================

Java 8 内置的 Functional 接口
========================================
java.util.function 包中包含了一些常用的 Functional Interface, 而且都支持泛型. 所谓Functional Interface接口就是只有一个虚函数的接口. 主要的接口包括:
Consumer 接口, 该接口主要函数有一个形参, 没有返回值.
Function 接口, 该接口主要函数有一个形参, 可以有返回值.
Supplier 接口, 该接口主要函数没有形参, 但有返回值.
Predicate 接口, 该接口主要函数接受一个参数, 返回布尔型值.

正如上面所讲, Functional Interface接口就是只有一个虚函数的接口, 没什么特别之处, 我们也很容易自定义一个, 定义方式也和普通的Interface一样, 当然最好加上 @FunctionalInterface 注解, 这样如果不小心声明了多个虚函数, 编译时会报错.

Functional Interface 典型用法不是: 先声明一个接口, 然后在编写一个实现类.  而是: 用来声明函数的形参, 或者用来声明一个变量,  然后使用lambda表达式进行赋值. 

有了这一功能, Java 8 也具有一定的函数式编程特性. 

========================================

重构后的代码
========================================

@Serviceclass RoleService2 {    @Autowired    RoleDao roleDao;    /** 提取出的公共函数, 先判断指定角色是否存在, 若存在则继续执行某个动作, 若不存在直接抛出异常     * @param roleId     * @param action     */    private void checkAndDo(Long roleId, java.util.function.Consumer
action) { Optional
oldRole = roleDao.getRole(roleId); if (oldRole.isPresent()) { action.accept(roleId); } else { throw new BusinessException(String.format("Cannot find the role record for id [%d]", roleId)); } } private void internalLock(Long roleId) { roleDao.updateRoleState(roleId, RoleStateEnum.LOCKED); } public void lockRole(Long roleId) { checkAndDo(roleId, (rId) -> internalLock(rId)); } public void deleteRole(Long roleId) { checkAndDo(roleId, (rId) -> roleDao.updateRoleState(rId, RoleStateEnum.DELETED)); }}

 

转载地址:http://wvzia.baihongyu.com/

你可能感兴趣的文章
基于Spring Cloud 几行配置完成单点登录开发
查看>>
Android Kotlin仿微信头像裁剪图片
查看>>
Java 反射由浅入深 | 进阶必备
查看>>
React-native动态切换tab组件的方法
查看>>
2018阿里巴巴招聘笔试
查看>>
React Native常见问题(不定时更新)
查看>>
唯品会特卖升级,消费升维即将大爆发
查看>>
windows驱动创建文件符号链接
查看>>
算法-无重复字符的最长子串
查看>>
React-如何在jsx中自动补全标签
查看>>
前端加解密
查看>>
Android Studio查看Android源代码失败
查看>>
Event loop (JavaScript中的执行机制)
查看>>
谈谈对Spring IOC的理解
查看>>
axios源码分析——取消请求
查看>>
java基础(三):谈谈java异常的处理
查看>>
React 零基础入坑
查看>>
使用code-printer生成一份炫酷的简历
查看>>
SQL 中的一些小巧但常用的关键字
查看>>
从实际案例中探讨io中的延迟性能的作用
查看>>