I've been struggling with the following problem. I have a series of function objects, each with it's own input and output types defined via generic type arguments in java. I would like to arrange these in a chain so that raw data is input to the first function, transformed to the into the output type, which is the input type of the next object, and so on. of course this would be trivial to hard-code, but i'd like to have the code be pluggable to new function objects. if i just leave out type arguments (only the final output type), this is how things look:
public T process() {
Iterator<Context> it = source.provideData();
for(Pipe pipe : pipeline) {
it = pipe.processIterator(it);
}
return sink.next(it);
}
here an iterator over the data is passed between function objects, and context should be Context. is there a way to keep the following kind of pipe pluggable and still maintain type safety?
edit:
for clarity, i have a series of function objects, pipes. each takes as input a particular type and outputs another type. (actually an iterators over these types) these will be chained together, eg, Pipe<A,B> -> Pipe<B,C> -> Pipe<C,D> -> ...
, so that the output of one pipe is the input type for the next pipe. There is also a source here that outputs an iterator of type A, and a sink that would accept type (the output of the past pipe). does this make things clearer? The question is, because there is critical dependence on the compatibility of input and output types, is there a way to ensure this?
I am starting to think that on insert of the function objects into the pipeline may be the best time to ensure type safety, but i'm not sure how to do this.
edit 2: i have a adder method for the function objects that currently looks like below:
public void addPipe(Pipe<?,?> pipe) {
pipeline.add(pipe);
}
i'd like to check if the first type parameter is the same as the "end" of the current pipe, and throw an exception if not? i dont think there is a good way to get compile time safety here. the "end" of the current pipe can then be set to the second type param of the input pipe. I can't think of how to do this with generics, and passing around the class information seems pretty hideous.