OOP组成

时间:2014-12-10 14:47:56

标签: c# oop composition

我对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);

谢谢:)

3 个答案:

答案 0 :(得分:5)

我更喜欢,

public class Mother : ObservableObject
{
    // ...

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

    // ...
}

答案 1 :(得分:2)

我认为建模有点偏差。 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的类似乎在这一点上是有限的和短视的。女人不一定是母亲,所有人都是孩子。可以想象,有很多功能可以添加到这个系统中。但是遵循相同的构建域的一般过程应该适应这一点。

答案 2 :(得分:0)

假设您有一个类名构建。这个类的构建具有一个称为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()
      {

       }    

    }