How to avoid persistence logic in domain model?
My domain m开发者_如何学运维odel looks like this:
class Group
{
private List<Person> persons;
public void AddPerson(Person p) {
persons.Add(p);
DoSideEffect()
}
public List<Person> GetPersons() {...}
}
Now I need to persist it. By DDD I cannot add any persistence attributes to this class so xml serializers will not work. BinaryFormatter cannot be used since the format should be readable. I can manually call GetPersons() and persist them - but how am I going to load them back? If I call AddPerson() then there is a side effect. The side effect should only happen when a person is "really" added to the domain, not with persistrancy.
I realize this post is old but it still remains unanswered, so here it goes:
The key here is that your model is flawed, imo.
Group should be a domain object with a simple read-only collection of 'persons' (members?). Responsibility for retrieving and persisting the Group belongs to the GroupRepository which with load the data from your persistence store and reconstitute the object.
For example:
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
}
}
Use a dependency injection framework (Spring.NET, MEF, Unity, etc.) and create an IGroupRepository interface which can be injected in your application code to retrieve and persist your Group domain objects.
Lack of attributes isn't a show-stopper; XmlSerializer has a constructor to pass in this model at runtime ( but to be honest, most times the defaults are fine) - as so several other serializers. XML via XmlSerializer is obviously desirable if readability is a concern though. See XmlAttributeOverrides. I can also suggest some binary serializers that would work here.
精彩评论