Hi.
I need help to generify and implement the visitor pattern.
We are using tons of instanceof
and it is a pain. I am sure it can be modified, but I am not sure how to do it.
Basically we have an interface ProcessData
public interface ProcessData {
public setDelegate(Object delegate);
public Object getDelegate();
//I am sure these delegate methods can use generics somehow
}
Now we have a class ProcessDataGeneric
that implements ProcessData
public class ProcessDataGeneric implements ProcessData {
private Object delegate;
public ProcessDataGeneric(Object delegate) {
this.delegate = delegate;
}
}
Now a new interface that retrieves the ProcessData
interface ProcessDataWrapper {
public ProcessData unwrap();
}
Now a common abstract class that implements the wrapper so ProcessData can be retrieved
@XmlSeeAlso( { ProcessDataMotorferdsel.class,ProcessDataTilskudd.class })
public abstract class ProcessDataCommon implements ProcessDataWrapper {
protected ProcessData unwrapped;
public ProcessData unwrap() {
return unwrapped;
}
}
Now the implementation
public class ProcessDataMotorferdsel extends ProcessDataCommon {
public ProcessDataMotorferdsel() {
unwrapped = new ProcessDataGeneric(this);
}
}
similarly
public class ProcessDataTilskudd extends ProcessDataCommon {
public ProcessDataTilskudd() {
unwrapped = new ProcessDataGeneric(this);
}
}
Now when I use these classes, I always need to do instanceof
ProcessDataCommon pdc = null;
if(processData.getDelegate() instanceof ProcessDataMotorferdsel) {
pdc = (ProcessDataMotorferdsel) processData.getDelegate();
} else if(processData.getDelegate() instanceof ProcessDataTilskudd) {
pdc = (ProcessDataTilskudd) processData.getDelegate();
}
I know there is a better way to do this, but I have no idea how I can utilize Generics and the Visitor Pattern. Any help is GREATLY appreciated.
UPDATE
I want to add that these classes are just snippets of a much larger implementation.
The ProcessData
and ProcessDataGeneric
is something that is outside of the delegates (ProcessDataMotorferdsel
and so on). The delegates all extends ProcessDataCommon
.
I can agree that a refactoring is probably best to do, but this is production code that is 2 years old, and it is costly to refactor (time,testing, etc). However, I am willing to do it.
UPDATE #2
I have tried to start the Generic process, however I am getting compile error. This is how it looks now.
public interface ProcessData<T extends ProcessDataCommon> {
T getDelegate();
setDelegate(T delegate);
}
public class ProcessDataGeneric<T extends ProcessDataCommon> implements ProcessData<T> {
private T delegate;
//Getter & setter
public ProcessDataGeneric(T delegate) {
this.delegate = delegate;
}
}
public class ProcessDataMotorferdsel extends ProcessDataCommon {
public ProcessDataMotorferdsel() {
unwrapped = new ProcessDataGeneric<ProcessDataMotorferdsel>(this);
}
}
I get compile error on line: unwrapped = new ProcessDataGeneric<ProcessDataMotorferdsel>(this);
Saying
[javac] ProcessDataMotorferdsel.java:52: incompatible types
[javac] found : ProcessDataGeneric<ProcessDataMotorferdsel>
[javac] required: ProcessData<ProcessDataCommon>
[javac]
I cannot make heads or tails of that error message. The ProcessDataMotorferdsel class extends ProcessDataCommon, so IMO it should work.