2010-10-17 12 views
4

Mon modèle de domaine ressemble à ceci:Comment éviter la logique de persistance dans un modèle de domaine?

class Group 
{ 
    private List<Person> persons; 

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

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

Maintenant je dois persister il. Par DDD, je ne peux pas ajouter d'attributs de persistance à cette classe, donc les sérialiseurs xml ne fonctionneront pas. BinaryFormatter ne peut pas être utilisé car le format doit être lisible. Je peux appeler manuellement GetPersons() et les persister - mais comment vais-je les recharger? Si j'appelle AddPerson() alors il y a un effet secondaire. L'effet secondaire devrait seulement arriver quand une personne est "vraiment" ajoutée au domaine, pas avec la persistance.

Répondre

3

Je sais que ce poste est vieux, mais il reste encore sans réponse, donc ici il va:

La clé ici est que votre modèle est défectueux, imo.

Le groupe doit être un objet de domaine avec une simple collection en lecture seule de 'persons' (membres?). La responsabilité de récupérer et de conserver le groupe appartient au GroupRepository qui charge les données de votre magasin de persistance et reconstitue l'objet.

Par exemple:

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 
    } 
} 

Utilisez un cadre d'injection de dépendance (Spring.NET, MEF, unité, etc.) et créer une interface IGroupRepository qui peut être injecté dans votre code d'application pour récupérer et persisteront votre groupe objets de domaine.

0

Le manque d'attributs n'est pas un blocage de présentation; XmlSerializer a un constructeur à passer dans ce modèle lors de l'exécution (mais pour être honnête, la plupart du temps les valeurs par défaut sont bien) - comme tant d'autres sérialiseurs. XML via XmlSerializer est évidemment souhaitable si la lisibilité est une préoccupation cependant. Voir XmlAttributeOverrides. Je peux aussi suggérer des sérialiseurs binaires qui fonctionneraient ici.

+0

Comment XmlSerializer peut-il fonctionner avec des champs privés? –

+0

@Yaron; ah, non, ça ne peut pas. DataConractSerializer * peut * bien. Comme protobuf-net "v2" si cela ne vous dérange pas binaire. Je sais que ce dernier supporte les modèles sans attributs ('cos je l'ai écrit). –

+0

@Yaron - l'autre approche est une couche DTO dédiée. –