考虑这个类图:
+--------+ * +------------------+ * afraid-of +------------+
| Garden |------>| Animal |<------------------------| Baby |
+--------+ +------------------+ +------------+
^
|
+----------+------+
| |
+------+------+ +------+-----+
| Cat | | Wolf |
+-------------+ +------------+
动物有两个角色:
- 他们将在花园里散步(类实例)
- 宝宝害怕一些动物(类型)
什么宝宝应该保留?它害怕的每种动物都有一个实例?(听起来像是糟糕的设计)类型名称?(我总是尽量避免重构)
应该如何解决这个问题?(我使用的是 C#,我只在最后提到它,因为我希望这里有一个通用的、无语言的设计模式或想法)
谢谢
寶總是害怕同樣的動物,你不必保留任何東西。你可以有一个方法:
public bool IsAfraid(Animal animal)
{
return animal is Wolf;
}
如果宝宝害怕不同地点和时间的不同动物,你应该让每只动物都有一个属性 动物类型(标志枚举)。然后,婴儿将有一个属性 害怕,类型为动物类型。然后,检查您是否害怕动物很简单:
bool afraid = this.AfraidOf.HasFlag(animal.AnimalType);
最后,对于架构中不同类型的关系(包含、继承、害怕),您可能应该具有不同类型的链接到不同类的链接。
>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
}
}
另一种选择是为您的动物添加功能。
public class Animal
{
public virtual bool EatsSmallChildren { get { return false; } }
}
然后你的宝宝可以检查动物是否可怕,而不是宝宝是否害怕它。
这给你的动物类带来了负担,并引入了一些概念耦合,但也非常直接,易于理解和维护。