开发组织都会有代码规范。当我拿到一份代码规范,首先会去查看有没有对于单个函数最大行数做限制。如果没有这个最基本的约定,这份代码规范,在我看来几乎没有意义。
以Java为例,一个函数不应超过多少行呢?
大多数人都会说,函数不能太长,但也不能定死,要具体问题具体分析。再追问一下,有人会说,不超过200行,100行,50行,30行都有。另有人说,面向对象风格的可以短些,面向过程风格的可以长些。也有人说,一个方法不超过一屏幕就行(姑且不论显示器大小,字体大小和分辨率问题)。
先摘录一段Martin Fowler《重构》P110-P111 中的一段话:
引用
人们有时会问我,一个函数多长才合适?在我看来,长度不是问题,关键在于函数名称和函数本体之间的语义距离(semantic distance)。如果提炼动作(extracting)可以强化代码的清晰度,那就去做,就算函数名称比提炼出来的代码还长也无所谓。
说了直白点,函数名是干什么,函数体是怎么干。当2者不是那么能容易分辨出来时,就需要提炼出函数来,让代码更好懂。
既然马大师都说了,长度不是问题了吗,那干吗还要追究函数长度规范呢?
其实马大师讲的是对于懂得编程之道的人而言,不用关心长度,因为小函数是必然的结果。但在开发实践中,适当的函数长度限制值,可以给予我们警示,为什么这个方法写长了?哪里不对劲了?
对于这个问题我的回答是:Java函数不应超过15行。
为什么定这个数呢?
一方面,这个是基于多年开发实践的总结。15行其实已经是一个比较宽松的标准,开发人员稍加培训就可以实际贯彻,而符合这个标准的函数也能达到良好的可读性。
另一方面,这是基于对函数复杂度和代码行数之间关联关系的认识。
我采用一个简单的数学公式(注1):
引用
函数复杂度 >= 代码行数^2
以下为了简化,只以最低增长方式,平方数进行计算。
以一个函数的行数,从1行到20行为例,见下图:
当函数行数到达10行以上,函数复杂度就开始大幅度攀升。
当代码行数达到20行时(复杂度400),其复杂度已经是14行时(复杂度 196)的2倍。
因此我将代码规范定在15行。
下面我们运行此公式,来分析一下提炼小函数的好处。
例如,有1个100行的函数,分解为11(含自身)个10行的函数。
原复杂度= 100^2=10000。
分解后复杂度= 11×(10^2)= 1100。
分解后的复杂几乎是分解前的 1/9,几乎降低了1个数量级。这就解释了为什么长方法分解之后,可维护性大幅度提高。
再运用此公式,来观察那些现实中的长函数。
函数长度(Line) | 函数复杂度(Unit) | 10 | 100 | 15 | 225 | 20 | 400 | 30 | 900 | 50 | 2500 | 100 | 10000 | 500 | 250000 | 1000 | 1000000 |
也就无怪乎有同学表示维护1000行以上的函数,有种生不如死的感受。
注1:
该公式参考于 gerald m. weinberg 《质量·软件·管理(第1卷)——系统思维》
- 大小: 14 KB
分享到:
相关推荐
我们可以使用这个函数来释放不需要的内存缓存,提高系统的性能。 在获得CPU使用率方面,我们可以使用GetSystemTimes函数来获得系统的CPU使用率信息。我们也可以使用PerformanceCounters来监视系统的性能,包括CPU...
当同时指定 `pad_string` 和 `padded_length` 且原始字符串长度超过指定长度时,`lpad` 函数同样不会进行填充操作,而是直接返回原始字符串。例如: ```sql lpad('techonthenet', 15, 'z'); ``` 执行结果为:`'...
Java时间函数是编程中处理日期和时间的重要工具,主要用于创建、操作和格式化日期。Java提供了多种类和方法来处理时间,例如`java.util.Date`、`java.util.Calendar`、`java.time`包中的类(自Java 8起)以及`java....
“本书向你展示了提升Scala技能的方法和理念,它已超过‘更好的Java’。” ——Fernando Dobladez, Code54 “里面的练习有些挑战,很有趣,对你在真实世界中使用它很有益。” ——Chris Nauroth, ...
* 一个方法不应抛出太多类型的异常。 * 异常捕获尽量不要直接catch (Exception ex),应该把异常细分处理。 * 程序内抛出的异常本身就可说明异常的类型、抛出条件,可不填写详细的描述信息。捕获异常后用()取到详细...
- **代码长度**:每行代码推荐80列,最长不超过120列,折行保持对齐。 - **内部函数说明**:在类的成员函数内部调用其他函数时,可以简短说明。 - **缺省值注释**:函数入口参数有默认值时,需注释说明。 - **...
虽然代码规范不应过于僵化,但基本的格式和命名约定对于团队内部的协作和代码的长期维护是非常必要的。通过遵循一致的编码规范,可以减少误解,提高工作效率,并确保代码在不同开发人员之间能够平滑过渡。
2. 函数设计:保持函数短小精悍,每个函数不超过50行。 3. 避免过长的import列表,合理使用`import static`导入静态成员。 4. 使用合理的访问权限控制:`private`、`protected`、`public`和默认访问级别。 四、异常...
进行非对等操作时,如果是关系密切的立即操作符(如.),后不应加空格。 2. 建议 华为JAVA编程规范还提供了一些建议,旨在提高代码的可读性和可维护性。 建议1.1.2 规定,类属性和类方法不要交叉放置,不同存取...
4. **排课约束**:在实际的排课问题中,需要考虑诸多约束,如每门课程的上课时间不能与其他课程冲突,同一教师在同一时间段只能教授一门课程,教室容量不能超过预定人数等。这些约束在遗传算法中通过适应度函数进行...
行长度不要超过 80 个字符,换行时使用换行符。 5. 注释(Comments) 注释是 Java 程序的重要组成部分。实现注释的格式有块注释、单行注释、尾端注释、行末注释等。文挡注释用于描述函数或变量的用途。 6. 声明...
2. 函数的逻辑层次: JAVA 编程规范建议函数的逻辑层次不能超过 4 层,以避免代码的复杂性和难以维护。 3. switch 语句下的 case 语句:在 switch 语句下的 case 语句中,必须在每个 case 分支结束前加上 break ...
Java时间操作函数主要涉及到对日期和时间的处理,包括创建、转换、格式化以及计算等操作。以下是对这些函数的详细解析: 1. 计算某一月份的最大天数: `Calendar` 类提供了 `getActualMaximum()` 方法来获取指定...
- `finalize`:对象被垃圾回收之前调用的方法,用于清理资源,但不应依赖它来释放资源,因为调用时间不确定。 这些知识点涵盖了Java的基础语法、面向对象特性、内存管理、并发编程和异常处理等方面,是Java面试中...
在Java编程中,日期处理是常见的任务之一,Java提供了多种方式来操作日期,如`java.util.Date`,`java.util.Calendar`以及`java.text.SimpleDateFormat`等类。以下是对这些类的一些常用函数的总结: 首先,引入`...
5. **第四档税率:** 当月收入超过12500元但不超过15000元时,应纳税所得额分为四部分:(月收入 - 12500)适用25%税率,另外加上固定税额4500 * 20% + 3000 * 10% + 1500 * 3%。 6. **第五档税率:** 当月收入超过...
2. 行宽:一般建议每行不超过80个字符,以保持代码的易读性。 3. 对齐:比如方法参数、括号对齐,使代码看起来更整洁。 4. 空格:在操作符周围、逗号后、大括号前等地方合理使用空格。 5. 大括号风格:有争议的一点...
标题“解决Oracle没有WM_CONCAT函数”暗示了这个问题的背景:用户在尝试使用WM_CONCAT时遇到了问题,或者想要在不支持此函数的数据库环境中实现类似的功能。这可能是因为他们正在处理需要聚合多个字符串字段的查询,...
Java 把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的 一些基本类型...为这个变量分配内存空间,当超过变量的作用域后,java 会自动释放 掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。