“是一个”vs“有一个”:哪一个更好?

时间:2008-11-04 20:43:48

标签: oop inheritance composition

投资组合A→基金1

投资组合A→基金2

投资组合A→基金3

如果不使用is / has,我无法构建句子。但是1& 2,

1)有一个:

class PortfolioA
{
    List<Fund> obj;
}

2)是:

class PortfolioA : List<Fund>
{

}

从可扩展性,可用性的角度来看,您认为哪一个更好?我仍然可以通过任何方式访问我的资金,尽管有一些小的语法变化。

8 个答案:

答案 0 :(得分:17)

我和其他人一起投票,他们说HAS-A在这种情况下更好。你在评论中提问:

  

当我说投资组合只是一个   收集资金,少数   它自己的属性就像   TotalPortfolio等,这样做   从根本上说不是“is-a”?

我不这么认为。如果您说Portfolio IS-A List<Fund>,那么投资组合的其他属性呢?当然,您可以向此类添加属性,但是将这些属性建模为List的属性是否准确?因为那基本上就是你正在做的事情。

如果要求投资组合支持多个List<Fund>,该怎么办?例如,您可能有一个列表显示当前的投资余额,而另一个列表显示新贡献的投资方式。那么什么时候停止资金,并用一套新资金来取得资金呢?历史信息对跟踪以及当前的资金分配非常有用。

关键是所有这些属性都不是List的正确属性,尽管它们可能是Portfolio的属性。

答案 1 :(得分:8)

不要'总是'赞成作曲或继承,反之亦然;他们有不同的语义(含义);仔细研究这些含义,然后再决定 - 如果一个人比另一个人“更容易”并不重要,因为长寿对你的语义学来说很重要

记住:is-a = type,has-a = containment

所以在这种情况下,投资组合在逻辑上是一组资金;投资组合本身不是类型的基金,因此构成是正确的关系

编辑:我最初误解了这个问题,但答案仍然是一样的。投资组合不是一种列表,它是具有自己属性的独特实体。例如,投资组合是具有初始投资成本,总当前值,随时间变化的历史值等的金融工具的集合,而列表是对象的简单集合。投资组合只是最抽象的一种“列表类型”。

编辑2:考虑投资组合的定义 - 它无一例外地被描述为一系列事物。艺术家的作品集是他们艺术作品的集合,网页设计师的作品集是他们网站的集合,投资者的作品集包括他们拥有的所有金融工具,等等。很明显,我们需要一个列表(或某种类型)来表示投资组合,但这绝不意味着投资组合是一种列表!

假设我们决定让Portfolio继承自List。这一直有效,直到我们向投资组合中添加股票或债券或贵金属,然后突然不正确的继承不再有效。或者假设我们被要求对比尔盖茨的投资组合进行建模,并发现List将耗尽内存;-)更现实地说,在未来的重构之后我们可能会发现我们应该从像Asset这样的基类继承,但是如果我们已经从List继承了然后我们不能。

总结:区分我们选择代表概念的数据结构,以及概念本身的语义(类型层次结构)。

答案 2 :(得分:7)

第一个,因为你应该尽可能地尝试使用组合优于继承。

答案 3 :(得分:4)

这取决于企业是否将投资组合定义为一组(并且只有一组)资金。如果甚至有可能包含其他对象的远程可能性,比如说“属性”,那么请选择选项1.如果一组基金与投资组合的概念之间存在强联系,请使用选项2。

就可扩展性和实用性而言,1比2具有轻微的优势。我真的不同意你应该总是偏爱一个而不是另一个的概念。这实际上取决于实际的现实生活概念。记住,你总是可以^重构。

^总是大多数情况。如果是公开曝光,那么显然不是。

答案 4 :(得分:2)

我会选择(1) - 组合,因为你最终可能拥有特定于投资组合的属性,而不是基金。

答案 5 :(得分:2)

第一个,因为“由”组成。 =&GT;组合物

答案 6 :(得分:1)

我将与看似普遍的看法不同。在这种情况下,我认为投资组合只是一组资金......通过使用继承,您可以使用多个构造函数,如

public Portfolio(CLient client) {};
public Portfolio(Branch branch, bool Active, decimal valueThreshold)
{
    // code to populate collection with all active portfolios at the specified branch whose total vlaue exceeds specified threshold 
}

和索引器如:

public Fund this[int fundId] { get { return this.fundList[fundId]; } }

等。等

如果您希望能够将Portfolio类型的变量视为资金集合,并使用相关语法,那么这是更好的方法。

Portfolio BobsPortfolio = new Portfolio(Bob); 

foreach (Fund fund in BobsPortfolio)
{
    fund.SendStatement();
}

或类似的东西

答案 7 :(得分:0)

IS-A关系船表示继承, HAS-A关系船表示组合。对于上面提到的场景,我们更喜欢组合,因为PortfolioA有一个List而它不是List类型。当Portfolio A是List的一种类型时,继承使用,但在这里它不是。因此,对于这种情况,我们应该更喜欢Composition