2016-11-14 15 views
1

我想在java中實現圖數據結構。 下面是類:通過在java中的繼承重用算法邏輯的不同實現

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 
} 

在這裏,我已經創建了兩個嵌套類:節點和邊緣

一個圖形對象可以有多個節點。

一個節點對象可以有一個相鄰頂點的列表。

相鄰頂點被視爲邊緣,其中包含

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

GenericGraph API方法使用類節點和邊實施。

直到現在一切正常。

現在我要做出比GenericGraph,像BfsGraph,DfsGraph等一些額外功能的一些其他類

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一個子類型的實例。
    • 這可以通過創建一個protected方法GenericGraph來處理,稱爲createNode,這只是實例化Node。然後,只要需要Node實例,GenericGraph就可以調用該方法;子類可以覆蓋該方法以提供Node的正確子類型。
    • 我注意到你已經有了一個createNode方法,但除了創建節點外,它還有其他的邏輯。您應該將該方法重新命名爲捕捉其全部用途的內容。
  • findNode方法需要被聲明爲返回的Node適當亞型。

    • 這可以通過在子類中重寫findNode進行處理,但與超越簡單地委託給超和進行適當的投,像這樣:

      BsfNode<N, E> findNode(N nodeData) { 
          return (BsfNode<N, E>) super.findNode(nodeData); 
      } 
      
    • 如果你有一大堆的方法像這樣,那麼你可能會考慮讓GenericGraph實際上將它的節點類型作爲類型參數,這樣就可以通過泛型的魔術來處理,而不需要顯式的覆蓋。但聽起來你並沒有想到這種方法是值得的。
+0

我正在考慮對我的需求的某些場景使用繼承,但是這種設計看起來不正確。但是你的解決方案幫助我將這種設計擴展到某種程度。所以創建BfsGraph是完全錯誤的解決方案。但無論如何謝謝。 –