jdk8函数式接口实现责任链

葵花点穴手☝   |     |   设计模式   |   6分钟   |   218浏览  

在开始之前,先了解Function这个接口。
Function接口有1个抽象方法apply(),2个默认方法compose()``andThen(),1个静态方法identity()
其中,apply()抽象方法的作用是将传入的类型 T 的参数根据具体实现,转成另一个R类型结果,前者称为前置条件before,后者称为后置条件after。
compose()默认方法的作用是返回一个组合函数,将当前函数的结果作为参数传递给后置条件before
andThen()默认方法的作用是返回一个组合函数,将当前函数的结果作为参数传递给后置条件after
用时间轴表示Function过程的表示为:

function(identity) —> compose(before) —> apply() —> andThen(after)

@FunctionalInterface
public interface Function<T, R> {
    //类型转换 T -> R
    R apply(T t);
    //前置操作
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
    //后置操作
    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
    //创建一个Function对象,表示
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

以上了解了Function接口的作用,类型转换,提供前置操作和后置操作。
顺便介绍下另一个函数式接口:Consumer。该接口允许传入参数进行消费,无返回值。其中包含accept()抽象方法,默认方法andThen()
accept()方法的作用是接收一个参数,并在实现类中进行自定义消费该数据。
andThen()方法的作用与上边有点不同,是一个组合函数,并执行于accept方法后,当前消费者函数运行结果作为参数运行。
现在开始 jdk 责任链:

public String handlePrefix(String s){
    return "《 " + s.toString();
}
public String handleSuffix(String s){
    return s.toString() + " 》";
}

@Test
void testChainOfResponsibility() {
    /** 责任链1: 完善书名信息 */
    //创建Function对象,约束类型入参类型、返回类型
    Function<String, String> initFunc = Function.identity();
    //操作1:前置操作
    Function<String, String> c1 = this::handlePrefix;
    //操作2:后置操作
    Function<String, String> c2 = this::handleSuffix;
    String book = initFunc.compose(c1).andThen(c2).apply("云端有个小卖部");
    //输出:《 云端有个小卖部 》
    System.out.println(book);

    /** 责任链2: 下单成功减少库存,失败则抛异常*/
    Consumer consumer = param -> System.out.printf("获取订单结果:%s\n", param);
    //订单校验
    Consumer<Object> checkParam = param-> {
        if (!(param instanceof String)) throw new RuntimeException("校验不通过");
    };
    //减少库存操作
    Consumer<String> reduceInventory = (String a)-> System.out.printf("%s\n", StringUtils.containsAny(a,"success", "yes", "true") ? "减少库存..." : "");
    //准备订单结果
    Object result = "the order do successfully!";
    // result = -1;
    //按照顺序处理
    consumer.andThen(checkParam).andThen(reduceInventory).accept(result);
}
如果你觉得文章对你有帮助,那就请作者喝杯咖啡吧☕
微信
支付宝

当前文章已关闭评论