2014-12-10 2 views
3

У меня вопрос относительно состава ООП.Состав ООП

Предположим, что у матери есть 0 или плюс дети, а у ребенка есть одна и только одна биологическая мать.

Чтобы проиллюстрировать это, я сделал следующее:

public class Mother : ObservableObject 
{ 
    // [...] 

    ObservableCollection<Child> Children {get; set;} 
} 

public class Child : ObservableObject 
{ 
    public Child(Mother mother) 
    { 
     this.Mother = mother; 

     // Adding the child to the mother's children collection 
     mother.Children.Add(this); 
    } 

    public Mother Mother {get; set;} 
} 

, но мне интересно, если это хорошо для автоматического добавления ребенка в коллекцию матери, или если я должен идти со следующим:

Mother mother = new Mother(); 

Child child = new Child(mother); 
mother.Children.Add(child); 

Спасибо :)

+0

Не рожают ли матери детей? – Jodrell

+2

'mother.GiveBirth (new Child());' :) – crashmstr

+0

Возможно, мать предпочла бы, чтобы ребенка не было в ее коллекции! – BenjaminPaul

ответ

5

Я бы предпочел,

public class Mother : ObservableObject 
{ 
    // ... 

    public Child GiveBirth() 
    { 
     var newBorn = new Child(this); 
     this.Children.Add(newBorn); 
     return newBorn; 
    } 

    // ... 
} 
+0

Вы были на секундах быстрее :) Я могу согласиться, я видел этот подход в большом количестве библиотек и проектов Java/.NET. – Gerino

+0

Согласен. Помещение в конструктор означает, что у матери всегда есть ребенок. Использование выделенного метода домена является более чистым, и теперь у матери есть только ребенок, если она действительно хочет :) Однако, если ребенок обязателен для матери, существует конструктор - это путь! –

+0

Я признаю, что я не думал об этом варианте, спасибо! – SeaSharp

2

Я думаю, что моделирование немного не работает. A Mother и Child семантически связаны друг с другом, но они являются экземплярами одного и того же объекта. Они оба являются Person.

Создание Person - операция, выполняемая Person. Таким образом, Person не должен иметь даже публичного конструктора, а скорее фабричный метод, который позаботится об этой логике. Что-то вроде этого:

public class Person : ObservableObject 
{ 
    private Person() 
    { 
     Children = new ObservableCollection<Person>(); 
    } 

    public Person Mother { get; private set; } 
    public ObservableCollection<Person> Children { get; private set; } 

    public Person Procreate() 
    { 
     var child = new Person(); 
     child.Mother = this; 
     this.Children.Add(child); 
     return child; 
    } 
} 

Это моделирование по-прежнему немного ограничено, например, мы говорим о бесполезном воспроизведении здесь. Поэтому мы пока еще не моделируем людей. Может, нам нужно добавить отца?

public class Person : ObservableObject 
{ 
    private Person() 
    { 
     Children = new ObservableCollection<Person>(); 
    } 

    public Person Mother { get; private set; } 
    public Person Father { get; private set; } 
    public ObservableCollection<Person> Children { get; private set; } 

    public Person Procreate(Person father) 
    { 
     var child = new Person(); 
     child.Mother = this; 
     child.Father = father; 
     this.Children.Add(child); 
     father.Children.Add(child); 
     return child; 
    } 
} 

Мы хотим добавить некоторую проверку нулей и того, что, конечно, нет. Теперь мы также обнаружили, что нам нужно указывать гендерные группы. (В то время как семейные структуры могут значительно различаться, действие создания человека довольно хорошо установлено.) Таким образом, мы можем продолжать добавлять такие функции. В какой-то момент мы действительно можем подклассифицировать их, но эти подклассы, скорее всего, станут в основном семантическими сквозными объектами с жестко закодированными значениями по умолчанию для этого Person суперкласса.

Но просто для удовольствия, давайте попробуем их добавить ...

public class Person : ObservableObject 
{ 
    private Person(Sex gender, Person mother, Person father) 
    { 
     // TODO: Check for null mother and father 
     this.Gender = gender; 
     this.Mother = mother; 
     this.Father = father; 
     Children = new ObservableCollection<Person>(); 
    } 

    public Sex Gender { get; private set; } 
    public Person Mother { get; private set; } 
    public Person Father { get; private set; } 
    public ObservableCollection<Person> Children { get; private set; } 

    public Person Procreate(Person father) 
    { 
     // TODO: Check for null father, confirm gender of father 
     var child = new Person(PickRandomGender(), this, father); 
     this.Children.Add(child); 
     father.Children.Add(child); 
     return child; 
    } 

    private Sex PickRandomGender() { /.../ } 

    public enum Sex 
    { 
     Female, 
     Male 
    } 
} 

Хорошо, это было весело. Убрал немного, переместив некоторую логику в конструктор. Но теперь есть еще одна проблема ... отцы могут размножаться. Это звучит как больно. Теперь, похоже, мы готовы к подклассу:

public class Person : ObservableObject 
{ 
    protected Person(Sex gender, Person mother, Person father) 
    { 
     // TODO: Check for null mother and father 
     this.Gender = gender; 
     this.Mother = mother; 
     this.Father = father; 
     Children = new ObservableCollection<Person>(); 
    } 

    public Sex Gender { get; private set; } 
    public Person Mother { get; private set; } 
    public Person Father { get; private set; } 
    public ObservableCollection<Person> Children { get; private set; } 

    protected Sex PickRandomGender() { /.../ } 

    public enum Sex 
    { 
     Female, 
     Male 
    } 
} 

public class Woman : Person 
{ 
    // TODO: Override Gender with a hard-coded value 

    public Person Procreate(Person father) 
    { 
     // TODO: Check for null father, confirm gender of father 
     var child = new Person(PickRandomGender(), this, father); 
     this.Children.Add(child); 
     father.Children.Add(child); 
     return child; 
    } 
} 

(Если мы подклассы Man, а это семантический кажется чище, но есть какие-либо операции или атрибуты, специфичные для мужчин, которые не разделяют женщинами? Возможно, но наши модели еще не все детали.)

Оглядываясь назад, классы Mother и Child кажутся ограниченными и недальновидными на данный момент. Женщина не обязательно мать, и все люди - дети. Как вы можете себе представить, есть множество возможностей для добавления в эту систему. Но, следуя одному и тому же общему процессу построения такого домена, он должен учитывать это.

+0

@ J.Steen: А как насчет них? Эти пары не * создают * ребенка, они его принимают. Мы пока не моделируем семейные структуры, а только физический акт создания ребенка. Это очень хорошо зарекомендовавшая себя и широко известная операция. – David

+0

Спасибо за ваш очень подробный ответ и объяснения :) – SeaSharp

+0

@ J.Steen: Модель домена довольно широка в это время, я согласен. Есть * много * функций, которые нужно добавить. Черт, мы можем даже говорить о клонировании как о возможной операции. Но если это не поддерживается бизнес-моделью, то это просто золотое покрытие. Для чего это стоит, я ответил на аналогичный вопрос (с точки зрения модели данных, а не на перспективу модели домена): http://stackoverflow.com/a/22114472/328193 – David

Смежные вопросы