1. 什么是“子程序”:子程序是为实现一个特定的目的而编写的一个可被调用的方法(method)或过程(procedure);
2. 子程序的目的:节约空间、可管理性和提高性能(宏观方面);
- 降低复杂度(最主要)
- 引入中间、易懂的抽象:当命名恰当的子程序。是足以说明这段代码用意,具有可读性也比较容易理解。
- 避免代码重复
- 隐藏顺序:一个子程序的执行与否,不应该依赖于另一个子程序是否执行。
- 提高可移植性:可以用子程序来隔离程序中不可移植的部分。不可移植的部分包括编程语言所提供的非标准功能、对硬件的依赖,以及对操作系统的依赖等。
- 改善性能:通过使用子程序,你可以只在一个地方优化代码。
3. 目标:子程序只把一件事做好,不再做任何其他事情;这样做的好处是得到更高的可靠性;
4. 在子程序层上设计
a) 内聚性:子程序中各个操作之间联系的紧急程度。
内容相关联(低耦合高内聚):
藕合度指程序模块间存在联系的紧密程度;
内聚性则是模块内部的相互依赖程度;
低耦合就是模块之间的关联少,越独立耦合度越低;
高内聚就是模块的内容针对干的事情少,功能越单一内聚越高;
低耦合 电脑的主板上的各种插槽,可以连接很多外置的各种各样的设备,不需要做什么只要简单地“插进去”,不管是分工,还模块设计。模块间,联系越少越好。
b) 功能的内聚性:是最强也是最好的一种内聚性,让一个子程序仅执行一项操作;
例子:计算雇员年龄并给出生日的子程序就是功能内聚性的,因为它只完成一项工作,而且完成得很好。
c) 顺序上的内聚性:在子程序内包含有需要按特定顺序执行的操作,这些步骤需要共享数据,而且只有在全部执行完毕后才能完成一项完整的功能。
例子:有一个按给出的生日计算雇员年龄、退休时间的子程序,如果它是利用所计算出的年龄来确定雇员将要退休的时间,那么他就具有顺序内聚性。
d) 通信上的内聚性:一个子程序中的不同操作使用了同样的数据,但不存在任何其他的联系。
例子(同上):有一个按给出的生日计算雇员年龄、退休时间的子程序,如果它是分别计算年龄和退休时间的,但是使用相同生日数据,那它就具有通信上的内聚性;
那如何将这个例子转化为功能内聚性呢?
可以分别建立两个子程序,一个根据生日计算年龄,另一个根据生日计算退休时间。
e) 逻辑上的内聚性(不可取的内聚性):若干操作被放入同一个子程序中,通过传入的控制标志来选择执行其中的一项操作。
5. 好子程序的名字:好的子程序能清晰地描述子程序所做的一切。以下为一些指导规则:
- 描述子程序所做的所有事情:子程序的名字应当描述其所有的输出结果以及副作用。当你想完整的描述其输入结果与它的副作用时,发现名字显得又笨又长,解决的方法不是使用某个描述性较弱的子程序名,而是应该换一种编写程序,直截了当地解决问题不产生副作用。
- 避免使用无意义的、模糊或表述不清的动词
- 不要通过数字形成不同的子程序名字
- 给函数命名时要对返回值有所描述
- 给过程起名时使用语气强烈的动词加宾语的形式:一个具有功能内聚性的过程通常是针对一个对象执行一种操作。过程的名字应该能反映该过程所做的事情,而一个针对某对象执行的操作就需要一个动词+宾语的形式
- 为常用操作确立命名规则