我知道有很多理由说明为什么要在另一个对象中构建某个对象。一些思想学派明确说明了以某种方式构建程序的原因,例如: “数据驱动设计”或“域驱动设计”。我仍然是OOP的初学者,而且我常常很难理解为什么一个对象应该被另一个对象包含。有时,我发现自己有一个看起来很棒的物体,然后我发现了一点我意识到,“好吧,现在我必须将放在某个地方?”这背后的推理类似于我决定将文件放在硬盘上的地方吗?
我有几个指导原则:
当你做出这个决定时,你会怎么看?
答案 0 :(得分:3)
嗯,帮助我解决这个问题的一个非常简单的概念就是“有一个”与“是一个”的概念。问问自己,包含对象是包含对象的东西,还是包含对象的东西?如果它是包含对象的东西,则包含是合适的。否则也许你应该看看继承。
狗是动物,有鼻子,所以它是:
class Animal
{
}
class Dog : Animal
{
Nose n;
}
现在这很好用。这种方法的一个“问题”是你紧紧地结合鼻子和狗,所以有时你会看到包含界面指针而不是对象的东西,或者你可能会谷歌“依赖注入”。但正如俗语所说,“有一个”和“一个”通常足够接近政府工作。
早期,只需尝试大量示例,随着时间的推移它将变得自然。如果你最后吃意大利面,扔一些肉丸,然后再试一次! :)
答案 1 :(得分:0)
您还在考虑哪些替代方案?你是在谈论遏制与继承,约翰洛克伍德关于hasA的评论和isA帮助解决了这个问题。
或者你或许正在谈论,遏制与结盟? hasA有各种口味。例如,一个人可能有配偶,但显然不包含配偶。改变配偶和改变鼻子之间存在差异。
您考虑的那种关系:
终生:创造一个没有鼻子的人是否有意义?没有人可以存在鼻子吗?一个人可以在没有配偶的情况下存在吗?这些问题的答案驱动了您选择在Person上进行的操作。可能不需要setNose()方法,虽然我们可能需要一个wipeNose()方法,但我们可能需要一个marry(Person)方法。
基数:一个人有多少鼻子?车辆有多少个车轮和座椅?这个问题的答案决定了数据结构的种类?只是一个参考?一个列表?哈希表?
我发现阅读UML建模很有帮助,特别是类图。这反映了如何有效捕捉各种关系的丰富经验。
答案 2 :(得分:0)
有时,我发现自己有一个 对象看起来很棒,然后我 达到我意识到的地步, “好的,现在我必须把它 某处?“
从上面的句子中,听起来你正试图从下往上设计。多年来我学到的一件事就是自上而下的设计是要走的路。 只有在知道需要使用它的位置后才能编写该类。否则,你最终会编写“看起来很棒”的类,并且包含可能根本没用的代码。