在软件高层设计中,如何分解模块是首要考虑的问题。目前业界公认模块划分要按照“高内聚,低耦合”的原则来进行,那么如何划分才能满足“高内聚,低耦合”呢?下面来对模块分解原理方面进行一些探索,有考虑不周和不成熟之处还请大家不吝指正。
模块是按功能来分解的吗?
许多人可能有过经验,面对一堆功能性需求,多个不同的需求可能要放到同一个模块里,而某个需求又需要分解到多个模块里去实现。
比如一个词典软件(类似金山词霸的软件),通常有查询词典的功能需求和添加用户词库的功能需求,显然不可能简单地为这两个功能各分解一个模块。查询界面和添加用户词库的界面处理部分会被划成一个模块,而对词典的数据管理(查询,添加等)部分会被划分成另外一个模块。
通过对以上词典软件的模块划分的分析,可以得出模块并不是简单地按功能来划分的结论,因此按功能来分解模块并不是一个任何情况下都可行的方案。
模块按专业领域进行分解
仔细观察上面所说的词典软件的模块分解就会发现,所划分的两个模块属于不同的专业领域,一个是交互领域(图形界面),另一个是数据管理领域(数据结构与算法)。这样看来模块划分是按专业领域来划分的了,是不是所有的模块划分都是或者应该按照专业领域来进行划分呢?
通过观察大量的软件的模块分解情况,其实可以发现绝大部分模块都是按照专业领域来分解的,这些专业领域包括软件公共领域的各个子领域,软件所处理业务的专业领域及其子领域等。
软件公共领域常见的子领域有数据结构算法,图形界面,IO处理,网络通信,数据库,加密,安全,图像处理,数学算法等,当然这些子领域还可以进一步划分出更小的子领域来。
软件所处理业务的专业领域则是指具体的业务方面所属的专业领域,如财务软件的业务包括了财务专业领域,CAD软件业务包括了机械制图方面的专业领域等。
这些不同专业领域内的内容都是被划分到不同的模块里,没有人会在同一个模块里同时实现网络通信和数据结构算法的功能。这样可以得到模块分解的一个最基本的原理:
模块分解基本原理:不能在同一模块中实现两个不同专业领域的内容
上面这句话的意思其实和模块按专业领域进行分解是一回事,只不过意思更明确一些。注意这里说的是“实现”,有许多的模块中需要用到许多不同专业领域的接口来进行处理,即在同一模块中可能会调用许多不同专业领域的接口来进行处理,调用接口并不属于“实现”。
模块按专业领域来分解只是一个原理,无法证明它的正确性,因此看一下它会不会与已有的一些设计特性有冲突呢,比如常说的“高内聚,低耦合”,可复用性,可扩展性等是否会产生冲突。
推论1:按专业领域分解的模块是“高内聚,低耦合”的
为什么说按专业领域分解的模块事“高内聚,低耦合”的呢?专业的划分都是人们经过长期的实践和探索划分出来的,专业领域本身就是“高内聚,低耦合”的, 比如数据结构算法专业和网络专业耦合就很小,但每个专业的内部都是高内聚的。
推论2:按专业领域分解的模块是可复用的
这点很容易理解,模块按专业领域分解完后,显然任何两个不同的模块都不会有重复的内容,因此满足可复用的特性。
推论3:按专业领域分解的模块是可扩展的
当有新增需求时,只要将新增需求分解成各个专业领域的内容,新增的内容可以分为三类:
1、在已有模块里已经有对应的实现,
2、属于已有模块的领域,但是没有对应的实现
3、不属于已有模块的领域
对第1种情况中,显然不需要对已有模块做任何修改和添加;对第2种,需要在已有模块里添加相应的接口来实现对应的内容;对第3种,需要增加新的模块来实现对应的内容。
所有这三种情况,都符合软件设计中的可扩展特性,因此按专业领域分解的模块是可扩展的。
推论4:按专业领域分解的模块是可维护的
这点可以由由模块高内聚,低耦合,可扩展性的特性得出。
由此看出模块分解基本原理是和以往对设计的要求是相符合的,但是会不会有反例呢,我实在不能确定,因为这个原理是无法证明的。如果有人发现有不应该按照专业领域来分解模块的反例,请回复一下。
模块按专业领域分解的困难之处
虽然模块按专业领域进行分解看起来好像很完美,可以说绝大部分需求都可以按照这个原则来进行分解。但是并不是说就不存在问题了,实际上按专业分解的前提条件就是要将需求能够分解成已有专业领域的内容。
困难1:如果需求的内容属于新兴未成型的专业领域的内容,那么按专业分解就不是那么容易了。
困难2:许多需求最终需要分解到某个专业领域的某个子领域里来处理,而很多专业领域还在发展之中,它的许多子领域还没定型,这时划分模块也不是一件容易的事情。