2010-10-17 64 views
4

我的域模型是這樣的:如何避免域模型中的持久性邏輯?

class Group 
{ 
    private List<Person> persons; 

    public void AddPerson(Person p) { 
     persons.Add(p); 
     DoSideEffect() 
    } 

    public List<Person> GetPersons() {...} 
} 

現在我需要堅持它。通過DDD我不能添加任何持久性屬性到這個類,所以XML序列化器將無法正常工作。由於格式應該可讀,因此無法使用BinaryFormatter。我可以手動調用GetPersons()並堅持它們 - 但我如何加載它們?如果我調用AddPerson(),那麼會有副作用。只有當一個人「真正」被添加到域中時,纔會發生副作用,而不是持久性。

回答

3

我知道這個職位是舊的,但它仍然沒有答案,所以這裏有雲:

這裏的關鍵是,你的模型是有缺陷的,海事組織。

組應該是一個域對象,具有簡單的只讀集合'persons'(members?)。檢索並維持該組的責任屬於GroupRepository,該組加載來自持久性存儲的數據並重新構建該對象。

例如:

public class Group 
{ 
    private Collection<Person> _persons; 

    public Group(Collection<Person> persons) 
    { 
     if (persons == null) 
      throw new ArgumentNullException("persons"); 

     _persons = persons;  
    } 

    public IEnumerable<Person> Persons 
    { 
     get { return _persons; } 
    } 

    public void AddPerson(Person p) 
    { 
     if (p == null) 
      throw new ArgumentNullException("p"); 

     _persons.Add(p); 
     DoSideAffect(); 
    } 
} 

public class GroupRepository 
{ 
    public Group FindBy(Criteria c) 
    { 
     // Use whatever technology (EF, NHibernate, ADO.NET, etc) to retrieve the data 

     var group = new Group(new Collection<Person>(listOfPersonsFromDataStore)); 

     return group; 
    } 

    public void Save(Group g) 
    { 
     // Use whatever technology to save the group 
     // Iterate through g.Persons to persist membership information if needed 
    } 
} 

使用依賴注入框架(Spring.NET,MEF,團結,等等),並創建一個IGroupRepository接口,可以在應用程序代碼注入到檢索並堅持您的組域對象。

0

缺乏屬性不是一個表演阻止者; XmlSerializer有一個構造函數可以在運行時傳入此模型(但說實話,大多數情況下默認值都可以) - 就像其他幾個序列化器一樣。通過XmlSerializer的XML顯然是可取的,如果可讀性是一個問題,但。見XmlAttributeOverrides。我也可以推薦一些可以在這裏工作的二進制串行器。

+0

XmlSerializer如何使用專用字段? – 2010-10-17 19:33:24

+0

@Yaron;啊,不,它不能。 DataConractSerializer *可以*雖然。正如protobuf-net「v2」一樣,如果你不介意二進制。我知道後者支持無屬性模型('我寫了')。 – 2010-10-17 19:36:00

+0

@Yaron - 另一種方法是專用的DTO層。 – 2010-10-17 19:37:36