2016-11-14 5 views
1

私はJavaでGraphデータ構造を実装しようとしています。 は以下のクラスです:Javaの継承を介して異なる実装のalgoロジックを再利用

interface Graph<N,E> { 
    addNode(N nodeData); 
    createEdge(N src, N dest, E edgeData); 
    //and many more api methods 
} 

class GenericGraph<N,E> implements Graph<N,E> { 

    Set<Node<N,E>> vertices; 

    static class Node<N,E> { 
     private N node; 
     private Set<Edge<N, E>> adjacencyList; 

     // getters and setters 
    } 

    static class Edge<N, E> { 

     private E edgeData; 
     private Node<N, E> src; 
     private Node<N, E> dest; 

     // getters and setters 
    } 

    //******** API methods implementation********* 

    Node<N, E> findNode(N nodeData) { 
     Node<N, E> node = new Node<>(nodeData); 
     if (vertices.contains(node)) { 
      for (Node<N, E> tempNode : vertices) { 
       if (Objects.equals(tempNode, node)) { 
        node = tempNode; 
        return node; 
       } 
      } 
     } 
     return null; 
    } 

    Node<N, E> createNode(N nodeData) { 
     Node<N, E> node = findNode(nodeData); 
     if (node == null) { 
      node = new Node<>(nodeData); 
      vertices.add(node); 
     } 
     return node; 
    } 

    @Override 
    public void addNode(N nodeData) { 
     createNode(nodeData); 
    } 

    // other api methods 
} 
ここ

私は2つの入れ子になったクラス作成しました:ノードとエッジ

1つのグラフオブジェクトは、多くのノードを持つことができます。

1つのノードオブジェクトは、隣接する頂点のリストを持つことができます。

隣接する頂点は

->src node 
->dest node 
->edge relation bw the two 

GenericGraph APIメソッドを実装するためのクラスノードとエッジを使用含まエッジ、と考えられます。

これまですべて正常に動作します。

今私はなどBfsGraph、DfsGraphようGenericGraphよりもいくつかの余分な機能を持っているいくつかの他のクラスを作りたいBFSアルゴが自分のノードのための3つの余分なパラメータ必要

->color 
->parent 
->distance 

を私が考えていましたこのようBfsGraphを作成するには:この設計に問題がある

class BfsGraph<N,E> extends GenericGraph<N,E> { 

    //access public,protected and default methods of GenericGraph 

    private enum NodeColor { 
     WHITE, GRAY, BLACK; 
    } 

    static class BfsNode<N,E> extends GenericGraph.Node<N,E> { 
     private NodeColor color = NodeColor.WHITE; 
     private Integer distance = Integer.MAX_VALUE; 
     private Node<N, E> parent; 

     BfsNode(N node) { 
      super(node); 
     } 
    } 
} 

を、私はGenericGraphから各メソッドをコピーしてBfsGraphのACCでそれを再実装する必要があります(ノードはBfsNodeに変わります)。

将来私は他の実装をしたい場合は、すべてのメソッドをコピーして変更する必要があります。

GenericGraphで記述されたアルゴリズム/ロジックは、再利用しないで再利用する必要があります。

私に新しい解決策または変更を提案してください。サブクラスは二つのことをコントロールできるようにする必要がありようなあなたの記述から

+0

( 'BfsGraph'は、オフ_sounds_ながら)アルゴリズムを書き換える代わりに(' Generic') 'Graph'(とまったく同じことをやっていない)から、それを再利用する_one_例を提供してください。 (あなたは 'super'を使ってメンバーのアクセス/呼び出しを修飾することができます。) – greybeard

答えて

1

は、それが聞こえる:

  • 作成NodeインスタンスはNodeのサブタイプのインスタンスでなければなりません。
    • これは単にNodeをインスタンス化すること、createNodeと呼ばれる、GenericGraphprotected方法を作成することによって処理することができます。 GenericGraphは、Nodeインスタンスが必要なときはいつでもそのメソッドを呼び出すことができます。そのサブクラスはそのメソッドをオーバーライドして、適切なサブタイプNodeを提供できます。
    • すでにcreateNodeメソッドがありますが、ノードを作成するだけでは他のロジックもあります。そのメソッドの名前を完全な目的を持つものに変更する必要があります。
  • findNode方法はNodeの適切なサブタイプを返すように宣言する必要があります。

    • これは、サブクラスのオーバーライドfindNodeを持つが、オーバーライドして、単にスーパークラスに委譲し、そのような適切なキャスト、実行することにより処理することができます:あなたがメソッドの束を持っている場合

      BsfNode<N, E> findNode(N nodeData) { 
          return (BsfNode<N, E>) super.findNode(nodeData); 
      } 
      
    • をこのように、GenericGraphが実際にノード型を型パラメータとして受け取るようにすると、明示的なオーバーライドを要求するのではなく、ジェネリックの魔法を使って処理できるようになります。しかし、あなたがそのアプローチが価値のあるところにいるようには聞こえません。
+0

私の必要性のいくつかのシナリオで継承を使用することを検討していましたが、このデザインは正しくありません。しかし、あなたのソリューションは、この設計をある程度まで拡張するのに役立ちました。だからBfsGraphを作成するのは間違った解決策です。しかし、とにかく感謝します。 –

関連する問題