【精通函数式编程】(八) 如何将你的代码重构

简介: 我们学习了java8的特性,那么未来将如何写优雅的代码呢?怎么改善代码的可读性和灵活性呢?本文实际上是前面7篇的一个总结与实战应用,本讲包含使用 Lambda表达式、方法引用、StreamAPI、行为参数化、重构设计模式的应用,相信读者对写法上的重构有了方法论

前言📫 作者简介:小明 java 问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫

🏆 Java 领域优质创作者、阿里云专家博主、华为云专家🏆

🔥 如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主哦

导读

我们学习了java8的特性,那么未来将如何写优雅的代码呢?怎么改善代码的可读性和灵活性呢?本文教你重构代码使用语言高级特性。

一、改善代码可读性、灵活性

增加代码可读性,什么是可读性,代码的可读性就是如何让人 一眼懂,别人理解更加简单,其二是让其他人怎么接手你的代码,因为你的代码很可能也经常会给别人维护

1、使用 Lambda表达式

代码会更加简洁,减少冗长重复的代码,通过Stream流、方法引用、方法参数行为化等等方法,代码会更加直观,所以使用 Lambda表达式将匿名类转换成更简洁的代码,可以使用Intellj自动重构

这里面要注意将匿名类转换为 Lambda表达式,导致了隐晦调用,因为Runnable、Task、都是目标类型,建议在构造时,使用显式的类型转换!

/**
     * 从匿名类到lambda
     * 1、变量名问题
     * 2、隐式调用问题
     */
    void runnnableTest() {
        int a = 2;
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int a = 2;
                System.out.println(a);
            }
        };
        Runnable r1 = (Runnable) () -> {
            int a1 = 2; // 如果定义 变量名为 a 编译错误
            System.out.println(a1);
        };
    }

2、用方法引用重构援用Lambda表达式

Lambda表达式配合方法引用,将lambda行为参数化,这样代码是非常直观表达代码的意图的,建议重构时将 复杂逻辑,例如下面代码中的filter的实现封装成方法引用

