8

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

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

所以最后,我被一个具有大型 main 函数、一个类和一些辅助函数的程序所困。不用说,它不是很可重用。

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

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

4

8 回答 8

5

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

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

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

于 2009-07-20T22:40:44.973 回答
3

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

于 2009-07-20T22:42:17.313 回答
1

我发现 TDD Red-Green-Refactor 规则创造了奇迹。

于 2009-07-20T22:46:49.393 回答
1

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

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

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

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

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

于 2009-07-20T22:48:31.433 回答
0

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

尽早考虑 OOP 和重构。这比在所有东西都建成后做要便宜得多。

于 2009-07-20T22:50:34.643 回答
0

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

一旦你得到你的主循环,迅速锁定它,只为修复错误而修改,而不是新功能。这最终可能只是将问题转移到另一个函数上,但无论如何,在基于事件的应用程序中,拥有一个整体函数是相当困难的。你总是需要一百万个小事件处理程序。

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

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

于 2009-07-20T23:50:50.387 回答
0

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

于 2009-07-21T00:12:11.747 回答
0

你的方法不一定是坏的——早期的模块化设计可能最终会过度设计。

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

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

于 2009-07-21T00:12:24.243 回答