管道模式背后的主要思想是创建一组操作(管道)并通过它传递数据。跟责任链和装饰器模式相比,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,我们可以创建非常灵活和易于使用的管道:
@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函数接口是挺不错的选项。
新闻标题:Java流水线Pipeline设计模式
分享网址:http://www.shufengxianlan.com/qtweb/news49/427949.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联