【问题标题】:Overcoming bad habit of "fixing it later"克服“稍后修复”的坏习惯
【发布时间】:2010-11-12 11:36:53
【问题描述】:

当我从头开始编写代码时,我养成了在一个函数中快速编写所有内容的坏习惯,一直在想“我以后会使其更加模块化”。然后当后来出现时,我有一个工作产品,任何修复它的尝试都意味着创建函数并且必须弄清楚我需要通过什么。

情况变得更糟,因为当您的项目快要完成时,重新设计类变得极其困难。例如,我通常在开始编写代码之前做一些计划,然后当我的项目完成后,我意识到我可以让类更加模块化和/或我可以使用继承。基本上,我认为我没有做足够的计划,而且我没有得到超过一级的抽象。

所以最后,我遇到了一个程序,它有一个大的主函数、一个类和几个辅助函数。不用说,它不是很可重用。

有没有人遇到过同样的问题并且有什么技巧可以解决这个问题?我想到的一件事是用伪代码编写主函数(没有太多细节,但足以看到他们需要什么对象和函数)。本质上是一种自上而下的方法。

这是个好主意吗?还有其他建议吗?

【问题讨论】:

  • 我最近问了一个关于项目规划的类似问题,但我们的问题略有不同。也许那里的一些答案可能对您有用。 stackoverflow.com/questions/1100819/…
  • 我用巧克力犒赏自己。

标签: c++ code-reuse modularity


【解决方案1】:

“首先我们养成习惯,然后习惯塑造我们。”

这似乎适用于好习惯和坏习惯。听起来像一个坏人抓住了你。

提前练习更加模块化,直到它“就像我做事的方式一样”。

【讨论】:

    【解决方案2】:

    是的,解决方案很简单,尽管需要时间来适应它。 永远不要声称会有一个“稍后”,您可以坐下来进行重构。相反,继续向您的代码(或测试)添加功能,并在此阶段执行小的增量重构。 “后来”基本上是“总是”,但隐藏在你实际上每次都在做新事情的阶段。

    【讨论】:

      【解决方案3】:

      我发现 TDD Red-Green-Refactor 规则非常有效。

      【讨论】:

        【解决方案4】:

        我的经验法则是任何超过 20 LoC 的东西都应该是干净的。 IME 每个项目都基于一些“只是一个概念验证”,这些“只是一个概念验证”从未打算最终出现在生产代码中。由于这似乎是不可避免的,即使是 20 行概念验证代码也应该是清晰的,因为它们最终可能成为一个大项目的基础之一。

        我的方法是自上而下。我写

        while( obj = get_next_obj(data) ) {
          wibble(obj);
          fumble(obj);
          process( filter(obj) );
        }
        

        以后才开始编写所有这些函数。 (通常它们是inline 并进入未命名的命名空间。有时它们会变成单行,然后我可能会稍后将它们删除。)

        这样我也避免了对算法进行评论:函数名称已经足够解释了。

        【讨论】:

          【解决方案5】:

          您几乎确定了问题所在。没有足够的计划。 花一些时间分析您将要开发的解决方案,将其分解为功能块,确定实现它们的最佳方式并尝试分离应用程序的各个层(UI、业务逻辑、数据访问层等) )。

          尽早从 OOP 的角度进行思考并进行重构。比一切都建好后再做要便宜很多。

          【讨论】:

            【解决方案6】:

            尽量少写main函数,里面几乎什么都没有。在大多数 gui 程序、sdl 游戏程序、open gl 或任何具有任何类型用户界面的程序中,主要功能应该只是一个事件吃循环。必须如此,否则在很长一段时间内计算机似乎没有响应,并且操作系统认为可能会因为没有响应消息而考虑将其关闭。

            获得主循环后,请迅速将其锁定,仅针对错误修复进行修改,而不是新功能。这最终可能只是将问题转移到另一个函数,但是无论如何在基于事件的应用程序中很难实现一个整体函数。你总是需要一百万个小事件处理程序。

            也许你有一个单一的类。我已经做到了。主要处理它的方法是尝试保持依赖关系的心理或物理映射,并注意存在的位置......比方说,一组函数不明确依赖于任何共享状态或变量的穿孔,裂缝类中的其他功能。在那里,您可以将该功能集群分离到一个新类中。如果它真的是一个巨大的类,并且真的很纠结,我会称之为代码气味。考虑重新设计这样的东西,使其变得不那么庞大和相互依赖。

            您可以做的另一件事是在编码时,请注意,当函数增长到不再适合单个屏幕的大小时,它可能太大了,此时开始考虑如何打破它分解成多个更小的函数。

            【讨论】:

              【解决方案7】:

              如果你有好的工具,重构就不会那么可怕了。我看到您将您的问题标记为“C++”,但任何语言都是如此。获取一个易于提取和重命名方法、提取变量等的 IDE,然后学习如何有效地使用该 IDE。然后,Stefano Borini 提到的“小型增量重构”就不会那么令人生畏了。

              【讨论】:

                【解决方案8】:

                您的方法不一定是坏事——早期的模块化设计可能会导致过度设计。

                您确实需要重构——这是不争的事实。问题是什么时候?为时已晚,重构任务太大,风险太大。太早了,可能是过度设计。而且,随着时间的推移,您将需要再次重构......一次又一次。这只是软件自然生命周期的一部分。

                诀窍是尽快重构,但不要太快。经常,但不是太频繁。多快和多频繁?这就是为什么它是一门艺术而不是一门科学:)

                【讨论】:

                  猜你喜欢
                  • 2010-10-16
                  • 1970-01-01
                  • 2010-11-14
                  • 2023-01-24
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-09-17
                  • 1970-01-01
                  相关资源
                  最近更新 更多