2011-03-23 15 views
2

在試圖集中如何添加項目或從業務實體類中移除項目時,我已將模型移至所有列表僅顯示爲ReadOnlyCollections的模型,並提供了Add和Remove方法來操作列表中的對象。業務實體 - 應將列表僅暴露爲ReadOnlyCollections?

下面是一個例子:

public class Course 
{ 
    public string Name{get; set;} 
} 

public class Student 
{ 
    private List<Course>_courses = new List<Course>(); 
    public string Name{get; set;} 
    public ReadOnlyCollection<Course> Courses { 
     get{ return _courses.AsReadOnly();} 
    } 
    public void Add(Course course) 
    { 
     if (course != null && _courses.Count <= 3) 
     { 
      _courses.Add(course); 
     } 
    } 
    public bool Remove(Course course) 
    { 
     bool removed = false; 
     if (course != null && _courses.Count <= 3) 
     { 
      removed = _courses.Remove(course); 
     } 
     return removed; 
    } 
} 

我在做上述是爲了不與貧血數據模型(反模式)結束,並且還避免其將所述邏輯目標的一部分和刪除所有地方的課程。

一些背景:我正在使用的應用程序是一個Asp.net應用程序,其中的列表曾經作爲列表公開,這導致了各種方式將課程添加到學生(有些地方支票已經支付,其他支票未支付)。

但我的問題是:以上是一個好主意嗎?

+0

我通常公開IEnumerable <>而不是ReadOnlyCollection,因爲Count()等在運行時類型上進行了優化,無論如何都沒有顯着的性能損失。 – 2011-03-23 22:18:45

回答

1

是的,這是一個很好的方法,在我看來,除了裝飾你的列表之外,你沒有做任何事情,它比實現自己的IList更好(因爲你節省了許多代碼行,即使你失去了更優雅方式遍歷課程對象)。

您可以考慮接收驗證策略對象,將來你可能有一個新的要求,爲前:一種新的學生,可以有超過3個療程,等

1

我想說這是一個好主意,當添加/刪除需要按照您建議的方式進行控制時,例如業務規則驗證。否則,就像你從前面的代碼中知道的那樣,確實沒有辦法確保執行驗證。

但是,您可能想要達到的平衡是什麼時候做到這一點,什麼時候不做。爲每一種收集做這個似乎是矯枉過正。然而,如果你不要這樣做,然後以後需要添加這種類型的關守代碼,那麼這將是一個突破性的改變,當時可能會或可能不會很頭疼。

我想另一種方法可能是有IList<T>這對於其Add()Remove()方法,其通知發生了什麼的系統通用把關代碼的自定義後代。類似於暴露在這些方法的內部邏輯被調用之前引發的事件。然後Student類提供委託或什麼東西(抱歉模糊,我今天非常編碼)當實例化_courses應用業務邏輯的事件和取消操作(拋出一個例外,我想象),如果業務驗證失敗。

這也可能是矯枉過正,這取決於開發者的處置。但至少對於像這樣稍微設計一些的東西,您可以獲得單個通用實現,並且可以根據需要隨時添加/刪除業務驗證,而不會中斷更改。

0

我已經做了並對此表示遺憾:更好的選擇是使用不同的類來讀取域對象,而不是用於修改它們的域對象。

例如,使用小心翼翼地守護它的課程擁有豐富的行爲Student域類 - 它不應該揭露他們在所有如果學生對他們負責 - 和StudentDataTransferObject(或ViewModel),提供了一個簡單的列表用於填充接口的課程字符串(或需要ID時的字典)。