【问题标题】:More vs Less Functions更多与更少的功能
【发布时间】:2009-10-14 03:40:26
【问题描述】:

我有一点争论,想知道外面的人是怎么想的:

在 C++(或一般情况下)中,您是否更喜欢将代码分解为许多较短的函数,main() 仅按逻辑顺序由函数列表组成,还是仅在必要时更喜欢函数(即,什么时候它们会被重复使用很多次)?或者可能介于两者之间?

【问题讨论】:

  • "...或者您只在必要时更喜欢函数?"严格来说,它们从来没有必要。它们只是让代码更易于维护。
  • 另外,Chris 提出了一个很好的观点。将您的必要性谓词更改为“阅读越来越困难”,您的状态就很好了。

标签: c++ function preferences


【解决方案1】:

小函数,拜托

传统观点认为函数越小越好,我认为这是真的。事实上,有一家公司有一个分析工具,可以根据他们做出的决策数量与他们拥有的单元测试的数量相比,对各个功能进行评级。

理论上,您可能会也可能不会降低整个应用程序的复杂性,但您可以完全控制任何给定函数的复杂性。

一种名为 cyclomatic complexity 的度量被认为与不良代码正相关...具体而言,通过方法的路径越多,其 CCN 数越高,编写得越差,越难理解并因此改变甚至正确开始,它需要的单元测试就越多。

好的,找到工具了。它被称为,咳咳,Change Risk Analysis and Predictions index。

最近,信息只编码一次的原则出现了新的首字母缩略词,特别是DRY (Don't Repeat Yourself) and DIE (Duplication is Evil) ... 我相信我们可以部分感谢RoR 社区推广这一理念...

【讨论】:

  • 这种分析称为圈复杂度。 en.wikipedia.org/wiki/Cyclomatic_complexity
  • 嘿,我只是在输入...并寻找测量工具
  • 是的。独立于该分析,我在 20 多年前发现大型函数对于普通人来说是非常难以理解、编写和维护的。所以我的经验法则是,如果一个函数太长以至于以清晰的字体打印它不适合在信纸大小的纸上,它需要被分解。当然也有例外。
【解决方案2】:

拆分功能,但绝不拆分功能。

功能可以分为层,然后每一层又可以拆分成不同的功能。例如,当我们处理sine series 时,求和和减法的主循环应该在主函数中。这可以认为是第 1 层。现在,用于查找功率的功能可以分类到第 2 层。这可以作为子功能来实现。同样,寻找阶乘也属于第 2 层,这将是另一个子功能。始终考虑功能,从不计算行数。行数可能从 3 到 300 不等,没关系。这将为我们的代码增加更多的可读性和可维护性。这就是我关于分裂的想法。

【讨论】:

    【解决方案3】:

    我认为唯一的答案是介于两者之间。如果你尽可能地分解函数,它就会变得不可读。同样,如果你从不分手,它也会变得不可读。

    我喜欢将函数分组为语义差异。它是某种计算的一个逻辑单位。保持单位小,但大到足以实际做一些有用的事情。

    【讨论】:

    • 这也是 Eric Raymond 在“Unix 编程的艺术”中提出的观点
    【解决方案4】:

    我最喜欢的函数粒度经验法则是“不超过 24 行,每行

    【讨论】:

    • @mgb,当然,还有 一对 Perl 中的应用程序,其中简洁性比可读性更值得称赞;-) -- 但是,这就是次要规则的用武之地 -- “只有一个[功能/角色/目的]”。
    【解决方案5】:

    小功能好,小功能好。

    大约五到八行代码是我对函数大小的上限。除此之外,它太复杂了。您应该能够:

    1. 假设被调用者按照其名称的含义行事,
    2. 在几秒钟内读取函数的定义,并且
    3. 快速说服自己,第一个假设意味着当前函数是正确的。

    另一件事是您应该在编写代码之前使用您的函数。当您了解您打算如何使用该功能时,您就会看到该功能必须遵守哪些前置条件和后置条件。

    任何乍看之下明显不正确的内容都应在运行评论中证明是正确的。如果这很困难,请排除子功能。

    【讨论】:

      【解决方案6】:

      我相信任何有助于代码重用和可读性的方法都是最好的。

      仅仅为了实现它而制作大量单行函数并无助于提高可读性,因此应将它们分组到有意义的类中,然后拆分函数,以便您可以快速了解该函数中发生了什么。

      如果你必须跳过去才能理解发生了什么,那么你的设计就有缺陷。

      【讨论】:

        【解决方案7】:

        我更喜欢适合一屏代码的函数(或方法),因此我可以一眼看出我需要参考的任何内容,以了解该函数的工作原理。我的编辑器窗口中通常有大约 50 行空间,通常也有 80 列,因此我可以在监视器上并排放置两个空间,并在两段代码之间进行交叉引用。

        所以,我通常认为 50 行大约是最大值。我唯一会考虑允许更多的情况是当你有一个大的长初始化函数或完全线性的东西(没有变量、条件或循环)时,因为这不是你需要那么多上下文的东西,而某些 API 需要一个整体一堆初始化来启动和运行,并将其拆分为更小的函数并没有太大帮助。

        不过,总体而言,漂亮、小巧、易于理解、只做一件事且命名良好的函数要远优于庞大的庞然大物,后者有数百行长,需要跟踪数十个变量,缩进为 10层次深。

        【讨论】:

          【解决方案8】:

          另一个简单的原因:当一个代码块被重复使用一次或两次以上时,应该创建一个函数。对于非常小的代码(比如一两条语句),宏通常可以缓解这个问题。

          【讨论】:

            猜你喜欢
            • 2014-01-20
            • 2015-09-05
            • 1970-01-01
            • 1970-01-01
            • 2011-12-25
            • 2011-09-30
            • 2019-04-17
            • 2015-12-12
            • 2020-06-02
            相关资源
            最近更新 更多