1

我知道有很多原因可以让您将某个对象组合到另一个对象中。一些思想流派已经明确说明了以某种方式构建程序的原因,例如“数据驱动设计”或“领域驱动设计”。我仍然是 OOP 的初学者,而且我通常很难理解为什么一个对象应该包含在另一个对象中。有时,我发现自己有一个看起来很棒的对象,然后我意识到,“好吧,现在我必须它放在某个地方?” 这背后的原因是否类似于我决定将文件放在硬盘上的原因?

为此,我有几个指导原则:

  • 如果它模拟了物理世界中的关系。
  • 如果作曲家有构造对象所需的数据。
  • 如果组合对象将听作曲家。

当你做出这个决定时,你会寻找什么?

4

3 回答 3

3

嗯,一个对我有帮助的非常简单的概念就是“有一个”与“是一个”的概念。问问自己,被包含的对象是包含对象的东西,还是包含对象的东西?如果它是包含对象具有的东西,那么包含是适当的。否则,也许您应该考虑继承。

狗是动物,有鼻子,所以它是:

class Animal
{
}

class Dog : Animal
{
    Nose n;
}

现在这工作正常。这种方法的一个“问题”是您将鼻子和狗紧密结合在一起,因此有时您会看到诸如包含接口指针而不是对象之类的东西,或者您可能会在 Google 上搜索“依赖注入”。但俗话说,“有一个”和“是一个”往往对政府工作来说已经足够接近了。

在早期,只需尝试大量示例,随着时间的推移它会变得自然。如果你最后吃到意大利面,扔一些肉丸子再试一次!:)

于 2009-08-30T03:59:08.323 回答
0

您正在考虑哪些替代方案?您是在谈论遏制与继承,John Lockwood 关于 hasA 和 isA 的评论有助于解决该问题。

或者你可能在谈论,遏制与关联?hasA有多种口味。例如,一个人可能有配偶,但显然不包含配偶。换配偶和换鼻子是有区别的。

您考虑的关系类型:

  • Lifetime:创造一个没有鼻子的人有意义吗?没有人,鼻子还能存在吗?一个人可以没有配偶而存在吗?这些问题的答案推动了您选择对 Person 进行的那种操作。可能不需要 setNose() 方法,但也许我们确实需要一个wipeNose() 方法,而且我们可能确实需要一个marry(Person) 方法。

  • 基数:一个人有多少个鼻子?一辆车有多少个车轮和座椅?这个问题的答案决定了数据结构的种类?只是参考?一个列表?哈希表?

我发现阅读有关 UML 建模的知识很有帮助,尤其是类图。这反映了如何有效地捕捉各种关系的许多经验。

于 2009-08-30T20:07:48.697 回答
0

有时,我发现自己有一个看起来很棒的对象,然后我意识到,“好吧,现在我必须把它放在某个地方?”

从上面这句话,听起来你是在尝试自下而上的设计。多年来我学到的一件事是自上而下的设计是要走的路。您应该只在知道需要在哪里使用该类之后才编写该类。否则,您最终只会编写“看起来很棒”的类并且包含可能根本没有用的代码。

于 2009-09-01T12:31:31.810 回答