2016-09-20 116 views
1

我無法確定下面這兩個示例的優點和缺點。理想情況下,我想知道它的重量高達最佳的設計方案:空派生類與Vs類型屬性

例1(類型屬性):

public abstract class Animal : /* all relevant interfaces*/ 
{ 
    /* 
    All necessary implementations 
    */ 
} 

Public class Dog : Animal 
{ 
    Public string Name {get; set;} 
    Public Breed Type {get; set;} 

    /* 
    All necessary implementations 
    */ 
} 

Public Type Breed 
{ 
    Bulldog, 
    Chihuahua, 
    Labrador, 
    /* 
    So on…… 
    This can grow without limitation, 
    you dno't know how much it will grow into, or 
    what breed you will have tomorrow e.g BulldogChihuahuaCross, 
    or BulldogLabradorCross. 
    */ 
} 

例2(空派生類):

public abstract class Animal : /* all relevant interfaces*/ 
{ 
    /* 
    All necessary implementations 
    */ 
} 

Public class Dog : Animal 
{ 
    Public string Name {get; set;} 

    /* 
    All necessary implementations 
    */ 
} 

Public class Bulldog : Dog 
{ 
    /* Empty Class */ 
} 

Public class Chihuahua: Dog 
{ 
    /* Empty Class */ 
} 

Public class Labrador: Dog 
{ 
    /* Empty Class */ 
} 

編輯:

在示例1創建Dog的實例,並將其類型指定爲屬性,在示例2中創建該特定類型的實例。

我正在尋找一些深入的論點,可擴展性,可維護性,在CPU上的成本,如果有1000種品種,運行查詢等費用。

+0

這實際上是一個非常好的問題,大多數人都懶得問。我認爲對你來說,這是一個很好的答案,但是直到今天晚些時候,你纔沒有時間寫出來。敬請關注。 –

+0

@ JimL.I期待着您的回答。 – Jegan

+0

@JimL。或者像費馬特說:我有一個很好的證據,但這裏的邊際太窄了,不能寫下來;-) –

回答

2

頻譜有兩種極端情況。一方面是那些僅僅是信息化的東西,並被操作爲文本,數字或對枚舉實例的引用。例如,一個狗沙龍應用程序可能會記錄您的寵物的名稱,顏色和品種,僅作爲識別目的的文本。另一方面是一些需要具有不同屬性,操作或方法的東西。例如,視頻遊戲可能會在每次發出吠聲時爲每隻狗發出不同的聲音。

作爲設計師必須做出的決定是如何準確地反映「話語的領域」與何時採取特定應用的快捷方式。在話語領域,每個品種都具有獨特的特徵,但對於狗沙龍應用的目的而言,你根本不在意。在這種情況下,您可以設計出細節,並希望將來您永遠不需要它。

問題出在該頻譜的中間,在那裏有人做出錯誤的決定。我曾在大型企業系統上工作過,在那裏有人將繼承層次壓縮成顯式編碼爲一個或多個數據庫列中值的類型。這很可怕,因爲它成爲程序員的問題,知道哪些其他列對於每種編碼類型都是有效的。該系統在各地都有切換語句,以實施隨時間演變成非常複雜的業務規則。該系統有很多錯誤。

因爲這個原因,在光譜中間的地方,事情並不那麼清晰,我會在許多課堂上犯錯。理由是準確地反映域使得更容易判斷是否滿足要求,並且可以使代碼更直觀地維護(假設它是DDD)。反映域的關鍵是準確地表示事物集合。例如,「Fido」是Dog集合和Animal超集的成員; 「西爾維斯特」是貓組和動物超集的成員。這對於人們來說很容易理解,並且每個類都可以有不同的外部隱藏的實現。一旦你開始解釋顯式編碼爲字符串,整數或枚舉類型引用的類型,你就需要遍佈各處的switch語句,並且你有一個難以維護,難以理解的混亂。許多面向對象的語言可以爲您節省所有這些,但您必須創建一個包含完整類型列表的工廠。運行時開銷可以忽略不計(特別是如果您實現工廠在恆定時間運行),並且類型可以映射到關係數據庫中的值,以便您可以查詢並報告它們。此外,正如您所指出的,您可能會利用仿製藥。

如果你知道你的課程將永遠是空的,就像在一個狗沙龍應用程序的情況下,不要打擾類。如果您知道他們將擁有不同的屬性,操作和方法,或者如果您不確定,請使用類。

+0

謝謝吉姆。這正是我的問題,我給出的例子比我現實中的要簡單得多。我正在研究一個非常複雜的企業系統。它使用「事件源」和DAG(有向無環圖),因此係統有兩部分,第一部分創建對象的實例,第二部分,這些對象註冊了依賴大量使用泛型的事件源。爲了適應泛型的使用,隨着時間的推移,空的類已經接管了。 – Jegan

+0

雖然在項目開始的時候,有很多未知的,但現在,它有點解決。我的問題是值得從話語領域轉移,同時我希望保持謹慎,不要像開關語句或任何地方那樣在大混亂中結束。 – Jegan

+0

爲什麼現在要改用枚舉的機會呢?我指出了在這條道路上骯髒的可能性。我不認爲班級有一個真正的缺點,除了他們很煩人。 –

1

第一種方法可以讓你確定哪些品種是狗,但第二種方法可以讓你爲子類制定特定的實現。

如果您打算需要對象爲每個不同的狗品種設置不同的方法或屬性,請使用派生類,否則僅更簡單地使用類型屬性和單個類。

+0

我正在尋找一個深入探討兩個設計的利弊的論點;比如說,這是一個擁有100萬隻狗和1000個品種的企業系統。 – Jegan

+1

用戶Kasper Holdum已經有相當長的討論:[http://stackoverflow.com/questions/1338391/when-to-subclass-instead-of-differentiating-the-behaviour](http://stackoverflow。 com/questions/1338391/when-to-subclass-instead-of-differentiating-the-behavior) – SilentLupin

+1

實際上,這與你的問題幾乎完全相同,並且回答得很好:[http://stackoverflow.com/questions/4254182 /inheritance-vs-enum-properties-in-the-domain-model](http://stackoverflow.com/questions/4254182/inheritance-vs-enum-properties-in-the-domain-model) – SilentLupin

1

好吧,這裏是我的2美分:如果你正在尋找一個快速訪問任何東西,你會把它放在一個關聯數組中。你的兩個實現都提供了一個哈希碼來作爲對象地址,這使得它們可以以相同的速度訪問。只有打算添加功能時,子類纔有意義(基本上)。從枚舉中獲取類型與從枚舉中獲取類型沒有什麼不同。如果你需要聰明的查詢,創建一個聰明的關聯數組。

+0

這是一個很好的觀點。我試圖從空的子類移動到類型列表,但我想確保我不會在設計中創建混亂。 – Jegan

+0

設計方面(如上所述)枚舉是更好的選擇,因爲您只創建用於輸入的子類而不添加功能,這是他們的真正目的。 –