• 【函数式编程实战】(八) 如何将你的代码重构


    前言
    📫 作者简介:小明java问道之路,专注于研究计算机底层,就职于金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的设计和架构📫 
    🏆 Java领域优质创作者、阿里云专家博主、华为云享专家🏆
    🔥 如果此文还不错的话,还请👍关注点赞收藏三连支持👍一下博主哦

    目录

    导读

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

    1、使用 Lambda表达式

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

    3、用StreamAPI重构数据处理

    4、代码灵活性

    4.1、行为参数化

    4.2、环绕执行

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

    1、策略模式

    2、模板方法模式

    3、观察者模式

    4、责任链模式

    5、工厂模式

    总结


    导读

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

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

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

    1、使用 Lambda表达式

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

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

    1. /**
    2. * 从匿名类到lambda
    3. * 1、变量名问题
    4. * 2、隐式调用问题
    5. */
    6. void runnnableTest() {
    7. int a = 2;
    8. Runnable r = new Runnable() {
    9. @Override
    10. public void run() {
    11. int a = 2;
    12. System.out.println(a);
    13. }
    14. };
    15. Runnable r1 = (Runnable) () -> {
    16. int a1 = 2; // 如果定义 变量名为 a 编译错误
    17. System.out.println(a1);
    18. };
    19. }

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

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

    1. public static void main(String[] args) {
    2. List orderInfos = Arrays.asList(new OrderInfo("123", BigDecimal.ONE),
    3. new OrderInfo("456", BigDecimal.TEN));
    4. // 计算全部订单的交易金额
    5. BigDecimal totalSubOrderAmt = orderInfos.stream()
    6. .filter(OrderInfo::filter)
    7. .map(OrderInfo::getOrderAmt)
    8. .reduce(BigDecimal.ZERO, BigDecimal::add);
    9. // filter的实现封装成方法引用
    10. BigDecimal totalSubOrderAmt1 = orderInfos.stream()
    11. .filter(orderInfo -> null != orderInfo && null != orderInfo.getOrderAmt() && orderInfo.getOrderAmt().compareTo(BigDecimal.ZERO) > 0)
    12. .map(OrderInfo::getOrderAmt)
    13. .reduce(BigDecimal.ZERO, BigDecimal::add);
    14. }
    15. /**
    16. * 过滤合法订单
    17. */
    18. public boolean filter() {
    19. if (null != this && null != this.getOrderAmt()
    20. && this.getOrderAmt().compareTo(BigDecimal.ZERO) > 0)
    21. return true;
    22. return false;
    23. }

     详细内容见:
    【函数式编程实战】(三)Lambda表达式原理与函数式接口精讲

    3、用StreamAPI重构数据处理

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

    1. public static void main(String[] args) {
    2. // 迭代器 + if
    3. Iterator it = orderInfos.iterator();
    4. while (it.hasNext()) {
    5. OrderInfo orderInfo = it.next();
    6. if (orderInfo.getOrderAmt().compareTo(BigDecimal.ZERO) > 0) {
    7. orderAmt.add(orderInfo.getOrderAmt());
    8. }
    9. }
    10. // Stream流 + Lambda表达式
    11. List collect = orderInfos.stream()
    12. .filter(orderInfo -> orderInfo.getOrderAmt().compareTo(BigDecimal.ZERO) > 0)
    13. .map(orderInfo -> orderInfo.getOrderAmt()).collect(Collectors.toList());
    14. }

    详细内容见:
    【函数式编程实战】(四)流-Stream API原理解析
    【函数式编程实战】(五) Stream实战大全
    【函数式编程实战】(六) Stream高并发实战

    4、代码灵活性

    4.1、行为参数化

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

    详细内容见:【函数式编程实战】(二)代码的行为参数化传递

    4.2、环绕执行

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

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

    1、策略模式

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

    1. public static void main(String[] args) {
    2. List orderInfos = Arrays.asList(new OrderInfo("123", BigDecimal.ONE),
    3. new OrderInfo("456", BigDecimal.TEN));
    4. // 这么写的意图,避免侧罗模式僵化的代码
    5. // 实际上 Validator v1 = new Validator(new StrategyImpl()); 我们用的更多
    6. Validator v1 = new Validator(o -> {
    7. System.out.println("订单号:" + o + " lambda下单成功");
    8. return true;
    9. });
    10. orderInfos.stream().forEach(orderInfo ->
    11. System.out.println(v1.submitOrder(orderInfo.getOrderId())));
    12. }
    13. public interface Strategy {
    14. /**
    15. * 函数式接口
    16. */
    17. boolean submitOrder(String orderType);
    18. }
    19. public class Validator { // 相当于一个中转站
    20. private Strategy strategy;
    21. public Validator(Strategy strategy) {
    22. this.strategy = strategy;
    23. }
    24. boolean submitOrder(String orderType) {
    25. return strategy.submitOrder(orderType);
    26. }
    27. }

    2、模板方法模式

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

    3、观察者模式

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

    4、责任链模式

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

    5、工厂模式

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

    详细内容见:【函数式编程实战】(二)代码的行为参数化传递

    总结

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

  • 相关阅读:
    前置放大器和功率放大器有什么区别?
    【C++】继承 ⑦ ( 继承中的对象模型分析 | 继承中的构造函数和析构函数 )
    Python从入门到实践:字节串与字符串
    卡方检验-python代码
    设计模式之组合模式
    STM32 GD32 标准库移植SFUD
    【Android】系统启动流程(zygote 进程启动流程)
    【无标题】
    HTTP/1.1协议中的响应报文
    java计算机毕业设计网络招聘系统源码+系统+数据库+lw文档+mybatis+运行部署
  • 原文地址:https://blog.csdn.net/FMC_WBL/article/details/125862813