组成特定对象的激励因素?

时间:2009-08-30 02:39:02

标签: oop architecture domain-driven-design composition

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

我有几个指导原则:

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

当你做出这个决定时,你会怎么看?

3 个答案:

答案 0 :(得分:3)

嗯,帮助我解决这个问题的一个非常简单的概念就是“有一个”与“是一个”的概念。问问自己,包含对象是包含对象的东西,还是包含对象的东西?如果它是包含对象的东西,则包含是合适的。否则也许你应该看看继承。

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

class Animal
{
}

class Dog : Animal
{
    Nose n;
}

现在这很好用。这种方法的一个“问题”是你紧紧地结合鼻子和狗,所以有时你会看到包含界面指针而不是对象的东西,或者你可能会谷歌“依赖注入”。但正如俗语所说,“有一个”和“一个”通常足够接近政府工作。

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

答案 1 :(得分:0)

您还在考虑哪些替代方案?你是在谈论遏制与继承,约翰洛克伍德关于hasA的评论和isA帮助解决了这个问题。

或者你或许正在谈论,遏制与结盟? hasA有各种口味。例如,一个人可能有配偶,但显然不包含配偶。改变配偶和改变鼻子之间存在差异。

您考虑的那种关系:

  • 终生:创造一个没有鼻子的人是否有意义?没有人可以存在鼻子吗?一个人可以在没有配偶的情况下存在吗?这些问题的答案驱动了您选择在Person上进行的操作。可能不需要setNose()方法,虽然我们可能需要一个wipeNose()方法,但我们可能需要一个marry(Person)方法。

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

我发现阅读UML建模很有帮助,特别是类图。这反映了如何有效捕捉各种关系的丰富经验。

答案 2 :(得分:0)

  

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

从上面的句子中,听起来你正试图从下往上设计。多年来我学到的一件事就是自上而下的设计是要走的路。 只有在知道需要使用它的位置后才能编写该类。否则,你最终会编写“看起来很棒”的类,并且包含可能根本没用的代码。