代码文件在什么点/范围太大?


36

我发现有很多2-3k线文件,但实际上并没有觉得它们应该那么大。

客观地将源代码文件称为“太大”的最佳标准是什么?源代码文件应具有最大行数吗?


查看代码后,您的同伴会告诉您。 “您不能自己确定这一点,因为您对作者的了解远超出代码本身所说明的。计算机无法告诉您,其原因与无法分辨绘画是否为艺术品的原因相同。因此,您需要另一个具有人类能力的人软件的维护-查看您所写的内容并给出他或她的意见...”
gnat 2012年

某些编译器以前对源代码大小有怪异的限制:最大行长或最大行数。当编译器抱怨时,这是客观的指示,表明代码太大(或者是时候升级了)。
mouviciel 2012年

2
尽可能拆分,但不要破坏文件的完整性。每个文件(或一对头文件/源文件)应始终是一个舍入的整体,而与其他文件的内部实现无关。如果这意味着某些文件将因为它们实现的复杂性而变得很大,那就这样吧。
Ambroz Bizjak 2012年

请注意,复杂度不仅与数字有关,而且与结构有关。例如,我想说明python zen“扁平比嵌套更好”:100个案例的平坦列表比层次结构更简单(您不会记住所有100个案例,但您很容易记得有100个替代方案) 。而“规则”层次结构中的分支结构与其兄弟姐妹具有相同的结构,它比具有不规则子结构的层次结构简单。
Juh_

“那是源代码吗?” “不,那是makefile,源代码在后面的卡车中”。
mckenzm

Answers:


26

作为理想模型,我使用以下标准(与Martin Beckett提出的原理类似,即根据逻辑结构而不是代码行进行思考):

规则1

每个文件一个类(在C ++中:一个类->一个头和一个实现文件)。

规则二

七个被认为是我们的大脑可以同时观察而不会感到困惑的项目数。高于7,我们发现很难对所看到的内容进行概述。因此:每个类的方法不应超过7-10个。具有10个以上方法的类可能太复杂了,您应该尝试将其拆分。拆分是一种非常有效的方法,因为每次拆分一个类时,每个类的复杂度至少降低2倍。

规则三

无法容纳一个或两个屏幕的方法主体太大(我假设一个屏幕/编辑器窗口大约有50行)。理想情况下,您可以在一个窗口中看到整个方法。如果不是这种情况,则只需要向上和向下滚动一点,而不会忘记方法中被隐藏的部分。因此,如果您必须向上或向下滚动一个以上的屏幕来阅读整个方法正文,则您的方法可能太大,您很容易失去概览。

同样,使用私有帮助方法拆分方法可以非常快速地降低方法的复杂度(每次拆分至少减少一半)。如果引入了太多的私有帮助方法,则可以考虑创建一个单独的类来收集它们(如果私有方法比公共方法更多,那么第二个类可能隐藏在主类中)。

将这些非常粗略的估算汇总在一起:

  • 每个源文件最多一个类。
  • 每个课程最多10个公共方法。
  • 每个类最多10个私有方法。
  • 每种方法最多100行。

因此,超过2000行的源文件可能太大,并且开始变得凌乱。

这确实是一个非常粗略的估计,我没有系统地遵循这些标准(特别是因为没有总是足够的时间来进行适当的重构)。而且,正如马丁·贝克特(Martin Beckett)所建议的那样,在某些情况下,类是大量方法的集合,以某种人为的方式拆分它们只是为了减小类而没有意义。

无论如何,以我的经验,当不考虑上述参数之一时,文件开始变得不可读(例如,跨越六个屏幕的300行方法主体,或具有5000行代码的源文件)。


1
我也将争取不超过10行的方法...有助于提高可读性/了解该方法的作用并降低大型方法中容易发生的复杂性...
Zack Macomber

4
如果遵循规则2得出结论,则它是荒谬的。一个目录中的文件不应超过7个,因此必须保持文件较大,以免在项目中的数十个或数百个文件之间感到困惑。同样,深度嵌套的目录结构过于混乱,因此,最好将几个大文件保留在一个目录中,而不是分散所有内容。
哈森

1
抱歉,此答案基于完全任意的指标。“ 7个项目”显然是胡扯,否则您将无法使用字母。对象的大小应基于关注点的分离,单一责任,高内聚-低耦合和类似原理,而不是任意数字。
JacquesB

1
@JacquesB这7个项目通常表示7条无关信息。如果您的大脑可以关联或分组信息,那么从实际意义上讲,如果您想回想一下,那一条信息可以带来更多信息(实际上,“字母”是一个符号,并非全部26个字母)。一个更好的例子是尝试记住在没有笔和纸的情况下通过电话告诉您的7位数字。方法显然不是任意数字,但是如果这些方法与您要编码的内容相关,则可以期望在7点之后,您必须先查找它,然后才能正确调用。
尼尔

3
@Neil:如果类中的方法是随机的,不相关的信息,那么与许多方法相比,类设计中的问题更大。
JacquesB

33

不-不在代码行方面。驱动程序应该是逻辑分组。例如,在一个大文件中当然不应存在多个类

如果您拥有一个合法地拥有数百种方法的类(在3D建模中并非并非不可能),那么将其拆分为任意文件将不那么方便。当内存不足且处理器速度较慢时,我们通常不得不这样做-这很麻烦,不断地寻找函数定义。


