软件模块化的设计原则
软件模块化的设计通常用聚合(聚合是对模块功能相对强度的度量)和祸合(祸合是对一个软件结构内不同模块之间互相关联程度的度量)的概念来衡量模块间的独立性和模块间的关联性,在设计模块时,我们将遵循如下的软件模块化设计的原则:
操作方法
- 01
1、设计时应该力求做到模块的高聚合(顺序聚合、功能聚合),通常中等程度的聚合(过程聚合、通信聚合)也是可以采用的,而且效果和高聚合相差不多。但是,低聚合(偶然聚合、逻辑聚合、时间聚合)效果很差,一般都不采用。
- 02
2、在祸合方式上力求降低模块间接口的复杂性。模块间接口的复杂性包括模块的接口方式、接口信息的结构和数量。接口方式不采用直接引入(内容祸合),而采用调用方式(如过程语句调用方式)。接口信息通过参数传递且传递信息的结构尽量简单,不用复杂参数结构(如过程、指针等类型参数),参数的个数也不宜太多,如果太多,则说明模块的功能过于庞大复杂,可考虑降低其复杂性。
- 03
3、尽可能改进软件结构提高模块独立性。设计出软件的初步结构以后,应试审查分析这个结构,通过模块分解或合并,力求降低祸合提高聚合。如图2.5所示,若其中B、C、D之间存在内容祸合,可将它们合并为一个模块BCD,若E、F中有一个公共的子功能,可将该子功能独立成一个模块,这样就可以改进结构。
- 04
4、尽量减少高扇出结构,特别当深度增加时,力求扇入,避免软件的瀑布式结构。深度表示软件结构中控制的层数,扇出是对某一模块直接控制的模块数目的度量,扇入则是对某一给定模块被多少个模块直接控制的度量。 扇出过大意味着模块越复杂,需要控制和协调过多的下级模块,扇出过小也不好。经验表明,一个设计得好的典型系统的平均扇出通常是3或4(扇出的上限通常是5~9)。一个模块的扇入表明有多少个上级模块直接调用它,扇入越大则共享该模块的上级模块数目越多,扇入的目的在于提高公共的实用模块的利用率,防止设计冗余。
- 05
5、将模块的作用域保持在其控制域内。模块的作用域定义为受该模块内一个判定影响的所有模块的集合。模块的控制域是这个模块木身及所有直接或间接从属于它的模块的集合。 为减少模块间的祸合度,应只在有调用控制关系的模块间存在控制祸合。若模块的作用域与控制域不一致,则说明存在另一个模块,与该模块无调用控制关系,但两者具有控制祸合,这样的结构使得软件难于理解、软件测试与软件维护。
- 06
6、模块功能应该可以预测。如果将一个模块看作黑盒子,就是说,只要输入的数据相同就产生同样的输出,这个模块的功能就是可以预测的。具有内部状态的模块,其输出不仅与输入有关,而且还取决于模块的当前状态,其功能是不可预测的,这就增加了模块的测试和维护难度,这条原则不是绝对的,如对于实时系统来说,针对不定时的输入,系统状态要不断发生变化,这种变化又直接影响下一个输入引起的输出。 对于这种不可避免的情况,要引起充分注意,要将相应模块做特殊处理。无论测试还是维护都把模块状态作为一个重要影响因素来考虑。
- 07
7、设计单入口单出口的模块。这条规则警告软件开发者不要使模块间出现内容祸合,这也是结构化程序设计的基木要求,目的在于提高软件的可理解性、可测试性和可维护性。