2009-11-17 45 views
0

我試圖決定哪個是更好的方式來分派在AspectJ的一個類型。 假設我正在用三種節點對一棵樹進行計算。然後,我可以寫一個簡單的Java方法:多態性的AspectJ

private void computation(TreeNode node) { 
    if (node instanceof Node0) { 
     // Do stuff. 
    } else 
    if (node instanceof Node0) { 
     // Do stuff. 
    } else 
    if (node instanceof Node0) { 
     // Do stuff. 
    } 
} 

private void computation(TreeNode node) { 
    switch (node.kindNode()) { 
     case NODE0: 
      // Do stuff. 
      break; 
     case NODE1: 
      // Do stuff. 
      break; 
     case NODE2: 
      // Do stuff. 
      break; 
    } 
} 

或者我可以注入的方法將每個節點類型:

private void Node.computation() { 
    throw new UnsupportedOperationException(getClass() + ".computation()"); 
} 

private void Node0.computation() { 
    // Do stuff. 
} 

private void Node1.computation() { 
    // Do stuff. 
} 

private void Node2.computation() { 
    // Do stuff. 
} 

哪種方法最好,爲什麼?

回答

1

是什麼preferrable非常依賴於這種情況。

如果我理解你的問題是正確的,你想以某種方式將這種「計算」方法事後添加到已經存在的類型層次結構中,並且更改原始類型的源代碼不是一個選項,對吧?

在這種情況下,最重要的問題是:如何頻繁的更改節點類型層次?因爲任何這樣的改變都可能會迫使你調整你的方面,這是一個維護問題。

話雖如此 - 你的第三個建議是「cannonical」面向對象的解決方案。在一般的編程,它是usally優於開關情況下的方法,因爲後者往往會導致複雜和難於理解代碼,除非computation()的操作是非常短而簡單。基本上,對於基於AspectJ的解決方案也是如此,就像你的情況一樣。但是設置方面稍微困難一點,因爲它必須將定義注入多個子類中,而在另一種情況下,當您使用開關案例解決方案時,您只需將一個小的轉發方法注入基類並從那裏跳到一個普通的java類中來保存你的開啓類型。

訪問者模式:實際上,您在這裏執行的操作看起來像訪問者模式的經典用例,可以使用某個方面進行優雅地實現。或許,這將是最乾淨的解決方案,但在自己Visitor模式是一種高級的主題(我可以更詳細地解釋,如果有興趣)