我正在尝试为链接任务创建一个API。
首先,我设计了一个定义任务的非常简单的界面:
public interface Task<U, V> {
U execute(V input);
}
其中V
是输入类型,U
是任务的输出类型。
我要创建的是Chain
类,它会链接Tasks
列表。
例如,我想执行:Task1<TypeA, TypeB> -> Task2<TypeB, TypeC> -> Task3<TypeC, TypeD>
这个Chain
类因此是Task<TypeA, TypeD>
。
所以我写了这段不编译的代码:
public class Chain<U, V> implements Task<U, V> {
List<Task<?, ?>> taskList;
public Chain() {
taskList = new LinkedList<Task<?, ?>>();
}
@Override
public U execute(V input) {
V currentInput = input;
U output = null;
for (Task<?, ?> task : taskList) {
output = task.execute(currentInput);
// Compile error because currentInput is of type V
// and output of type U
currentInput = output; // Compile error as well
}
return output;
}
// Other methods to add and remove tasks in the list
}
我明白为什么它无法编译,但我不知道如何实现有效的方法并解决我的问题。
有没有人遇到过这种问题?
亲切的问候,
本
答案 0 :(得分:5)
您的Task
课程与Guava课程Function
几乎相同。您可以使用它而不是定义自己的那个。
使用Function
的一个好处是你可以使用Functions
类中的辅助方法,其中一个方法是compose()
:
Function<String,MyObject1> stringToMyObject1 = ...;
Function<MyObject1, AnotherObject> myObject1ToAnotherObject = ...;
Function<String,AnotherObject> stringtoAnotherObject = Functions.compose(myObject1ToAnotherObject, stringToMyObject1);
通过重复调用compose()
可以实现更深层次的链接。
即使您出于某种原因不想使用Guava,也可以从这种方法中获取灵感:使用已知类型参数链接任意两个函数/任务会创建一个具有易于计算的类型参数的新函数/任务。
答案 1 :(得分:4)
不是试图在(非通用)列表中维护任务,而是可以尝试“装饰器”方法(缺少更好的单词),即定义一个将另一个任务作为参数的类,执行一些任务然后通过其结果是另一项任务。或者作为一个复合,它接受两个任务,并将第一个的输出作为输入传递给第二个。
答案 2 :(得分:0)
尝试以下方法。你遇到的问题是你的输出不能同时是V和U.
public U execute(V input) {
Object object = input;
for (Task task : taskList)
object = task.execute(object);
return (U) object;
}