2010-11-27 6 views
5

私はJavaで責任チェーンのデザインパターンを使用しています。チェーン全体は、特定のタイプのオブジェクトの要求を表します。チェイン内の各「ハンドラ」は、要求された1タイプのユニットを処理します。 すべてのリクエストは本質的に同じ方法で処理されるので、 "Handler"クラスの汎用を作成しようとしました。 だから私はこのような方法で(それが唯一の私の問題を難読化になるので、それ自体の取り扱いが簡略化される)必要があるハンドルクラスで:責任を負う責任のハンドラをJavaジェネリックで

public class Handler<T>{ 
    int required; 
    Handler<?> next; 

    public void handle(Object O){ 
     if(o instanceof T){ 
     required --; 
     }else{ 
     next.handle(o); 
     } 
    } 
} 

問題は、このようなinstanceofは不可能であるということです。タイプTは実行時に明示的に格納されていないため(または、私がインターネットでの研究中に理解したもの)です。だから私の質問は:最良の選択肢は何ですか?

答えて

2

ハンドラがサポートするクラスを定義するには、コンストラクタのパラメータを使用してジェネリックを使用してハンドラを実装します。

public class Handler<T> { 
    private int required; 
    private Handler<?> next; 
    private Class<? extends T> c; 

    public Handler(Class<? extends T> c) { 
     this.c = c; 
    } 

    public void handle(Object o) { 
     if (c.isInstance(o)) { 
      required--; 
     } else { 
      next.handle(o); 
     } 
    } 

    // ... 
}  
+0

確かに...より高いオブジェクトレベルで動作しますが、ジェネリックスはコンパイル時にメソッドシグネチャの 'Object'にデフォルト設定されているようです。とにかく。 2番目のソリューションは削除されていますが、最初のソリューションはまだ達成しようとしているものにぴったりです –

+0

これは私が達成したいソリューションに最も近いものです。今ではジェネリック部分を削除することができます。なぜなら、Classを引数としてすべて行うことができるからです – Ingdas

1

それは醜いだろうが、あなたはこれを試みることができる:

public abstract class Handler { 
    int required; 
    Handler next; 

    public void handle(Object o){ 
     if(getMyClass().isInstance(o)){ 
     required --; 
     }else{ 
     next.handle(o); 
     } 
    } 

    protected abstract Class getMyClass(); 
} 
+0

+1を - それは動作し、それは本当にすべてが醜いではありません。 –

+0

'getClass'は' java.lang.Object'で 'public'として定義されていませんか?より厳しいアクセスレベルで上書きしようとしているようです。 –

+0

そして、別の名前を選択した場合、 'Class'は型パラメータを持つべきです:' protected abstract Class getHandledValueType(); ' –

1

あなたは両方のベースとサブクラスがイベントをキックオフいくつかのケースを持っていない限り、あなたが実際に、まったくチェーンを使用していないように見えます。そのない限り、一部が適用されない場合は、

Map<Class, Handler> handlers = //...initialize however 

のように、ルートハンドラ内で何かができる:それはあなたが扱う呼び出す場合、ジェネリックを使用してハンドラを持ってしても意味がありません

public void handle(Object o) { 
handlers.get(o.getClass()).handle(o); 
} 
0

すべてのオブジェクト。

public class Handler<T>{ 
    int required; 
    Handler<?> next; 

    public void handle(T O){ 
    ... 
    } 
} 

か、抽象クラスのハンドラを定義し、特定のサブクラスは、特定のタイプを扱うか、単にチェーンにイベントを渡すようにしましょう: はどちらかあなたは次のようにタイプのハンドラをインスタンス化します。また

if(x.isInstance(o)) {...} 

を使用して は本当にアンチパターンですし、OOPのルールを破ることができます。

関連する問題