一、创建子程序的正当理由
- 降低复杂度
所谓降低复杂度就是通过创建子程序来完成一系列的操作,一旦程序写好,你就可以忘记具体实现的细节,只需知道他是用来干嘛的,简化了代码布局,使代码看起来更加易读。
- 避免代码重复
避免代码重复,比较好理解,就是将多处用到相同代码的实现提取出来,那么多个不同的使用者用到这块相同的逻辑只需调一下函数,那么复杂的多行代码就只需要写一遍,维护也更加方便,出了bug也只需要检查一处,修复也只需要修改一处的逻辑,这样代码也更加安全,节约代码空间和时间的成本,简直不要太爽!何乐而不为。
- 改善性能
上个特性已经提到,把代码集中到一处可以方便查出代码的运行效率低下,想用更搞笑的算法或更高效的语言重写代码也更加容易。
- 除此之外的理由:隔离复杂度、隐藏实现细节、隐藏全局数据、达到特定的重构目的等等。
二、在子程序层上设计
- 功能的内聚性
功能内聚性是最强也是最好的一种内聚性,就是说让一个子程序仅执行一项操作。
三、好的子程序名字
命名的最高境界就是函数即注释,好的程序名字能清晰地描述子程序所做的一切,所谓见字如面。下面是有效地给子程序命名的指导原则:
-
描述子程序所做的所有事情
-
避免使用无意义的、模糊或表述不清的动词
-
最佳长度:9-15个字符
-
给函数命名是要对返回值有所描述
-
准确的对仗词
例如:add/remove open/close begin/end lock/unlock show/hide start/stop get/put get/set min/max first/last
四、子程序可以写多长?
IBM所做的一项研究发现,最容易出错的是那些超过500行代码的自陈谷。超过500行之后,子程序的出错率就会与其长度成正比。在任何时候,复杂的算法总会导致更长的子程序。在这种情况下,可以允许子程序的长度有序的整张到100-200行。
五、如何使用子程序参数
-
参数顺序保持一致
-
使用所有的参数
如果有没有用到的,请删除
-
把状态或出错变量放在最后
-
不要把子程序的参数用作工作变量
把传入子程序的参数用作工作变量是很危险的,应该使用局部变量。 **
-
把子程序的参数个数大约限制在7个以内
-
确保实际参数与形式参数类型相匹配(弱类型语言中很可能因为参数类型发生错误)
六、使用函数是要特别考虑的问题
- 什么时候使用函数,什么时候使用过程
函数:带有返回值 过程:工作方式、执行逻辑。 这两个你中有我,我中有你,有时候很难区别开来,所以这么来判断: 如果一个子程序的主要用途就是返回由其名字所指明的返回值,那么就该使用函数,否则就应该使用过程。 比如:
function updateStatus(){
return DB.updateStatus()
}
if(updateStatus()==='success'){
...
}
修改为:
const status = updateStatus()
if(status === 'success'){
...
}
status变量就可以理解为函数,下面判断的逻辑像工作方式一样,就称为过程。如果什么情况就执行什么程序,就是过程。单纯的接收返回值就是函数。
总结
-
创建子程序最主要的目的是提高程序的客观理性,其中节省代码空间只是一个次要原因;提高可读性、可靠性和可修改行等原因都更重要一些。
-
有时候把一些简单的操作写成独立的子程序也非常有价值。
-
子程序可以按照其内聚性分为很多类,最佳的内聚性是功能上的内聚性:每个子程序只完成一个功能。
-
子程序的名字是他的质量的指示器。
-
只有在某个子程序的主要目的是返回其有起名字所描述的特定结果时,才应该使用函数。