Java流水线Pipeline设计模式
Pipeline模式适用于流式递归传递输入和处理后的输出,对于比较简单的场景,使用Java函数接口是挺不错的选项。
概述
管道模式背后的主要思想是创建一组操作(管道)并通过它传递数据。跟责任链和装饰器模式相比,Pipeline的主要优势在于它对结果的类型具有灵活性。
管道可以处理任何类型的输入和输出。
(资料图片)
不可变管道
让我们创建一个不可变的管道的例子。从管道接口开始:
public interface Pipe { OUT process(IN input);} 这是一个非常简单的接口,只有一个方法,它接受输入并产生输出。接口是参数化的,我们可以在其中提供任何实现。
现在,让我们创建一个管道类:
public class Pipeline { private Collection> pipes; private Pipeline(Pipe pipe) { pipes = Collections.singletonList(pipe); } private Pipeline(Collection> pipes) { this.pipes = new ArrayList<>(pipes); } public static Pipeline of(Pipe pipe) { return new Pipeline<>(pipe); } public Pipeline withNextPipe(Pipe pipe) { final ArrayList> newPipes = new ArrayList<>(pipes); newPipes.add(pipe); return new Pipeline<>(newPipes); } public OUT process(IN input) { Object output = input; for (final Pipe pipe : pipes) { output = pipe.process(output); } return (OUT) output; }} 因为我们需要一个类型安全级别,并且不允许使管道失效,所以在添加新管道时,将产生一个新的独立管道。
简单管道
我们可以稍微简化上面的例子,并完全去掉Pipeline类:
public interface Pipe { OUT process(IN input); default Pipe add(Pipe pipe) { return input -> pipe.process(process(input)); }} 与以前使用管道的实现相比,此解决方案非常简单和灵活。
改进
我们可以用现有的Function接口替代它:
public interface Function { //... R apply(T t); //...} 此外,Function接口包含两个有用的方法,其中一个是andThen:
default Function andThen(Function super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t));} 我们可以使用它来代替以前的add方法。此外,Function接口提供了一种在管道开始时添加函数的方法:
default Function compose(Function super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v));} 通过使用Function,我们可以创建非常灵活和易于使用的管道:
@Testvoid whenCombiningThreeFunctions_andInitializingPipeline_thenResultIsCorrect() { Function square = s -> s * s; Function half = s -> s / 2; Function toString = Object::toString; Function pipeline = square.andThen(half) .andThen(toString); String result = pipeline.apply(5); String expected = "12"; assertEquals(expected, result);} 我们可以使用BiFunctions扩展管道:
@Testvoid whenCombiningFunctionAndBiFunctions_andInitializingPipeline_thenResultIsCorrect() { BiFunction add = Integer::sum; BiFunction mul = (a, b) -> a * b; Function toString = Object::toString; BiFunction pipeline = add.andThen(a -> mul.apply(a, 2)) .andThen(toString); String result = pipeline.apply(1, 2); String expected = "6"; assertEquals(expected, result);} 因为andThen方法采用Function,所以我们必须将mul BiFunction转换为一个Function。
结论
Pipeline模式适用于流式递归传递输入和处理后的输出,对于比较简单的场景,使用Java函数接口是挺不错的选项。
标签:
- 01 当前消息!鲤城困难家庭学生 可申领临时救助金
- 02 Faraday Future宣布获得1亿美元无担保可转换债融资
- 03 银轮股份(002126):股价成功突破年线压力位-后市看多(涨)(05-10)_世界信息
- 04 刘建荣率队走访新余市政府推进宝武战略合作项目落地
- 05 部分路段违停投诉多 “鹰眼铁骑”专项整治-当前要闻
- 06 【世界报资讯】不定冠词的用法_基本用法如下
- 07 2023年黄河口(东营)汽车场地越野赛即将鸣枪开赛 全球时快讯
- 08 世界今头条!北京地区普惠小微贷款平均利率创新低
- 09 保险报销需要哪些资料?报销多久到账?
- 010 世界热资讯!财政部公布重磅数据!养老金涨幅定了?3100元以下,可以多涨吗?
