Domain Driven Design - Parent child relation pattern - Specification pattern

前端 未结 3 706
清酒与你
清酒与你 2021-01-02 19:23

I was wondering which of the following is considered to be a best practice when dealing with parent child relationships.

1) The following example seems to be a commo

相关标签:
3条回答
  • 2021-01-02 19:42

    I definitely like suggestion number 2, but I think that it misses something important that is found in 3, namely that if a Child object cannot exist without a Parent it should take a Parent object in its constructor. Furthermore the Parent property on the Child class should be read only. So you would end up with something like:

    public class Parent 
    { 
        private ICollection<Child> children; 
    
        public ReadOnlyCollection Children { get; } 
    
        public Child CreateChild() 
        { 
            var child = new Child(this); 
            children.Add(child); 
            return child; 
        } 
    } 
    
    
    public class Child 
    { 
        internal Parent Parent 
        { 
           get; 
           private set; 
        } 
    
        internal Child(Parent parent) 
        { 
           this.Parent = parent;
        } 
    } 
    
    0 讨论(0)
  • 2021-01-02 19:55

    I tend to use option (1) - has always worked well for me. The important thing is not to expose the children collection itself to the outside world - the Parent should be able to mediate all the access. But I'm perfectly happy for a Child to be created elsewhere - I only care about it when it gets added to the Parent, and at this point it can be checked for validity etc. etc.

    I don't understand your specification example: it seems like your ChildSpecification would return true if any of the parent's children has someCondition as true. Surely IsSatisfiedBy(Child child) should only return true if the specific child passed as a parameter satisfied the condition.

    0 讨论(0)
  • 2021-01-02 19:59

    Since I've just encountered the same design desissions and question still not marked as answered I'll post my vision on solution of this problem - maybe it'll help anyone. This solution actually perfectly viable for use with NHibernate.

    public class Parent
    {
        private readonly ISet<Child> _children = new HashedSet<Child> ();
        public virtual IEnumerable<Child> Children { get { return new ImmutableSet<Child> (this._children); }  }
    
    
        protected internal virtual void AddChild (Child child)
        {
            this._children.Add(child);
        }
    }
    
    
    public class Child
    {
        public virtual Parent Parent { get; protected set; }
    
    
        protected Child()
        {
        }
    
    
        public static Create (Parent parent)
        {
            if (parent == null)
                throw new ArgumentNullException ("parent");
    
            var child = new Child
            {
                Parent = parent
            };
    
            child.Parent.AddChild (child);
    
            return child;
        }
    }
    

    That's differs from your #2 option in a way that creation of the child object (and invalidating it's initial values) are gathered withing child object itself and not in parent object as you suggested in #2.

    Tho one thing I'm not sure if it's considered bad design or not if we create child objects with personal factory method (Child.Create).

    I hope someone with more experience in using DDD could comment on that.

    0 讨论(0)
提交回复
热议问题