2
上百种方法的类难道不是类羡慕,缺乏凝聚力,设计欠佳,违反单一责任原则的症状吗?
图兰斯·科尔多瓦

2
@ user1598390:通常但并非总是如此。
whatsisname 2012年

4
@ user1598390-在gis / 3d建模中很常见,可以执行很多操作,然后将它们重载为2d,3d,4d,3d +信号,然后进行浮点/双精度/整数等操作-模板虽然有所帮助,但提高了效率很多操作通常都比漂亮的阶级体系要好
Martin Beckett

2
@ tp1-您使用的是小字体,因此它们不会占用太多空间?
马丁·贝克特

2
@ tp1 Dude,对不起,我的确并不表示任何不敬,但对于与您一起工作的人,我深感抱歉。如果您有1200个类,请使用目录约定,如果目录太多,请将其拆分为独立的模块/库。
dukeofgaming

8

当其中的代码变得不可维护时。即:您不能仅通过观看代码来判断您要查找的方法/类/函数(必须进行编辑/调试)是否在其中,如果不是,那么在哪里。

但是,您的IDE /编辑器选择和功能将影响此上限的实际量化。代码折叠功能/方法列表和查找推迟此开发方案提出的时间。

但是,当它这样做时,就该拆分它了。


2

这是另一种视图:您正在询问如何限制文件大小。我的观点是,有很多因素使大型代码文件非常有问题。有时,代码文件很大,但是其内容很好地聚集在一起,并且代码非常干净,因此大小不会引起任何重大问题。尽管LOC很高,但我看到了很多可读性很强的文件。

与其利用LOC指标,不如考虑使用历史数据来了解代码在那些大文件中被破坏的频率。通常,这样做的原因是,开发人员没有时间耐心检查同一文件中的其他相关位置,并且在没有足够了解的情况下以“快速修复”的心态进行更改。

更大的危险是复制粘贴代码的存在。复制粘贴编码自然也可以加快LOC的增长。我认为消除复制粘贴比将LOC保持在某个魔幻数字以下更为重要。除了纯复制粘贴外,大文件还存在第二个危险:功能重叠。文件越大,您越有可能最终重新实现同一文件其他部分中已经存在的某些代码段。

因此,只要较大文件的错误修复率(错误修复提交与所有提交的比率)较低,这种情况是可以忍受的。请尝试git log并略过与错误相关的提交次数。或者使用可以自动分析和可视化的工具,例如Softagram


-1

考虑一下Metaphor。关于代码长度,我认为我们应该考虑以下几点:

The Cat in The Hat (50 pp.)

Lord of The Rings (1,178 pp.)

没有错Lord of the Rings。这是一本很棒的书。The Cat in the Hat也是一本好书。两者都可以被5岁的孩子所理解,但是由于内容的原因,只有一个更适合。

就我而言,只要有可能,编写代码对5岁的孩子就有意义。Cyclomatic Complexity是开发人员在生成代码时应考虑的重要概念。利用和创建库以尽可能增强功能和代码可重用性。这样,我们的代码可以说出比我们看到的更多的内容。

我们大多数人不是在编写汇编代码。但是我们代码的根源是汇编。如果正确完成,搜索10000行汇编比10000行python难。

但是有些工作需要写500到1000行。我们使用代码的目标应该是编写300行干净的代码。

作为开发人员,我们要编写“指环王”。直到我们得到一个错误并希望我们写“帽子里的猫”。不要编码来衡量自我。只是使事情以简单的方式工作。

开发人员不想记录代码(我个人喜欢记录的代码,我并不那么自私)。因此,请勿编写只有您能理解/阅读的代码。编写Cat in the Hat代码。

我们都知道您是JRR Tolken(在您的脑海中)。请记住,您将无法通过无错误代码证明任何事情。

隐喻的另一个原因。

不要夸大读者的财富。如果您与一群人一起工作,而所有这些人都必须同时更改一个大文件,那么您很可能会陷入git合并困境。

每个人都喜欢基地。

->从来没有人说过!

TL; DR注重可读性。尽可能地将代码和帮助程序分布在多个行和文件中。不要在单个文件中抛出8或9个类,这会使代码难以阅读且难以维护。如果条件代码或循环较大,请考虑在语言支持的情况下将其更改为Lambda。实用程序功能应被视为增加代码可读性的绝佳途径。避免大量嵌套。


不是低级投票者,但您的类比对我有些迷茫。您是说最好将代码分布在多行上,并且每行上的单词较少吗?
饲料

尽可能地将代码和帮助程序分布在多个行和文件中。注重可读性。不要在单个文件中抛出8或9个类。它使代码难以阅读且难以维护。如果条件代码较大或存在循环。将它们变成实用程序。避免大量嵌套。请让我知道这是否有助于解释。
GetBackerZ

也许您应该将其编辑为答案,因为这样可以使您的意思更清楚。
饲料

我使用Jackie Brown的脚本作为模块化z / OS COBOL程序的准绳。你知道吗,鸡尾酒会
戏ban

“只要有可能,对5岁的孩子就有意义。” -对于付账单的现实问题,这几乎是不可能的,并且针对的是错误的事情
whatsisname
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.