【问题标题】:Should I instantiate a collection or inherit from collection?我应该实例化一个集合还是从集合继承?
【发布时间】:2010-02-11 07:38:55
【问题描述】:

在创建类时,我曾多次问过自己这个问题,尤其是那些涉及集合的类,但我从来没有想出一个令人满意的答案。这是一个 OOP 设计问题。

例如,在一个支票簿注册程序中说我有一个BankAccount 类。 BankAccounts 包含涉及账户名称、账户类型(Checking、Saving 等的枚举)和其他数据的数据,但最重要的是账户中 Adjustments(存款或取款)的集合.

在这里,我有两个选项来保存调整的集合:

  1. 实例化一个集合并将其作为 BankAccount 类中的一个成员。这就像说“BankAccount 有一系列调整。”
  2. 从集合继承。这就像说“BankAccount 是一个调整集合。”

我认为这两种解决方案都很直观,当然,它们都有一些优点和缺点。例如,实例化允许类(在只允许单个基类的语言中)从另一个类继承,而从集合继承可以轻松控制 Add、Remove 和其他方法,而无需编写代理方法来“包装” '那些。

那么,在这种情况下,哪种方法更好?

【问题讨论】:

标签: language-agnostic oop inheritance class-design


【解决方案1】:

对我来说,银行账户有一系列调整。银行帐户不是调整的集合,因为它“是”远不止这些:它还“是”一个名称和类型等。

因此,就您的情况(以及类似情况)而言,我建议您在班级内聚合一个集合。

如有疑问,请避免继承。 :-)

我可以进一步论证这一点。为了正确使用继承,子类必须满足Liskov's substitution principle;这意味着,在您的情况下,BankAccount 应该是任何预期 Collection 的有效类型。我不认为是这种情况,因为Collection 可能会公开诸如Add() 和Remove() 之类的方法,而您将希望对从您的银行帐户中添加和删除调整进行一些控制,而不是让人们添加和删除随意删除它们。

【讨论】:

    【解决方案2】:

    就个人而言,我会说BankAccount 有一个 Adjustment 集合。它可能还有其他属性,这些属性不仅仅与已存入或提取的内容有关(客户、银行帐户类型等)。

    在设计方面,我的BankAccount 对象将公开Adjustments 类型的延迟加载属性。

    就代码中的使用而言,我会实例化银行账户,如果我需要知道账户进出什么,我会使用暴露的属性。 BankAccount 将是主要对象,负责提供仅与实例化帐户相关的调整。

    【讨论】:

      【解决方案3】:

      实例化,绝对。

      我同意其他关于银行账户“不仅仅是”其他项目集合的海报。 或者,也许您刚刚选择了一个真正为“实例化”而大喊大叫的示例。

      例子:

      • 如果您的银行帐户需要第二次收集完全不同的项目会怎样? (例如:收集可以对它进行操作的人,例如夫妻,例如收集信用卡、paypal 帐户或其他任何可以对您的银行帐户“操作”的东西)。
      • 根据语言,集合会暴露过多的信息:如果另一个对象需要访问 Adjustements...例如在网页上显示您的移动历史记录,您会自动公开您的“集合”以进行注入、删除等操作.

      【讨论】:

        【解决方案4】:

        我认为过度沉迷于诸如“这更多的是 is-a 还是 has-a”这样的语义有点危险 - 归根结底,重要的是您的设计解决问题的能力如何,可维护性如何它是等等。事实上,就我个人而言,我理解面向对象编程方式的一个转折点是放弃“作为名词的对象”。当您深入了解它时,对象是函数的上一级抽象,仅此而已。

        说“有一个”是一个很长的路要走。 :-) 子类化很复杂,使用很简单。

        【讨论】:

        • 好的。我的意思是,诸如“这在概念上看起来更像是一种关系船”之类的元问题是危险的。实用性占主导地位。
        • 我不同意。 :-) 对我(以及我的大多数同事)来说,“元问题”才是最重要的。他们直奔问题的核心,因此他们推动实践。单靠实用性往往会绕过更深层次的问题。一个伟大的开发者能够思考这些更深层次的问题,并在没有意识到的情况下利用他/她的“元”能力,从而获得基于合理理论的伟大实践成果。
        猜你喜欢
        • 1970-01-01
        • 2018-06-01
        • 1970-01-01
        • 2014-08-31
        • 2021-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多