软件模块化设计的思路

【摘要】编程

本文讨论了软件模块化设计过程当中的若干重要问题解决的通常思路。api

【关键词】软件模块化设计、职责分离原则、可移植性、稳定性安全

1、问题的提出

软件模块化的目的是创建可重用的软件组件,在不须要修改或仅做少许修改的状况下,可再次用来组建新的软件系统,提升软件的开发周期和可靠性。因为软件模块有在不一样的系统中使用的需求,决定了软件模块的设计和专用于单一系统的软件代码存在差异,这具体体如今如下方面:网络

1. 软件模块须要更好的弹性,增长适用范围;并发

2. 软件模块须要有更好的可移植性,增长适用范围;框架

3. 软件模块须要更清晰地定义接口,避免模糊含混;socket

4. 软件模块须要有更好的稳定性,避免错误影响范围扩散;模块化

5. 软件模块须要有更好的独立性,避免引用牵连模块,造成依赖链。函数

2、解决思路

2.1如何提供更好的设计弹性

长期的软件实践代表,良好的弹性来自于抽象。引入更多的更高层次的抽象会增长软件的弹性。而一个抽象的层次高低来自于设计者对问题域的本质认识的深入程度,因此要设计更有弹性的模块,首先须要提升本身对模块所解决的问题的认识。额外的抽象层次基本上都会带来性能损失,因此设计上应该考虑到性能和弹性的平衡,但在性能问题没有确证以前,弹性优先。弹性带来的另外一个问题是复杂性,过于复杂的软件会带来理解和维护上的困难,因此过分的弹性设计也是不可取的。性能

改进模块弹性的通常的手段有:

1. 采用接口提供服务而非具体实例。经过不一样的方案实现接口,可提供弹性,而对客户不产生影响;

2. 采用单一职责的简单模块而非复杂庞大的。实践证实细粒度的软件单元有更好的适用范围,不一样职责的服务应该使用分离(物理的或逻辑上)的接口,不要在一个模块中提供2个以上的服务;

3. 提供可扩展机制,容许客户自行添加新的功能来强化模块;

4. 提供配置选项,容许客户定制模块的部分行为。

2.2如何提供更好的可移植性

可移植性是指让软件在不一样平台上运行的难易程度,不须要任何修改就能够运行的就称为跨平台的。实际上真正跨平台的软件是不存在的,任何跨平台的软件必须有一个抽象的底层来支撑,这个支撑的部分是须要在不一样的平台上从新实现的,也就是软件的需移植部分。认识到这一点,就能够看到,增长一个软件模块的可移植性,须要作两件事:分离不须要移植和须要移植的部分、减少须要移植部分的复杂度以方便移植。

要肯定一个软件模块是不是可移植的,首先须要肯定这个模块的目标平台。必须仔细分析全部目标平台的异同,才可以肯定哪些是能够在全部平台上都支持的,这些就是不须要移植(可移植)的部分,而并不是全部平台都支持只要有一个不支持)的部分则是须要移植的。选择技术方案时,优先选择可移植方案。对模块中无可移植方案的部分,采用接口抽象出一个可移植层,在不一样的平台上分别实现此接口,此接口的实现就是整个模块的须要移植部分,在作移植工做时,只要将关注点放在这里便可。

一般,采用C语言开发的软件,标准C库是很好的可移植库;采用C++开发的软件,选择STL也会得到很好的可移植性;对于网络编程,socket api 也是受绝大多数系统平台支持的,有很好的可移植性。不一样的编译器之间也会存在差别,编码时采用标准C/C++语法,避免使用特定编译器的扩展语法,也会改进可移植性。采用一些跨平台第三方库通常也能带来较好的可移植性,但在采用以前须要考虑是否开放源代码、是否收费等因素。

总之,一个软件模块的可移植性好坏,也是取决于设计者对全部目标编译/运行平台的熟悉程度。增长对各个目标的平台了解,有助于设计出具备更好可移植性的模块。

2.3如何提供更清晰的接口定义

当一个模块不考虑可重用时,有时可能不会对接口考虑得很是仔细,接口说明可能就以口头约定或项目内部约定为准。这在单一项目内部通常不会形成很大问题,但一旦模块须要重用到其余项目,这种不太严谨的方法就会带来诸如语义含混、理解困难、功能定义不明确等问题。所以可重用模块的接口的定义须要比内部使用的模块更严格,通常须要考虑如下方面:

1. 该模块提供的具体服务的详细描述,清晰地阐明该模块提供了哪些服务,以及如何提供;

2. 每个接口函数(操做)的语义说明,包括全部的参数的含义、传递方向、有效范围、异常处理、前提/后置条件等;

3. 在多任务环境下的并发访问安全性的说明,这对多任务开发很是重要;

4. 模块自己的适用范围须要详细描述,清晰界定模块能够工做的环境;

5. 提供完整的示例代码演示正确的使用方法,不少时候demo是最好的文档。

2.4如何提供更好的稳定性

稳定性体可细分了功能上的稳定性和设计上的稳定性。功能上的稳定性表现为模块屡次运行不会出现错误;设计上的稳定性表现为屡次复用不会须要修改。

功能上的稳定性能够经过单元测试等手段来达到。根据接口设计足够多的测试用例,能够在很大程度上保证功能。同时,注重编程规范、严格检查各类前提/后置条件、编写更多的保护性代码、采用更好的错误处理机制,这些手段都有利于提高模块的功能稳定性。

设计上的稳定性则须要设计者对问题域有深入的认识,在设计时采用更多的前瞻性、考虑跟多的兼容性、兼顾更多的可移植性。这对设计者提出了更高的要求。不少时候,彻底不要修改而直接复用的可能性是比较小的,但通常经过努力分析问题域,能够作到基本框架和接口的设计不作任何修改,而只须要针对新的应用环境作移植和扩展。这种比较稳定的框架设计能够经过在若干个复用过程当中反复重构而得到,但须要设计者善于从旧有的设计中提炼总结。参考一些成熟框架也是提高设计稳定性的不错的选择。

2.5如何提供更好的独立性

一个模块若是依赖其余模块,那么在复用时,其依赖的模块也须要一并复用。这种依赖会造成一个链,若是其中任何一个不可复用,将致使整个链上的都不可复用。因此,若是可能,以可复用为目标的软件模块在设计时,尽可能要考虑作成独立的组件。

设计独立的软件模块时,可考虑下列方面:

1. 避免采用存在复用风险(如缺少源代码)的其余模块,只考虑使用平台的基本服务或有持续支持的其余模块;

2. 将依赖的模块集成到本模块内部,使得外部依赖成为内嵌部分;

3. 将可能存在风险的外部依赖模块经过额外的抽象层隔离,使得本模块能够独立于依赖模块而变化;

4. 选择具备较短依赖链的外部模块做为依赖模块,缩短整个依赖链。

全文地址:点击打开连接