管道模式背后的主要思想是创建一组操作(管道)并通过它传递数据。跟责任链和装饰器模式相比,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函数接口是挺不错的选项。
关键词:
								世界今日讯!住一晚8888元,“猪景房”为啥这么贵?
								山西加快焦化行业调整升级 年内将全面关停4.3米焦炉 速递
								【天天聚看点】人民银行开展1960亿元逆回购操作
								白玉兰最佳女主:跟“前半生”和解
								深圳福田皇岗村旧改项目确定申报主体为皇岗实业
								星露谷物语春季鱼王在哪里钓 星露谷物语秋季鱼王在哪里钓|全球速读
								2023“一带一路”青年创意与遗产论坛暨长沙媒体艺术节明日开幕 速看
								端午粽香飘飘 市场购销两旺 全市线下消费支付金额约180亿元 要闻
								无穷小量的替换(无穷小量)
								天天观热点:嫡孙是什么意思啊第几代 嫡孙是什么意思
								热门:就是大龙团的问题! Crisp:第三局失利是因为大龙前做的不够好
								每日信息:海胆怎么处理不苦_海胆怎么处理
								天天观热点:分数怎么打成上下形的_分数怎么打
								金童奖官方:2005年金童奖得主梅西生日快乐_全球速看
								球王生日!巴萨卡点给梅西送祝福,舆论一边倒,怒斥管理层-当前关注
								宁夏银川烧烤店燃气爆炸事故4名犯罪嫌疑人被刑拘
								五年最火端午收官 热门城市机票、酒店预订量均超2019年 环球热点评
								一公司标志“太丑”引吐槽,回应:是董事长本人
								全球通讯!亚马逊计划在未来7年内在印度再投资150亿美元。
								天天热消息:如何让女生感动?用建造冰棒棒城堡的技巧,送出最完美的礼物!
								RNG粉丝上台攻击EDG,称他们是软脚虾,事后公开解释原因
								环球信息:莫斯科所有最重要设施已加强安保 瓦格纳总部附近没有出现执法人员
								信息课电脑怎么解除控制-信息课老师把屏幕控制了 怎么解除控制_全球新资讯
								早期类似《三国志2》游戏 全球球精选
								焦点快报!睢宁人,端午返程拥堵路段是…
								齐威王论国宝翻译及阅读答案(齐威王论国宝)
								4-8,大冷门!鱼腩险创奇迹,4次攻破日本球门,中国男足却做不到
								经济日报:稳步释放房地产市场需求 世界资讯
								即时焦点:薛佳凝和胡歌再次传出绯闻_薛佳凝被曝新恋情
								环球速看:好问则裕自用则小的意思_好问则裕自用则小的解释