3

親クラスを拡張する子クラスがいくつかあり、統一されたコンストラクターが必要です。これらのクラスのリストを保持するキューがあり、MergeHeuristicを拡張する必要があります。私が現在持っているコードは次のようになります:

    Class<? extends MergeHeuristic> heuristicRequest = _heuristicQueue.pop();
    MergeHeuristic heuristic = null;    

    if(heuristicRequest == AdjacentMACs.class)
        heuristic = new AdjacentMACs(_parent);
    if(heuristicRequest == SimilarInterfaceNames.class)
        heuristic = new SimilarInterfaceNames(_parent);
    if(heuristicRequest == SameMAC.class)
        heuristic = new SameMAC(_parent);

それを単純化してクラスを動的にインスタンス化する方法はありますか?

heuristic = new heuristicRequest.somethingSpecial();

これにより、ifステートメントのブロックがフラットになります。

4

4 に答える 4

3

キューのクラスを、インスタンス化するリクエストのタイプを示す一種のフラグとして使用しているようです。リフレクションを使用しない別のアプローチは、ファクトリメソッドを使用して、要求タイプを示す列挙型を導入することにより、このフラグの動作を明示的にすることです。

public enum HeuristicType {

  AdjacentMACsHeuristic(AdjacentMACs.class) {
    @Override public MergeHeuristic newHeuristic(ParentClass parent) {
      return new AdjacentMACs(parent);
    }
  },
  SimilarInterfaceNamesHeuristic(SimilarInterfaceNames.class) {
    @Override public MergeHeuristic newHeuristic(ParentClass parent) {
      return new SimilarInterfaceNames(parent);
    }
  },
  ... // other types here.
  ;

  private final Class<? extends MergeHeuristic> heuristicClass;
  public Class<? extends MergeHeuristic> getHeuristicClass() {
    return heuristicClass;
  }

  abstract public MergeHeuristic newHeuristic(ParentClass parent);

  private HeuristicType(Class<? extends MergeHeuristic> klass) {
    this.heuristicClass = klass;
  }

}

クライアントコードは次のようになります。

Queue<HeuristicType> _heuristicQueue = ...
HeuristicType heuristicRequest = _heuristicQueue.pop();
MergeHeuristic heuristic = heuristicRequest.newHeuristic(_parent);

リフレクションではなく列挙型を使用する主な利点は次のとおりです。

  • 新しいヒューリスティックタイプを追加するための要件を明示的に示しています。つまり、ヒューリスティッククラスが存在し、親に基づいてインスタンス化できる必要があります。
  • システムには、利用可能なすべてのヒューリスティックタイプを表示できる単一のポイントがあります。
  • インスタンス化をファクトリメソッドに抽象化することで、代替コンストラクタシグニチャの可能性を許可します。
于 2012-11-20T16:36:15.023 に答える
2

リフレクションを使用することもできますが、コードがより美しくなることはありません。

try {
    Constructor<? extends MergeHeuristic> heuristicConstructor = 
            heuristicRequest.getConstructor(_parent.getClass());
    heuristic = heuristicConstructor.newInstance(_parent);
} catch (Exception ex) {
    // TODO Handle this
}

これは、さまざまなクラスを計画している場合にのみ行ってください。そのうちの3つだけになる場合でも、気にしないでください。コードはそれで問題ありません。

于 2012-11-20T16:16:18.347 に答える
1

残念ながら、特定のコンストラクターまたは静的メソッドを持つようにクラスを強制することはできません。どちらも、あなたの場合に非常に役立ちます。

すべてのコンストラクターが同じ引数を取るため、動的クラスのインスタンス化を使用してコードを単純化するもう1つの方法があります。

Constructor c = heuristicRequest.getConstructor(ParentClass.class).
heuristic = c.newInstance(_parent);

コードに_parentのクラスタイプが含まれていないことに注意してください-私が名前を付けたコードサンプルでは-それParentClass.classをコードに適合させる必要があります。

于 2012-11-20T16:13:30.450 に答える
0

Class.forName(heuristicRequest.getName())オプションはありますか?

それでconstructor heuristicRequestClass.getDeclaredConstructor(_parent.getClass());

最後heuristic = constructor.newInstance(_parent);

于 2012-11-20T16:16:44.100 に答える