2014-01-06 88 views
0

以前我聽說過多重繼承的缺陷,而且我知道.Net開發者反對它被包含在內。如何在.Net中處理真實世界的多重繼承場景?

說到這裏,考慮一個簡單的例子,比如'遊戲公司'。一家遊戲公司可以是:

如果我必須在.Net中對此進行建模,那麼我將如何處理「存在」關係存在以及公司可以同時存在多個關係這一事實?想象一下,我有一個模型:

  1. Game類,有List<Developer>Publisher作爲屬性
  2. Console類,有一個Manufacturer財產。

在一個理想的情況下,這應該儘可能安全,並且易於過濾和導航到每個類(如完全連接的實體框架映射)。

我以同樣的態度思考了一些事情,對此我可能知道「正確」的答案。

如果我有FatPersonTallPerson作爲基類並想「解決」多繼承限制?因爲很可能有一個同時又胖又胖的人。在這種情況下,如果有一個單獨的Person有兩個屬性,即WeightHeight,它可能會更乾淨,從而完全消除基類。這只是一個重寫我以前所做的任何過濾的問題,而這些過濾是基於要考慮這些新屬性的對象的類型。

對於每個多重繼承情況,是否存在與此相當的內容?對於我提出的這個特殊情況呢?

更新:

我讀過,被標記爲我的一樣這個問題的答案(前張貼這一個),但我在這裏稍微不同意。我認爲這與將SQL優化問題標記爲每個其他SQL優化問題的重複相同。最後,每種情況都是不同的情況,並且需要不同的方法/答案。我認爲這適用於此,因爲我詢問了一個非常固定的情況,就像其他答案一樣。

+0

也許我不明白。你的解決方案是:如果你不繼承,那麼你將不會有多重繼承?無論如何......問題是什麼? –

+0

您列舉的特定情況並未定義任何需要多重繼承的情況。比如說暴雪,你可能只有兩個對象,BlizzardDeveloper和BlizzardPublisher。在繼承Developer和Publisher的同時獲得一個對象會獲得什麼? –

+0

如果你使用屬性,你甚至可以用提供它的語言來躲避MI,所以是的。真正的問題是你是否需要諸如Publish之類的方法,在這種情況下,如果它實現了界面,你就斜視並說實體是一個發佈者IPublish –

回答

1

這個場景就是一個很好的例子基於角色的軟件工程這是當前研究的一個話題。這是因爲沒有解決問題的辦法。有幾種方法,但都有缺點。

接口是設計類型關係的好方法。如果你製作例如DeveloperPublisher接口,可以有兩個公司。但是,您不能從接口繼承代碼,並且通常最終會產生大量重複的代碼。

更進一步,你想出mixin繼承。這基本上是擴展了擴展方法的接口實現。看看這個例子:

class Company { } 

interface Publisher { } 
public static class PublisherMixin 
{ 
    public static void Publish(this Publisher p) 
    { 
     //do something 
    } 
} 

class CompanyThatIsAPublisher : Company, Publisher { } 

然後你就可以做

var c = new CompanyThatIsAPublisher(): 
c.Publish(); 

可以爲幾個混入做到這一點。你甚至可以在弱基準字典的幫助下爲mixin提供狀態。

避免代碼重複的另一種方法是委派。你仍然有你的界面層次結構,但爲開發者角色,發佈者角色等創建對象。然後,公司只是將方法調用轉發給這些子對象。但是,這會導致精神分裂症。子對象並不屬於可能造成問題的主要對象。但是,您可以輕鬆地交換它們。您可以在C#中使用DynamicObject。有了這個,您可以動態註冊角色並動態地將方法調用重定向到適當的對象。所以開發商公司最終可以成爲出版商,而不必放棄其身份。這種方法也患有目標精神分裂症問題。

+0

非常好,我以前見過這個mixin方法。你有什麼建議可以讓測試更友好嗎?我一直認爲這些擴展方法適用於沒有副作用的小型純方法。那裏的'Publish'方法可能會有複雜的代碼,並且在這種測試過程中不可能剔除主類中的行爲。 – julealgon

+1

您可以使用與mixin相同的方法添加模擬類。編譯器將在擴展方法之前選擇類方法。 –