【问题标题】:What functions to put inside a class在类中放入什么函数
【发布时间】:2023-11-02 13:13:01
【问题描述】:

如果我有一个函数(比如 messUp 不需要访问类的任何私有变量(比如 room),我应该像 room.messUp() 那样在类内编写函数还是像 @ 那样在类外编写函数987654324@? 似乎第二个版本对我来说更好读。

【问题讨论】:

    标签: class language-agnostic function encapsulation


    【解决方案1】:

    这里需要权衡取舍。使用成员函数可以:

    • 覆盖派生类中的实现,因此即使在通用房间中没有可用的橱柜,弄乱厨房也可能涉及破坏橱柜。
    • 决定您以后需要访问私有变量,而不必重构使用该函数的所有代码。
    • 使函数成为接口的一部分,这样一段代码可能会要求它的参数是混乱的。

    使用外部函数可以:

    • 使该函数通用,以便您可以将其平等地应用于房间、仓库和石油钻井平台(如果它们提供了搞砸所需的成员函数)。
    • 保持类签名较小,以便为单元测试(或不同的实现)创建模拟版本变得更加容易。
    • 无需检查该函数的代码即可更改类实现。

    没有真正的方法可以让你的蛋糕也吃,所以你必须做出选择。一个常见的 OO 决定是让一切都成为方法(除非显然是愚蠢的)并牺牲后三点,但这并不意味着您应该在所有情况下都这样做。

    【讨论】:

      【解决方案2】:

      任何一类对象的行为都应该写成实例方法。

      所以room.messUp() 是执行此操作的 OO 方式。

      messUp 是否必须访问该类的任何私有成员,这无关紧要,它是房间的一种行为,这表明它是一个实例方法,就像 cleanUppaint 一样,等等……

      【讨论】:

        【解决方案3】:

        忽略哪种语言,我认为我的第一个问题是 messUp 是否与任何其他功能有关。如果你有一组相关的函数,我倾向于把它们放在一个类中。

        如果它们不访问任何类变量,那么您可以将它们设为静态。这样,无需创建类的实例即可调用它们。

        除此之外,我还会关注语言。在某些语言中,每个函数都必须是某个类的方法。

        最后,我认为这不会有太大的不同。 OOP 只是一种帮助组织应用程序数据和逻辑的方法。如果你接受它,那么你会选择 room.messUp() 而不是 messUp(room)。

        【讨论】:

        • -1 表示“如果你接受它”......如果你使用的是 OO 语言,在任何专业环境中都应该强制按照预期使用它,而不是随心所欲个人。这就是我们最终遇到编码恐惧的方式。
        • 如果您阅读他的评论,您会发现他并没有说他使用的是面向对象语言。他只是问哪个更好,不管那是什么意思。此外,像 C++ 这样的语言通常具有不是类成员的函数。作为一个纳粹分子,人们对发展采取的方法没有任何客观目的。所以这对你来说是两个错误的......
        • @Jonathan,戈德温斯定律 -1,以及在 OP 的问题中使用的缺少关键词。 ...“访问类的任何私有变量”什么非 OO 语言在类中使用私有变量? (甚至有课程?!?令人难以置信。) - 现在,我不会不同意即使是 OO 系统中的函数也经常有很好的用途/原因,这些函数的行为方式与 messup(room) 的行为方式相同。 .. 1. 因为它对我来说似乎更好读; 2.因为觉得喜欢,都不是很好的理由。但更糟糕的是 3。因为我不想在 OO 语言中接受封装。
        • @Slomojo:VB6 有课程,但没有正式成为面向对象的语言。无论如何,看起来你的任务是把你的想法强加给别人,所以我会在这里停下来。继续……
        • @Johnathan... OOP 和封装不是我的想法。
        【解决方案4】:

        我以 Sutter 和 Alexandrescu 的 "C++ Coding Standards: 101 Rules, Guidelines, And Best Practices" 以及 Bob Martin 的 SOLID 为基础。我当然同意他们的观点;-)。

        如果消息/函数与你的类没有太多的交互,你应该把它变成一个标准的普通函数,以你的类对象作为参数。

        你不应该用与你的班级没有密切关系的行为来污染你的班级。 这是为了尊重Single Responsibility Principle:你的课程应该保持简单,瞄准最精确的目标。

        但是,如果您认为您的消息/函数与您的对象内脏密切相关,那么您应该将其作为您的类的成员函数。

        【讨论】: