rendered paste bodyinterface Task<V, R extends Result<V>> {}interface Result<V> { V get();}class Processor { public <V, R extends Result<V>> R process(Task<V, R> t) { return null; }}//---- Cooking module ----------------------------------------------------------interface CookingTask<V, R extends CookingResult<V>> extends Task<V, R> {}class CookPuddingTask implements CookingTask<PuddingValue, PuddingCookedResult> {}class CookSteakTask implements CookingTask<SteakValue, 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<V, R extends LaundryResult<V>> extends Task<V, R> {}class CleanJeansTask implements LaundryTask<JeansValue, CleanJeansResult> {}class CleanTieTask implements LaundryTask<TieValue, 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<V, R extends Result<? extends V>> { 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);// } protected <V1 extends V, R1 extends R> V1 processTask(Task<V1, R1> task) { R1 result = proc.process(task); return handleResult(result); } abstract protected <V1 extends V, R1 extends R> V1 handleResult(R1 result);}