2012-01-02 122 views
7

我有一組類擴展了一個抽象類。這些類的一個子集需要一個方法的相同實現,另一個類的子集需要方法的另一個實現,第三個子集需要另一個。總共有十個子類,但其中一種方法只有三種可能的實現方式。 (這些類實現的許多其他方法沒有任何共同之處。)如何在沒有多重繼承的情況下做到這一點

我試圖找出完成此操作的最佳方法。我認爲我在C++中所做的是多重繼承:創建三個只實現此方法的類,然後讓子類從這三個類中相應的一個繼承。

在Java中這樣做有最佳做法嗎?

我正在考慮三個抽象類的介入層,介於主抽象類和子類之間。這三者中的每一個都從主抽象類繼承,並實現了所討論的方法。然後這些孩子從這三位繼承。但是,如果另一種方法伴隨着類似的「分組」行爲,並且不符合三個「中間層」類,我不喜歡這種情況?那會變醜

這是否有任何意義?我在趕時間寫...

編輯:因此,24小時後提出我的問題,我收到了大約六打模式進行調查。我不確定他們是否都是官方設計模式名稱。但是我會研究每一個,然後回報(並選擇一個正確的答案)。到目前爲止提出的圖紋:

* Delegation 

* Bridge 

* Strategy 

* Composition 

* Decorator (if I was choosing on name alone, I choose this one) 

我還需要補充一點的是正在實施的需要方法來訪問幾乎所有類的私有成員。所以這在我的選擇中會佔很大的比例。

回答

3

如果你堅持通過繼承來解決它,GoF書中的bridge pattern可能對此有所幫助(它可能或可能不是一個完美的結合,這取決於哪些領域問題導致分離爲三個實現)。就我個人而言,我可能只是將三個方法實現放入一個助手類中,並從類中轉發方法調用(JB Nizet正確地稱爲委派)。

+0

感謝您的鏈接,我將閱讀並回復我的問題。你還在聽嗎?我是新來的。發佈到回答的評論是否會導致某種警報發送給回覆者? – 2012-01-03 18:43:08

+0

對答案的評論會觸發一些小小的通知,但如果您有後續問題,則更應該以網站的精神將其作爲新的發佈(同時檢查重複內容),而不是在先前的答案上請求後續答案。像這樣的元討論具有[自己的子站點](http://meta.stackoverflow.com/),並且在這裏被壓垮了。 – Barend 2012-01-03 21:32:21

6

使用委託而不是繼承。讓同一組的所有類都委託給一個通用的幫助對象來實現它們的方法。

+0

我認爲橋樑和戰略模式也歸結爲授權。您認爲哪種模式最適合您?或者我們應該在這裏沒有模式(只要幫助類本身不是一個模式)?我認爲提問者現在留下了多個答案,所有這些答案本身都沒有錯...... – 2012-01-02 19:39:14

+0

戰略模式似乎是最合適的模式,除了策略模式包含向班級注入策略。在這種情況下,我不認爲這些類必須從外部進行配置。一個方法必須從課堂上外化。一切都不能有模式名稱,在這裏簡單的委託就足夠了。 – 2012-01-02 22:25:13

+0

同意。模式很好,但不應該用在他們不適用的地方。 – 2012-01-02 22:56:55

1

不使用繼承的簡單快速解決方案是將3個「常用方法」抽象到其他位置,然後重複該方法調用。

如果你想以一種很好的OO方式來做它,那麼看一下裝飾模式,這可能對你很有幫助 - 創建3個標準類來實現你的三個選擇的方法,然後用另一個「裝飾」它們類。

1

首先,考慮用接口替換抽象類。我不知道在你的情況下是否可能有 。其次,您可以將您的「分組」方法的功能刪除到另一個類(執行者)。創建3個不同的類,實現該方法(或者只是某些類中的3個不同方法),並根據需要從子類中調用它們。

因此,「分組」方法將在每個子類中定義,但它只會顯式地調用3個可能的實現者之一。

7

其實,我在這裏聞到策略模式。

您可以在基類委託給在構造時傳入的策略的那個方法。子類只是通過一組策略中的任何一個作爲其構建的一部分。這些策略本身可以在課堂之外提供,也可以在內部以私人課程的形式提供。這可能最終會導致層次結構中的類更少。

這就是說,這裏還有其他的氣味,即使我提出的解決方案。你可能想在更高層次上考慮接口(如其他解決方案所提到的)和組合,只有沒有繼承。隨着時間的推移,我得出結論,繼承不是我的朋友。現在我儘可能避免它。

+0

策略不一定只適用於1個方法。我可以有一個實現多種方法的策略(如果它們按照這種方式分組)。我也可以爲每個接口和實現提供多種策略接口,然後在構建時根據需要進行組合。只是一個想法。不一定是最好的答案。編輯:這是一個評論的迴應,當*我輸入時被刪除*。 :) – rfeak 2012-01-02 18:32:24

+0

我非常喜歡你的答案我刪除了我的。如果另外一種方法也需要在類之間共享,策略模式也可以再次使用。 – toto2 2012-01-02 18:35:20

+0

對不起,我刪除了評論...這是錯誤的,我的回答也是如此。但正如你從上面的新評論中可以看到的,我完全同意你的觀點。 – toto2 2012-01-02 18:36:33