文章目录
- 前言
- 1. Function 示例
- 2. Function 介绍
- 3. Consumer 示例
- 4. Consumer 介绍
- 5. 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 接口
后记
函数式是一种编程风格,希望能在业务逻辑中用起来。有更多收获的时候再来总结下。