Only minor modifications lead to this solution (if I didn't miss some point (untested)).
You get the following benefits:
- information passing is very straightforward (using instance variables)
- you retain thread-safety
- from an external (public) view,
ConcreteProcessor
can remain immutable
It would probably be best not to return a ConcreteProcessor
from updateData
but some immutable type that represents the transformed data.
public abstract class AbstractProcessor {
public void updateDataFromUrl(String url) {
//Download url
//Decrypt, and do a lot of stuff,
String data = "abc"; //Result from downloading
String processed = processData(data);
//Do a lot of other things with the transformed data
}
public abstract String processData(String data);
}
final class ConcreteProcessor extends AbstractProcessor {
public static ConcreteProcessor updateData(int year, int month, int day) {
ConcreteProcessor p = new ConcreteProcessor(year, month, day);
p.updateDataFromUrl(url);
return p;
}
private /* instance vars for year, month, day, url, ... */
private ConcreteProcessor(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
this.url = String.format("http://%d.%d.%d", year, month, day);
}
@Override
public String processData(String data) {
//Process the data
//---------------
// NO PROBLEM:
//----------------
//Easy to access to year, month, day using the instance vars
return null;
}
}
But the overall concept looks like a linear pipeline and therefore it would probably be best to make the pipeline more explicit. You will need some kind of state carrying but that shouldn't be a big problem using generics I think.