Я думаю, что моделирование немного не работает. 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
кажутся ограниченными и недальновидными на данный момент. Женщина не обязательно мать, и все люди - дети. Как вы можете себе представить, есть множество возможностей для добавления в эту систему. Но, следуя одному и тому же общему процессу построения такого домена, он должен учитывать это.
Не рожают ли матери детей? – Jodrell
'mother.GiveBirth (new Child());' :) – crashmstr
Возможно, мать предпочла бы, чтобы ребенка не было в ее коллекции! – BenjaminPaul