设计问题:一个班级的两个角色。首先是实例创建,另一个是类型

时间:2012-04-21 17:11:21

标签: c# design-patterns architecture

考虑这个类图:

 +--------+     * +------------------+ * afraid-of             +------------+
 | Garden |------>|    Animal        |<------------------------| Baby       |
 +--------+       +------------------+                         +------------+
                        ^
                        |
                 +----------+------+
                 |                 |
          +------+------+   +------+-----+
          | Cat         |   | Wolf       |
          +-------------+   +------------+

Animal有两个角色:

  1. 他们将在花园里散步(Class Instance)
  2. 宝宝害怕某些动物(类型)
  3. 宝宝应该保留什么?害怕每只动物的一个例子? (听起来很糟糕的设计) 型号名称? (我总是尽量避免重构)

    如何解决这个问题? (我正在使用C#,我最后才提到它,因为我希望这里有一个通用的,无语言的设计模式或想法)

    由于

3 个答案:

答案 0 :(得分:4)

如果婴儿总是害怕同样的动物,你不必保留任何东西。 你可以有一个方法:

public bool IsAfraid(Animal animal)
{
    return animal is Wolf;
}

如果婴儿在不同的地方和时间害怕不同的动物,你应该让每只动物都有一个属性AnimalType(flag enum)。然后宝宝将拥有属于AnimalType的AfraidOf属性。 然后,检查你是否害怕动物很简单:

bool afraid = this.AfraidOf.HasFlag(animal.AnimalType);

最后,对于模式中的不同类型的关系,您可能应该有不同类型的链接到不同的类(包含,继承,害怕)。

答案 1 :(得分:0)

Baby可以列出他/她害怕的动物名单。我会指定独立的方法来添加和删除列表中的动物因为时间过去可以删除或添加一些动物。可以直接通过属性更改动物列表,但在这种情况下我更喜欢特定的方法。

public class Animal { }
public class Cat : Animal { }
public class Wolf : Animal { }

public class Baby
{
    public List<Animal> ScaryAnimalsList { get; private set; }

    public Baby()
    {
        ScaryAnimalsList = new List<Animal>();
    }

    public void AddAnimalToScaryList(Animal animal)
    {
        ScaryAnimalsList.Add(animal);
    }

    public void RemoveAnimalFromScaryList(Animal animal)
    {
        if (ScaryAnimalsList.Contains(animal))
            ScaryAnimalsList.Remove(animal);
    }

    public bool IsAffraidOf(Animal animal)
    {
        return ScaryAnimalsList.Contains(animal);
    }
}

这是如何使用它

class Program
{

    static void Main(string[] args)
    {
        Cat cat = new Cat();
        Wolf wolf = new Wolf();

        var babyJo = new Baby();
        babyJo.AddAnimalToScaryList(wolf);
        babyJo.IsAffraidOf(wolf);   //true
        babyJo.IsAffraidOf(cat);    //false

        var babySam = new Baby();
        babySam.AddAnimalToScaryList(wolf);
        babySam.AddAnimalToScaryList(cat);
        babySam.IsAffraidOf(wolf);   //true
        babySam.IsAffraidOf(cat);    //true

        var babyBob = new Baby();
        babyBob.IsAffraidOf(wolf);   //false
        babyBob.IsAffraidOf(cat);    //false
    }
}

答案 2 :(得分:0)

另一种选择是为动物添加功能。

public class Animal
{
    public virtual bool EatsSmallChildren { get { return false; } }
}

然后你的宝宝可以检查动物是否可怕,而不是宝宝是否害怕它。

这给你的动物类带来了负担,并引入了一些概念上的耦合,但也非常直观,易于理解和维护。