软件设计的启发式规则 2启发式规则是一种经验规律 对改进设计和提高软件质量 具有重要的参考价值,但不 要过分拘泥于这些规则 7.设计功能可以模块
一、软件设计的启发式规则 1. 提高模块独立性 2. 设计规模适中的模块 3. 深度、宽度、扇入、扇出适中 4. 模块的作用域应该在控制域之内 5. 降低接口复杂性 6. 设计单入口和单出口的模块 7. 设计功能可以预测的模块 启发式规则是一种经验规律, 对改进设计和提高软件质量 具有重要的参考价值,但不 要过分拘泥于这些规则
1)提高模块独立性 是划分模块的最高准则。 高内聚,尽量一个模块一个功能; 低耦合,避免“病态连接”; 降低接口的复杂程度; 综合考虑模块可分解性、模块可组装性 模块可理解性、模块连续性和模块保护 (因修改错误而引起的副作用被控制在 模块的内部)等
1) 提高模块独立性 • 是划分模块的最高准则。 • 高内聚,尽量一个模块一个功能; • 低耦合,避免“病态连接”; • 降低接口的复杂程度; • 综合考虑模块可分解性、模块可组装性、 模块可理解性、模块连续性和模块保护 (因修改错误而引起的副作用被控制在 模块的内部)等
2)设计规模适中的模块 W. M. Weinberg的研究表明:如果一个模块 长度超过30条语句,其可理解性将迅速下降; F.T. Baker:最好控制在50行左右,能够打印 在一张纸上。 由于模块独立性是最高原则,对于一个设计 合理的功能性模块,即使长达千句或小到几 行,也是允许的 分解模块不应该降低模块独立性
2) 设计规模适中的模块 • W. M. Weinberg的研究表明:如果一个模块 长度超过30条语句,其可理解性将迅速下降; • F. T. Baker : 最好控制在50行左右,能够打印 在一张纸上。 • 由于模块独立性是最高原则,对于一个设计 合理的功能性模块,即使长达千句或小到几 行,也是允许的。 • 分解模块不应该降低模块独立性
3)深度、宽度、扇入、扇出适中 深度:软件结构中控制的层数。一般而 它与系统的复杂度和系统大小直接对应 宽度:软件结构中同一个层次上的模块总 数的最大数。 扇出:一个模块直接控制(调用)的模块 数目。扇出过大说明模块过分复杂;过小 也不好,不利于系统平衡分解,3到9为宜 扇入:一个模块的扇入是指直接控制该模 块的模块数目。扇入越大说明共享该模块 的上级模块越多 整个系统结构呈现“椭圆外型
3) 深度、宽度、扇入、扇出适中 • 深度:软件结构中控制的层数。一般而言 它与系统的复杂度和系统大小直接对应。 • 宽度:软件结构中同一个层次上的模块总 数的最大数。 • 扇出:一个模块直接控制(调用)的模块 数目。 扇出过大说明模块过分复杂;过小 也不好,不利于系统平衡分解,3到9为宜。 • 扇入:一个模块的扇入是指直接控制该模 块的模块数目。扇入越大说明共享该模块 的上级模块越多。 • 整个系统结构呈现“椭圆外型
如图的系统中:深度为4;宽度为5;模块A的扇出 为5,扇入为0。模块K的扇出为0;扇入为2。 A B D E F H K
A B C D F G H I J K E 如图的系统中:深度为4;宽度为5;模块A的扇出 为5,扇入为0。模块K的扇出为0;扇入为2
4)模块的作用域应在控制域之内 控制域:控制范围,是包括模块本身以及 所有下属模块(直接调用模块和间接调用 模块)的集合 作用域:作用范围,它是一个与条件判定 相联系的概念。是受该模块内一个判定影 响的所有模块的集合 对作用域不在控制域的两种改进方法:判 定上移和在作用域但不在控制域的模块下 移
4) 模块的作用域应在控制域之内 • 控制域:控制范围,是包括模块本身以及 所有下属模块(直接调用模块和间接调用 模块)的集合。 • 作用域:作用范围,它是一个与条件判定 相联系的概念。是受该模块内一个判定影 响的所有模块的集合。 • 对作用域不在控制域的两种改进方法:判 定上移和在作用域但不在控制域的模块下 移
A 模块D的控制域为 D, G,H,I, J K D E 如果D中有一个条件判 H定仅影响到模块G和H, 其作用域为G,H,L,J,K 作用域在控制域内 K 如果D中判定影响到E,通常需在D为判定结果设置 标记,并把该标记通过上级模块A传递给E,导 致控制耦合。其作用域为D.G,H,I,JK和,作用 域在控制域内
A C D G H I J K E 如果D中判定影响到E,通常需在D为判定结果设置 一标记,并把该标记通过上级模块A传递给E,导 致控制耦合。其作用域为D,G, H, I, J, K和E ,作用 域在控制域内。 模块D的控制域为 D,G,H,I,J, K。 如果D中有一个条件判 定仅影响到模块G和H, 其作用域为G, H, I, J, K , 作用域在控制域内
5)降低接口复杂性 尽量少用goto,避免病态连接和内容耦合 注意全局变量的使用,控制外部耦合和公共 耦合的使用。 将数据结构的传递改成数据传递,例如:在 求一元二次方程根的模块 quad root(able,X) 中,利用系数数组 Table和根数组X进行参数 传递。如果将其改为直接的系数和根传递, 即 quad root(a,b,c,x1x2),则特征耦合→数据 耦
5) 降低接口复杂性 • 尽量少用go to,避免病态连接和内容耦合。 • 注意全局变量的使用,控制外部耦合和公共 耦合的使用。 • 将数据结构的传递改成数据传递,例如:在 求一元二次方程根的模块quad_root(Table, X) 中,利用系数数组Table和根数组X进行参数 传递。如果将其改为直接的系数和根传递, 即quad_root(a, b, c, x1 ,x2 ),则特征耦合→数据 耦合