前言
Pipeline设计模式就不说了,这里写一段非常简单的实现,如下。
public interface Step<I, O> {
static <I, O> Step<I, O> of(Step<I, O> step) {
return step;
}
default <R> Step<I, R> addStep(Step<O, R> source) {
return value -> source.execute(execute(value));
}
O execute(I value);
}
没错这就完了,下面看如何运行。
public class Main {
private static String test(Integer a) {
System.out.println("执行test");
return "1";
}
private static Long test2(String a) {
System.out.println("执行test2");
return 1l;
}
public static void main(String[] args) {
Step<Integer, Long> step = Step.of(Main::test)
.addStep(Main::test2);
step.execute(1);
}
这是一个从Integer类型的输入到Long结果的输出的一段代码。
这里面有几点还是比较绕的,比如下面这段。
default <R> Step<I, R> addStep(Step<O, R> source) {
return value -> source.execute(execute(value));
}
这是在流水线上添加步骤的方法,我们已经在Step类上定义了泛型I和O,I表示输入的类型,O表示输出的类型,第一个实现类已经可以确定输入输出的类型,比如上面我们用方法引用,告诉第一个输入的类型是Integer,输出的类型是String,那么其后在添加"步骤"的时候,输入的类型只能是上面步骤的输出类型,而定义一个R泛型,表示新添加的"步骤"的输出类型是R。
在看下面这段。
return value -> source.execute(execute(value));
这段其实和下面这段是相等的,只不过用了lambda写法,更简洁。
return new Step<I, R>() {
@Override
public R execute(I value) {
return source.execute(Step.this.execute(value));
}
};