public static void main(String[] args) {
    List<OrderInfo> orderInfos = Arrays.asList(new OrderInfo("123", BigDecimal.ONE),
            new OrderInfo("456", BigDecimal.TEN));
    // 计算全部订单的交易金额
    BigDecimal totalSubOrderAmt = orderInfos.stream()
            .filter(OrderInfo::filter)
            .map(OrderInfo::getOrderAmt)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
    // filter的实现封装成方法引用
    BigDecimal totalSubOrderAmt1 = orderInfos.stream()
            .filter(orderInfo -> null != orderInfo && null != orderInfo.getOrderAmt() && orderInfo.getOrderAmt().compareTo(BigDecimal.ZERO) > 0)
            .map(OrderInfo::getOrderAmt)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
 * 过滤合法订单
 */
public boolean filter() {
    if (null != this && null != this.getOrderAmt()
            && this.getOrderAmt().compareTo(BigDecimal.ZERO) > 0)
        return true;
    return false;
}

3、用StreamAPI重构数据处理

建议所有的使用迭代器的处理,都转换为 Stream流的形式,Stream API可以更清晰的表达数据处理管道的意图,现在处理器的超线程、多核处理器可以对Stream优化

public static void main(String[] args) {
        // 迭代器 + if
        Iterator<OrderInfo> it = orderInfos.iterator();
        while (it.hasNext()) {
            OrderInfo orderInfo = it.next();
            if (orderInfo.getOrderAmt().compareTo(BigDecimal.ZERO) > 0) {
                orderAmt.add(orderInfo.getOrderAmt());
            }
        }
        // Stream流 + Lambda表达式
        List<BigDecimal> collect = orderInfos.stream()
                .filter(orderInfo -> orderInfo.getOrderAmt().compareTo(BigDecimal.ZERO) > 0)
                .map(orderInfo -> orderInfo.getOrderAmt()).collect(Collectors.toList());
    }

4、代码灵活性

4.1、行为参数化

这个地方有 使用Lambda表达式进行行为参数化,将不同的行为作为参数传递给函数执行,不止这些还有Predicate、Comparator等对象提供的函数式接口

4.2、环绕执行

一些业务上的代码会有甚多同性,例如准备数据结构和清理回收对象等等等,完全可以减少重复代码,这块就是复用代码,本质上还是使用Stream和 Lambda表达式以及函数式编程,但是会将代码扩展性和复用性应用到极致

二、函数式编程重构设计模式实战

1、策略模式

策略模式可以理解为一种通过算法解决一类问题的通用方案,策略模式包括该算法的接口,一个或多个接口的实现逻辑,以及策略对象,下面我们用lambda表达式实现

网络异常,图片无法展示
|

public static void main(String[] args) {
    List<OrderInfo> orderInfos = Arrays.asList(new OrderInfo("123", BigDecimal.ONE),
            new OrderInfo("456", BigDecimal.TEN));
    // 这么写的意图,避免侧罗模式僵化的代码
    // 实际上 Validator v1 = new Validator(new StrategyImpl()); 我们用的更多
    Validator v1 = new Validator(o -> {    
        System.out.println("订单号:" + o + " lambda下单成功");
        return true;
    });
    orderInfos.stream().forEach(orderInfo -> 
    System.out.println(v1.submitOrder(orderInfo.getOrderId())));
}
public interface Strategy {
    /**
     * 函数式接口
     */
    boolean submitOrder(String orderType);
}
public class Validator { // 相当于一个中转站
    private Strategy strategy;
    public Validator(Strategy strategy) {
        this.strategy = strategy;
    }
    boolean submitOrder(String orderType) {
        return strategy.submitOrder(orderType);
    }
}

2、模板方法模式

模板方法模式和上面的策略模式是行为模式,模板方法模式定义一个操作中的算法的接口,而将步骤延迟到子类实现类中。我们可以理解为字lambda表达式中,创建一个匿名内部类实现,然后重构成模板方法模式

网络异常,图片无法展示
|

3、观察者模式

观察者模式也是行为模式的一种,使用lambda表达式的时候,lambda也要实现,但是lambda本质是想消除固定的代码,当我们业务大的时候,实际上不适合在lambda里面实现

网络异常,图片无法展示
|

4、责任链模式

责任链模式也是行为模式的一种,本质上写法和上面策略模式、模板方法、观察者相同,都是定义函数式接口,用lambda实现函数的逻辑。在上面策略模式有类似实现代码

网络异常,图片无法展示
|

5、工厂模式

在Java8以及高版本中,Collection在Java8和9中的增强,我们之前介绍了集中静态工厂,以及创建出来的副本的一些特性,本章不再赘述

总结

我们学习了java8的特性,那么未来将如何写优雅的代码呢?怎么改善代码的可读性和灵活性呢?本文实际上是前面7篇的一个总结与实战应用,本讲包含使用 Lambda表达式、方法引用、StreamAPI、行为参数化、重构设计模式的应用,相信读者对写法上的重构有了一定的思想。

相关文章
|
11月前
|
NoSQL Cloud Native Linux
通过 RIOT 将 AWS ElastiCache 迁移到阿里云 Tair
通过 RIOT 将 AWS ElastiCache 迁移到阿里云 Tair
|
Java 开发工具 流计算
flink最新master代码编译出现Java Runtime Environment 问题
在尝试编译Flink源码时遇到Java运行时环境致命错误:EXCEPTION_ACCESS_VIOLATION。问题出现在JVM.dll+0x88212。使用的是Java 11.0.28和Java HotSpot(TM) 64-Bit Server VM。系统为Windows客户端,没有生成核心dump文件。错误日志保存在hs_err_pid39364.log和replay_pid39364.log。要解决这个问题,建议检查JDK版本兼容性,更新JDK或参照错误报告文件提交Bug至http://bugreport.java.com/bugreport/crash.jsp。
Echarts手机端无刷新实现图表自适应横屏和竖屏的解决方案
Echarts手机端无刷新实现图表自适应横屏和竖屏的解决方案
616 0
|
2月前
|
消息中间件 缓存 负载均衡
构建高效可扩展的后端架构:从设计到实现
本文探讨了如何构建高效、可扩展的后端架构,涵盖需求分析、系统设计、实现与优化全过程。内容包括微服务、数据库设计、缓存与消息队列等关键技术,并涉及API设计、自动化测试、CI/CD及性能优化策略,助力打造高性能、易维护的后端系统。
|
6月前
|
机器学习/深度学习 编解码 自然语言处理
SigLIP 2:多语言语义理解、定位和密集特征的视觉语言编码器
SigLIP 2 是一种改进的多语言视觉-语言编码器系列,通过字幕预训练、自监督学习和在线数据管理优化性能。它在零样本分类、图像-文本检索及视觉表示提取中表现卓越,支持多分辨率处理并保持图像纵横比。模型提供 ViT-B 至 g 四种规格,采用 WebLI 数据集训练,结合 Sigmoid 损失与自蒸馏等技术提升效果。实验表明,SigLIP 2 在密集预测、定位任务及多模态应用中显著优于前代和其他基线模型。
497 9
SigLIP 2:多语言语义理解、定位和密集特征的视觉语言编码器
|
11月前
|
存储 前端开发 UED
uni-app:基础组件 (下)
本文介绍了多种前端组件及其用法,包括:label 组件用于表单元素的标签;picker 组件用于实现日期、时间及普通列表的选择器;textarea 组件用于输入多行文本,并可通过 v-model 双向绑定数据;process 组件用于显示进度条;swiper 组件用于轮播图展示;match-media 组件根据屏幕尺寸展示内容;audio 组件用于播放音频;switch 组件用于开关选择;scroll-view 组件实现滚动视图功能;以及 storage 的使用方法,如设置、获取和移除本地存储等。
257 0
|
11月前
|
JavaScript 前端开发 测试技术
精通Selenium:从基础到高级的网页自动化测试策略
【10月更文挑战第6天】随着Web应用变得越来越复杂,手动进行功能和兼容性测试变得既耗时又容易出错。自动化测试因此成为了现代软件开发不可或缺的一部分。Selenium是一个强大的工具集,它支持多种编程语言(包括Python),允许开发者编写脚本来模拟用户与Web页面的交互。本文将带领读者从Selenium的基础知识出发,逐步深入到高级的应用场景,通过丰富的代码示例来展示如何高效地进行网页自动化测试。
1758 5
|
9月前
|
监控 供应链 数据可视化
物联网工厂可视化监控平台:为智能制造打造的可视化大屏
物联网(IoT)已成为数字化转型的核心力量,通过连接设备和传感器实现数据实时收集与分析。本文介绍物联网设备可视化监控平台,解决行业痛点如多系统统筹难、库存管理不精准、巡检工作繁杂等问题。应用场景包括数据分析与决策支持、园区监控、车间概览及设备管理,利用数字孪生技术实现全方位监控和智能决策,优化资源配置,提高运营效率。获取路径:素材广场【尊享版】。
|
10月前
|
机器学习/深度学习 算法 API
量子计算编程语言:面向未来的开发工具
量子计算编程语言是面向未来的开发工具,基于量子力学原理,能够突破经典计算的瓶颈。本文介绍了量子计算编程语言的发展历程、主要特点、应用前景及学习方法,涵盖了QCL、Q#、Quipper等代表性语言,以及Qiskit、ProjectQ等主流工具,为开发者提供了全面的学习路径。