文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java流水线Pipeline设计模式

2024-11-30 14:17

关注

管道可以处理任何类型的输入和输出。

不可变管道

让我们创建一个不可变的管道的例子。从管道接口开始:

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 after) {
    Objects.requireNonNull(after);
    return (T t) -> after.apply(apply(t));
}

我们可以使用它来代替以前的add方法。此外,Function接口提供了一种在管道开始时添加函数的方法:

default  Function compose(Function before) {
    Objects.requireNonNull(before);
    return (V v) -> apply(before.apply(v));
}

通过使用Function,我们可以创建非常灵活和易于使用的管道:

@Test
void 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扩展管道:

@Test
void 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函数接口是挺不错的选项。

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