OOP composition

本文关键字:composition OOP | 更新日期: 2023-09-27 18:33:47

我有一个关于OOP组合的问题。

假设一个母亲有 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);

谢谢:)

OOP composition

我宁愿,

public class Mother : ObservableObject
{
    // ...
    public Child GiveBirth()
    {
        var newBorn = new Child(this);
        this.Children.Add(newBorn);
        return newBorn;
    }
    // ...
}

我认为建模有点不对劲。 MotherChild在语义上彼此相关,但它们是同一对象的实例。 他们都是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进行子类吗? 它在语义上似乎更干净,但是是否有任何特定于男性的操作或属性是女性不共享的? 也许吧,但是我们的模型还没有那么详细。

回过头来看,MotherChild的阶级在这一点上似乎有点有限和短视。 女人不一定是母亲,所有人都是孩子。 可以想象,该系统可以添加许多功能。 但是,遵循像这样构建域的相同一般过程应该可以适应这一点。

假设您有一个类名构建。这个类构建有一个名为 BuildRooms(( 的函数。还有另一个班级房间,具有制作房间的功能。您将类 Room 的对象创建为 r1、r2、r3 等。现在这栋楼有3个房间。我们可以在 Room 类中打开门和关门方法。建筑类由房间组成。这意味着这栋楼有3个房间。用您喜欢的任何语言编写代码。这是构图。建筑有房间,所以它是Has-A关系。

    class building{
    void make_rooms()
    {
        room r1=new room(), r2=new room();
        r1.open();
        r2.close();
    }
}
class room{
    void open()
     {
     }
      void close()
      {
       }    
    }