新聞中心
概述
管道模式背后的主要思想是創(chuàng)建一組操作(管道)并通過它傳遞數(shù)據(jù)。跟責任鏈和裝飾器模式相比,Pipeline的主要優(yōu)勢在于它對結(jié)果的類型具有靈活性。

管道可以處理任何類型的輸入和輸出。
不可變管道
讓我們創(chuàng)建一個不可變的管道的例子。從管道接口開始:
public interface Pipe {
OUT process(IN input);
} 這是一個非常簡單的接口,只有一個方法,它接受輸入并產(chǎn)生輸出。接口是參數(shù)化的,我們可以在其中提供任何實現(xiàn)。
現(xiàn)在,讓我們創(chuàng)建一個管道類:
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;
}
} 因為我們需要一個類型安全級別,并且不允許使管道失效,所以在添加新管道時,將產(chǎn)生一個新的獨立管道。
簡單管道
我們可以稍微簡化上面的例子,并完全去掉Pipeline類:
public interface Pipe {
OUT process(IN input);
default Pipe add(Pipe pipe) {
return input -> pipe.process(process(input));
}
} 與以前使用管道的實現(xiàn)相比,此解決方案非常簡單和靈活。
改進
我們可以用現(xiàn)有的Function接口替代它:
public interface Function {
//...
R apply(T t);
//...
} 此外,F(xiàn)unction接口包含兩個有用的方法,其中一個是andThen:
default Function andThen(Function super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
} 我們可以使用它來代替以前的add方法。此外,F(xiàn)unction接口提供了一種在管道開始時添加函數(shù)的方法:
default Function compose(Function super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
} 通過使用Function,我們可以創(chuàng)建非常靈活和易于使用的管道:
@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轉(zhuǎn)換為一個Function。
結(jié)論
Pipeline模式適用于流式遞歸傳遞輸入和處理后的輸出,對于比較簡單的場景,使用Java函數(shù)接口是挺不錯的選項。
本文題目:Java流水線Pipeline設(shè)計模式
轉(zhuǎn)載來于:http://fisionsoft.com.cn/article/djisihc.html


咨詢
建站咨詢
