訪問者パターンを生成して実装するために助けが必要です。私たちは大量に使用しinstanceof
ていますが、それは苦痛です。変更できると確信していますが、それを行う方法がわかりません。
基本的に私たちはインターフェースを持っていますProcessData
public interface ProcessData {
public setDelegate(Object delegate);
public Object getDelegate();
//I am sure these delegate methods can use generics somehow
}
ProcessDataGeneric
これで、実装するクラスができましたProcessData
public class ProcessDataGeneric implements ProcessData {
private Object delegate;
public ProcessDataGeneric(Object delegate) {
this.delegate = delegate;
}
}
ProcessData を取得する新しいインターフェイス
interface ProcessDataWrapper {
public ProcessData unwrap();
}
ProcessData を取得できるようにラッパーを実装する一般的な抽象クラスになりました
@XmlSeeAlso( { ProcessDataMotorferdsel.class,ProcessDataTilskudd.class })
public abstract class ProcessDataCommon implements ProcessDataWrapper {
protected ProcessData unwrapped;
public ProcessData unwrap() {
return unwrapped;
}
}
これで実装
public class ProcessDataMotorferdsel extends ProcessDataCommon {
public ProcessDataMotorferdsel() {
unwrapped = new ProcessDataGeneric(this);
}
}
同様に
public class ProcessDataTilskudd extends ProcessDataCommon {
public ProcessDataTilskudd() {
unwrapped = new ProcessDataGeneric(this);
}
}
これらのクラスを使用するときは、常に行う必要がありますinstanceof
ProcessDataCommon pdc = null;
if(processData.getDelegate() instanceof ProcessDataMotorferdsel) {
pdc = (ProcessDataMotorferdsel) processData.getDelegate();
} else if(processData.getDelegate() instanceof ProcessDataTilskudd) {
pdc = (ProcessDataTilskudd) processData.getDelegate();
}
これを行うためのより良い方法があることは知っていますが、ジェネリックとビジター パターンを利用する方法がわかりません。どんな助けでも大歓迎です。
アップデート
これらのクラスは、はるかに大きな実装の一部にすぎないことを付け加えておきます。ProcessData
andProcessDataGeneric
は、デリゲート (など) の外側にあるものですProcessDataMotorferdsel
。デリゲートはすべて拡張しProcessDataCommon
ます。
おそらくリファクタリングを行うのが最善であることに同意できますが、これは 2 年前の製品コードであり、リファクタリングにはコストがかかります (時間、テストなど)。しかし、私は喜んでそれを行います。
更新 #2
Generic プロセスを開始しようとしましたが、コンパイル エラーが発生します。これが今の様子です。
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);
}
}
オンラインでコンパイルエラーが発生しますunwrapped = new ProcessDataGeneric<ProcessDataMotorferdsel>(this);
:
[javac] ProcessDataMotorferdsel.java:52: incompatible types
[javac] found : ProcessDataGeneric<ProcessDataMotorferdsel>
[javac] required: ProcessData<ProcessDataCommon>
[javac]
そのエラーメッセージの表も裏もわかりません。ProcessDataMotorferdsel クラスは ProcessDataCommon を拡張するため、IMO は機能するはずです。