rendered paste bodyinterface Task<R extends Result> {
}
interface Result<V> {
V get();
}
class Processor {
public <R extends Result<?>> R process(Task<R> t) {
return null;
}
}
//---- Cooking module ----------------------------------------------------------
interface CookingTask<R extends CookingResult> extends Task<R> {}
class CookPuddingTask implements CookingTask<PuddingCookedResult> {}
class CookSteakTask implements CookingTask<SteakCookedResult> {}
interface CookingResult<V> extends Result<V> {
V accept(CookingVisitor vst);
}
class PuddingCookedResult implements CookingResult<PuddingValue> {
public PuddingValue get() { return null; }
public PuddingValue accept(CookingVisitor vst) { return vst.visit(this); }
}
class SteakCookedResult implements CookingResult<SteakValue> {
public SteakValue get() { return null; }
public SteakValue accept(CookingVisitor vst) { return vst.visit(this); }
}
class PuddingValue {}
class SteakValue {}
interface CookingVisitor {
public PuddingValue visit(PuddingCookedResult r);
public SteakValue visit(SteakCookedResult r);
}
class CookingClient extends AbstractProcessingClient<CookingResult> implements CookingVisitor {
CookingClient() { super(null); }
public PuddingValue cookPudding(Object data) {
CookPuddingTask task = null;
return processTask(task);
}
protected Object handleResult(CookingResult result) {
// dispatch by visitor pattern
return result.accept(this);
}
public PuddingValue visit(PuddingCookedResult r) { return r.get(); }
public SteakValue visit(SteakCookedResult r) { return r.get(); }
}
//---- Laundry module ----------------------------------------------------------
interface LaundryTask<R extends LaundryResult> extends Task<R> {}
class CleanJeansTask implements LaundryTask<CleanJeansResult> {}
class CleanTieTask implements LaundryTask<CleanTieResult> {}
interface LaundryResult<V> extends Result<V> {
V accept(LaundryVisitor vst);
}
class CleanJeansResult implements LaundryResult<JeansValue> {
public JeansValue get() { return null; }
public JeansValue accept(LaundryVisitor vst) { return vst.visit(this); }
}
class CleanTieResult implements LaundryResult<TieValue> {
public TieValue get() { return null; }
public TieValue accept(LaundryVisitor vst) { return vst.visit(this); }
}
class JeansValue {}
class TieValue {}
interface LaundryVisitor {
public JeansValue visit(CleanJeansResult r);
public TieValue visit(CleanTieResult r);
}
class LaundryClient extends AbstractProcessingClient<LaundryResult> implements LaundryVisitor {
LaundryClient() { super(null); }
public JeansValue cleanJeans(Object data) {
CleanJeansTask task = null;
return processTask(task);
}
protected Object handleResult(LaundryResult result) {
// dispatch by visitor pattern
return result.accept(this);
}
public JeansValue visit(CleanJeansResult r) { return r.get(); }
public TieValue visit(CleanTieResult r) { return r.get(); }
}
abstract class AbstractProcessingClient<R extends Result> {
Processor proc;
public AbstractProcessingClient(Processor p) { this.proc = p; }
protected <V, R1 extends Result<V>> V processTask(Task<R1> task) {
R result = (R)proc.process(task);
return (V)handleResult(result);
}
abstract protected Object handleResult(R result);
}