2012-06-07 47 views
2

問題是:什麼是最好的方法來擴展某些對象,其中包含當前上下文或場景所需的附加數據 。優雅對象擴展

例如,我有產品類具有基本(核心)屬性,如ID,名稱和價格。產品實例主要用作業務層操作的輸入/輸出,也用於在其他應用程序層之間傳遞信息。例如,當我需要使用一些擴展信息(例如Manufacturer,Made In,某些計算值等)列出GUI中的產品時,我通常會使SP返回一組行,然後我需要將這些附加數據存儲在Project實例中。 我不想用這些附加屬性中的每一個來擴展Product類(類最終會變得沉重和不雅,缺少主要功能),而且我也不想爲Product添加子類來添加新屬性(這會增加某些情況下的複雜性)。

我的想法是將一個或多個複雜的屬性(即存儲對象及其屬性),這將存儲用於各種方案的其他數據,但我不知道這是很好的解決方案。

你會建議什麼?

+0

你似乎想避免多態,因爲它會增加一些情況下的複雜性。你能解釋你的爭用嗎? –

+0

對象只是攜帶信息,它不會改變行爲時,只需添加一些額外的屬性。這不是一個優雅的解決方案,如果我爲每個使用對象的情況創建子類 - 我最終會有幾十個類做同樣的事情。從簡單的事情開始,作爲這些子類的命名,我的頭會爆炸。 – Dusan

回答

1

你可能會考慮構建兩個類。其中一個叫ProductSummary,將包含一些產品數據的只讀表示:

public class ProductSummary 
{ 
    public int Id { get; } 
    public string Name { get; } 
    public double Price { get; } 
} 

第二類,稱爲ProductDetail,將包含所有產品數據的讀寫表現:

public class ProductDetail 
{ 
    public int Id { get; } 
    public string Name { get; set; } 
    public double Price { get; set; } 
    public string Manufacturer { get; set; } 

    private ProductDetail() 
    { 
    } 

    public double ComputeValue() 
    { 
    } 

    public static ProductDetail(ProductSummary summary) 
    { 
     var newProduct = new ProductDetail(); 
     // load Product data using primary key from summary.Id  
     // populate newProduct from loaded data 
     return newProduct; 
    } 
} 

ProuctSummary類原來是一個重要的產品信息的輕量級只讀容器。可以使用一組ProductSummary數據來填充列表等。

一旦產品需要編輯,您可以使用來自ProductSummary對象的ID加載較重的ProductDetail類,您可以使用該類編輯場景。

這看起來像是多餘的工作,但考慮到類應該針對特定的用例進行設計。如果您對輕量級只讀摘要類有用,並且對可編輯類有單獨用例,那麼您可能需要考慮兩個單獨的類。

+0

不錯!基於我在問題中提到的方法。 – Dusan

2

聽起來像你有模型vs ViewModel的問題。 ViewModels僅用於顯示目的,因此有效的設計是讓視圖模型具有額外的屬性並將模型映射到UI級別的視圖模型。

+0

是的,對於某些情況,這也是一個問題。我強烈不喜歡創建ViewModel,然後複製模型中的所有屬性,如果只需要一個與View相關的附加屬性。 – Dusan

+0

正確,但視圖模型只能將初始模型作爲視圖模型的屬性加上所需的其他屬性。您可以映射到UI的視圖模型中的屬性屬性,因此您不需要爲這些屬性創建單獨的屬性。 –

+0

映射可以被優化,或者有自動繪圖器可以幫助您進行手動映射。但是,視圖模型用於像您需要在模型的數據中顯示UI上的不同內容那樣的場景,但它不完全在模型中,或者兩個不同的UI可能使用相同的數據來顯示它不同的方式。 –

0

我個人會擴展類,但你也可以做線沿線的東西:

public class Product 
{ 
    ... 

    public List<ProductProperty> AdditionalProperties { get; set; } 
} 

class ProductProperty 
{ 
    public string Name { get; set; } 
    public object Data { get; set; } 
} 

請記住,絕對不是最好的做法;)

0

所以......如果我理解這correcty:

  • 你不想在產品類別延伸到其秉承「產品」
  • 你不想加入所有的子類ŧ他額外的「情境」屬性到產品類別本身

鑑於此,你正在尋找的是一種方法來添加臨時屬性到一個對象的情景基礎?

我會推薦一個標準的簡單HashTable擴展「自定義屬性」。

private HashTable CustomProperties { get; set; } 

//Note: all three of these functions are unecessary if you make the hashtable public, but they do look good as far as an interface goes. 
public void AddCustomProperty (String key, Object value) 
{ 
    CustomProperties.Add(key, value); 
} 

public void RemoveCustomProperty (String key) 
{ 
    CustomProperties.Remove(key); 
} 

public object GetCustomProperty (String key) 
{ 
    return CustomProperties[key]; 
} 

這使您可以將所需的任何屬性直接存儲到Products對象中作爲KeyValue對。現在,顯示它們會變得更加有趣,因爲您不能再使用直接數據綁定了......與編輯相同。但直接設置框和標籤很容易。

的替代解決方案 - RUNTIME類型

聲明並不真正存在的,但也可以使用像它的自定義類型。

var ExtProduct = new { 
    MyCustomProp = "whatever I want", 
    ProductBase = productInstace }; 

根據需要進行擴展。

你也可以列出

var ExtProductList = from a in ProductList select new { 
    MyCustomProp = "Whatever I want", 
    ProductBase = a }; 

這是幾乎是無用的,當涉及到各地值傳遞給其他的東西非常臨時的事情,但對從連接列出自定義計算大量實用工具做到這一點或UI顯示臨時值。當您需要自定義值可編輯時,它們有點難以捕捉,但並不顯着。