【Java】Java8 Function 和 Consumer 接口的使用场景

前言

在 《精通Java8》一书中有讲过 Java8的函数式接口可以简化设计模式的实施,这里记录一下Function 和 Consumer 的使用场景。

1. Function 示例

  • 作为构造方法传入 Funtion 接口实现
// 用 Funtion 声明 iphone 全场9折
Product iphone = new Product("iphone", price -> price.multiply(new BigDecimal("0.9")));
  • 等出现价格后,延迟计算
// 当前商品价格8000, 使用 Funtion 计算
BigDecimal finalPrice = iphone.calFinalPrice(new BigDecimal("8000"));
  • 结果
// 折后7200
assertThat(finalPrice, comparesEqualTo(new BigDecimal("7200")));

2. Function 介绍

JDK介绍,第一个泛型表示输入类型,第二个类型表示输出类型。本文例子中:

  • 输入是原价
  • 输出是经过价格策略处理的现价

在这里插入图片描述
JDK介绍,apply方法接受输入,产生输出。本文例子中:

  • 方法实现就是价格策略
  • 构造方法把策略传入,同样的策略可以多次使用
    在这里插入图片描述
  • 所有代码
public class Product {
    
    
    private final String  name;

    /**
     * 价格处理策略
     */
    private final Function<BigDecimal, BigDecimal> function;

    public Product(String name, Function<BigDecimal, BigDecimal> function) {
    
    
        this.name = name;
        this.function = function;
    }

    public BigDecimal calFinalPrice(BigDecimal price) {
    
    
        return function.apply(price);
    }
}

3. Consumer 示例

在上文的基础上,做一个方法重载

    /**
     * 计算价格前,原价可以被不同系统记录(但是不能修改)
     */
    public BigDecimal calFinalPrice(BigDecimal price, Consumer<BigDecimal> consumer) {
    
    
    	// BigDecimal 每次运算都会参数新值,consumer不会影响传入的price
        consumer.accept(price);
        return function.apply(price);
    }
  • 测试
    @Test
    public void test_discount_coupon_save_snapshot() {
    
    
        // iphone 全场九折, 并叠加10元优惠
        Product iphone = new Product("iphone", price -> price.multiply(new BigDecimal("0.9")).subtract(BigDecimal.TEN));
        // 原价800, 计算折后, 并保存快照
        BigDecimal finalPrice = iphone.calFinalPrice(new BigDecimal("8000"), price -> saveSnapshot(price));
        // 折后7190
        assertThat(finalPrice, comparesEqualTo(new BigDecimal("7190")));
    }

    private void saveSnapshot(BigDecimal price) {
    
    
        // 原价做快照存储,方便溯源
    }

4. Consumer 介绍

JDK介绍,一种避免副作用的函数式接口。
在这里插入图片描述

5. Function 和 Consumer 接口的使用场景

  • Function 用于处理输入并产生输出
  • Consumer 用于处理输入,但是不产生任何副作用
  • 实际情况可以组合使用
  • Function 和 Consumer 如果语义不能满足业务,可以抄Jdk的实现改一下名
    • 本例中 Function 可以换成一个自定义的 PriceStrategy 接口
    • 本例中 Consumer 可以换成一个自定义的 PriceShapshot 接口

后记

函数式是一种编程风格,希望能在业务逻辑中用起来。有更多收获的时候再来总结下。

猜你喜欢

转载自blog.csdn.net/chenghan_yang/article/details/134359239