代码应该有多复杂?

39
我正在学习关于可以帮助我编写更小但更复杂的代码的算法。 我可以设计一个算法来执行150行的if-else语句,只需要20行。 问题是许多这些算法可能很复杂,并且需要很多数学知识才能理解它们。 而且我是唯一一个理解这些算法的人。

为了保持代码的可维护性,是按照其他人的方式编写代码更好,还是使用算法更好呢?


1
一个例子会很有帮助。 - Sam
8
“150行的if-else语句”,这本身就太复杂了。 - Patrik Hägne
我觉得这个问题演变成了更加普遍的形式,但对于我的情况来说。 - danmine
一个用于驱动电机的接口。一种方式是编写大量if-else语句,以检查先前的状态、当前的状态以及更早之前的状态。另一种方法是使用大学教材上的PID公式。还有一种折中的办法,可以改善if-else代码。 - danmine
+1 对于机械工程师来说,PID控制器非常重要 :) 注意:您还可以对系统进行特征化和更好的控制。 - ccook
显示剩余3条评论
28个回答

55

正如爱因斯坦所说:

使一切尽可能简单,但不要过于简化。

这同样适用于代码和物理学。

凭借您的判断力 - 它是否更易于维护?通常通过将大量的if/else混乱转化为更简洁的形式,您可以消除其中不必要的情况,从而避免未来可能会出现的错误。当然,将一组清晰的条件转化为只有偶然起作用的布尔逻辑的晦涩曲折,可能会使事情变得更加难以维护,尤其是在某些情况下发生改变时。

编辑:
您提到的情况,如果公式能够工作,则可能是更好的选择-您甚至可以留下引用来源的评论。当然,也有可能公式以前存在,但被删除以便绕过某个特定的案例。这就是版本控制存储库中的注释应该起到帮助作用的地方。

由于还没有人发布链接,这里是他所指的PID算法的描述。


6
如果公司里没有其他人能够理解这个公式,那么现在可能是使用“// Magic. Do not touch.”注释的合适时间。 - Spencer Ruport
实际上,如果你在一家从事嵌入式系统工作的公司,而没有其他人理解PID环路,那么是时候更新你的简历并开始寻找更好的公司了! - Huntrods
所以,“让一切只变得像它需要的那样复杂,但不要更复杂”。 ;) - Don Music
很棒的引用。你比我早几个小时就做到了。 - Jon Ericson
3
不,Spencer,现在是使用“这段代码很复杂。以下是它应该如何运作”的注释,以便他人在代码审查中确认。如果你不能向别人解释清楚,那么你可能并没有像你想象的那样理解这段代码。 - Rob Kennedy
显示剩余2条评论

27
Code只需要写一次,但要阅读十次。因此,您应该尽可能使其易于理解。
此外,调试比编写代码要困难得多。那么,在您已经将所有脑力投入编写复杂代码时,如何调试您的代码呢?
只需遵循软件开发的三大定律
  1. 开发人员必须编写创造价值的代码。
  2. 开发人员必须使他们的代码易于维护,除非这样的支出会与第一条法则冲突。
  3. 开发人员必须将其代码缩小到最小的大小,只要这种缩小不与前两个法则冲突即可。

26

罗伯特·C·马丁将这个漫画用作他的书《代码整洁之道》的引言:

The only valid measurement of code quality: WTFs/minute
(来源:osnews.com)


14

请记住,代码应该主要为人类所理解...编译器会负责让计算机理解。


11

"复杂"的级别可能有些棘手,但只要算法不需要数学博士解决,

我建议使用这些算法。请确保对算法名称进行适当的文档说明,可能还要提供算法如何工作的简短描述或指向相关文档的参考。

这将减少代码量,希望能提高应用程序的性能,并有望鼓励你周围的一些程序员学习新事物,并加入他们的技能库中。此外,总会有可能后来出现懂得这些内容的程序员。


10

优秀的引言....

任何傻瓜都能写出计算机能够理解的代码。优秀的程序员编写能够被人类理解的代码。

  • Martin Fowler

8

我无法相信有人认为150行的代码比20行的代码更简单。

采用20行代码,并按以下方式保护您的同事:

  • 记录每个数据结构不变量和每个非平凡循环不变量。这些记录不是在注释中,而是在实际检查不变量的代码中进行。可以在生产过程中关闭检查。

  • 如果在代码中使用数学公式或通过数学公式推导,则在注释(或静态字符串)中包含参考文献。最好包括两个参考文献:一个网络参考文献,在几秒钟内可能会得到;一个知名的教科书,可能会长期保持印刷状态并在大学图书馆中找到。

如果理解您的代码需要特殊的专业知识(如部分微分方程,物理学学位,伽罗瓦理论等),那么为了保护自己,您可能希望去找管理层并说“我有这种特殊的专业知识,可以编写更小(因此更快,更可靠和更易于维护)的代码,但当你不得不替换我时,你需要雇佣具有类似专业知识的人。你想让我怎么办?“如果您能告诉管理层这样的专业知识可以轻松地获得,那将是有帮助的。例如,许多拥有工程学位的人可以学习部分微分方程,但伽罗瓦理论家却很少。

附:以下是来自个人项目的示例注释,以便稍后调试自己的代码:

/* 
 * Compute the position of a point partially along the geodesic from 
 * pt1.lat,pt1.lon to pt2.lat,pt2.lon
 * 
 * Ref: http://mathworld.wolfram.com/RotationFormula.html
 */

3
我认为在评论中引用参考资料的潜在用处被严重低估了。 - Eclipse

6
尽可能复杂,但不要过度。

6
这真的取决于“复杂”意味着什么。如果您的“简单”算法是150行几乎相同的代码,我的眼睛会变得模糊,我就看不懂了。但如果您把这些条件放入矩阵或其他东西中,那么您的代码将变成一个循环来读取矩阵并做出决策,即使该循环可能比一堆if/else语句更“复杂”,我也会更好地理解它。
如果您基本上正在谈论一个Perl程序,其中您在一行中完成所有操作,并大量使用默认变量$_,我会建议您坚持使用更长、更详细的版本。
如果有一种被接受的公式可以做某件事,那么您可以使用这种方式。如果有一个简单的代数公式需要3或4行,而有一个复杂的微分方程只需要一行,那么您应该使用简单的代数公式。在评论中提到的情况中,我认为PID算法比150行if/else代码更“简单”。我认为您并不是在使用算法来掩盖任何内容,而是在使用问题域中的标准技术。只需确保对其进行良好的注释,甚至可能包括指向描述该公式的网页的链接即可。

5
寻找一百行if/else语句的正确路径往往比花同样的时间理解更好的算法(应该在评论中解释或链接)并最终验证实现的20行确实执行那个算法对于维护者的耐力来说更加困难(据我所见)。 它还有教育工作的好处,使得工作更有趣(在积极意义上),而且通常也更好地执行(使用的资源更少)。
你应该避免的聪明之处是“聪明的黑客技巧”,它滥用语言而没有实际益处。 你应该拥抱的聪明之处是始终使用最佳算法来完成工作。
编辑:关于PID示例:我很难想象一个PID的功能可以被一堆if-else语句合理地替代。 if-else解决方案将始终工作得更差(转换不够平滑),非常难以维护,并且非常难以调整(调整PID部分非常重要以获得所需的行为)。 我想补充说明,即使您不知道数学,理解PID也不太难,这可以轻松查找。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接