分析 收藏
2 软件系统模型分析
2.1软件系统模块的原型
以系统的角度和开发过程来看待一个软件系统的模块,就会发现一个能保证运行良好、具备良好的使用方式,并能方便后续的维护扩展要求的系统模块,需求具备以下几点:
1、良好的模块操作接口。
2、良好的模块内部组织。
3、良好的模块通信接口。
4、良好的模块规范。
5、清晰明确的内部任务。
之间的相互关系如下图:
其中:操作接口是模块提供给使用者操作的方式;通信接口是模块与外界系统通信交互的关键所在;内部组织是一个模块内部所有要素的组织结构;规范是整个模块生存期间内所有要素所必须遵守的规则;内部任务是该模块所要完成的任务。
一个模块存在的目的主要是为了实现所需要的功能,也就是内部任务,如果不能完成所需要的功能,那么这个模块就没有存在的理由。也许你会认为只要模块能完成所需要的功能就可以达到模块存的目的,那么我们还为什么需要什么操作接口、内部组织、规范和通信接口呢?
可以想一下,模块实现需要的功能是让别人使用,让别人使用就意味着必须有操作接口,否则又怎么能用呢,所以即使一个很简单的模块如pfintf函数,也就提供给使用者的操作接口(该函数的原形声明),使用使用者知道该怎么去用。
而内部组织也是一个模块必须具备的,在简单的一段代码或是一个100行的函数,或是一个几十个函数的库,或是一个实现具体业务的插件,其内部根据工作任务,需要明确内部的逻辑顺序、函数调用关系、或是各个类之的间功能划分等,其它都是其内部组织,一个模块的内部组织就是这个模块的骨架,也就是常说的架构,在软件中不管大如几十万行的系统,几千行的插件,几十行的函数,都有其架构,只是复杂成度不一样。
规范是一个模块在其生命周期内遵守的规则,如编码规则、设计规则等。
通信接口是模块外部系统通信的规则,通过它能将模块与外部的联系统屏蔽起来,降底维护成本。
由此我们可以看出,只有具备前4个条件,我们才能在模块中真正实现我们想实现的功能,而且我们也发现,这4个条件与模块具体实现的功能是无关的,其只中用来在这4个条件的约束下更好地实现模块要达到的目的,所以我们可以把这4个条件称为模块的约束条件,而内部任务是模块存在的最终目的。由此可以得出一个结论,软件模块由约束条件和最终目的构成,约束条件是为更好实现目的,实现目的质量好坏,依赖于约束条件的是否完整的执行。这也是后面要分析如何组建项目团队的一个思路。
2.2软件系统模块的构成因素分析
1、操作接口分析。操作接口是系统模块提供给使用人员使用本模块的方法,操作接口是否简单是关键,一个简单的接口,使用人员在使用过程使用肯定非常容易,同时由于业务的经常性变运,使用者在使用软件模块的过程中有可能经常改动对模块的使用,因此接口还必须具备良好的抽象性,也就是说,对于用户的各种操作,接口都不会因为用户操作的改变而改变自身的形状,如WIN32API函数CreateThread,其原型如下:
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
该函数做为一个启动线程的模块,对于使用者而言,在给线程函数lpStartAddress传入运行参数LPVOID(等于void*) lpParameter时,对该参数是什么样子的并不做任何限制,任何数据都可以,所以该模块能满足使用者在启动函数时给线程函数传入任意的数据,当然该模块在这方面是非常完美,在其它方面有它的不好之处,我们在这里主要是分析对使用模块时一个接口能否满足用户各种操作的问题,就完成传入参数而言,这样的方法完全可以满足所有的情况。
通过对该函数的分析,我们可以得出一个结论,一个软件模块在提供给用户操作接口的时候,该接口应该可以满足用户的所有操作,如果用户对该接口的操作特性只有输入,那么输入数据应该是任意类型的(void *),如果还需要输入数据,那么输出数据也应该是任意类型的(void *)。
当然也可以将输入数据和输出数据合为一个。如 void Interface(void* pData);这样该接口在用户操作时根据接口格式设计pData,由接口内部根据接口格式解析pData。这样带来的危害是:如果使用者构造的数据与接口处理的数据不一致就会导致发生各种异常情况,这当然是我们不想要的,因些,在我们将接口进行抽象带来方便的时候,我们得付出其它方面的代价。
付出的代价就是:模块内部对数据进行检查,如果是非法数据则返回不处理,因此我们在接口中还得再加一个参数用于说明pData的长度,如果使用者传入的数据长度与模块需要的不一致,就可以判断为非法数据。
void Interface(void* pData,unsigned long uDataLen);
这样虽然加大了使用者和模块开发者构造数据和解析数据的时检查的工作量,但能带给后期不管发生什么变化,都不需要进行接口的修改的好处,想想修改接口带来的混乱,我觉得付出这么点代价很值,而且做好构造数据和解析数据时检查本身就是一个程序员应该完成的一项工作。同时我们也可以想办法计上心来接口进数据在进入接口前和进入接口后自动进行检查,这样开发者就不用付这种代价了,这一点在系统通信接口部分进行分析。
2、模块内部组织分析。
如果说模块的接口是从使用者的方便性和模块的可维护性、可扩展性方面来考虑其对模块质量好坏的考虑,那么模块实现真正的功能,能否保证功能实现的正确性、健壮性、模块开发者易维护性等方面的影响是要靠模块内部组织结构来打好基础。
一个好的内部组织结构,会把内部的各项业务功能安排的非常合理,非常清晰,对于开发者而言,实现每一个细节,都知道应该去做哪些事;在修改每个细节的时候,都清楚一次修改会影响到哪些地方;而需要增加一个功能的时候,应该很清楚应该在哪个地方增加,需要在其它哪些地方做相应的处理;在出现问题的时候,能很快根据现象确定问题所出的范围。
而设计软件的过程中,这也正是每一个设计人员和开发人员所想达到的目标,所以做一为个模块(或系统)的骨架,其质量的好环,决定着这个模块的实现难度、维护、扩展、修改的难度和可实现性,可以说一个模块内部的质量好坏,其内部组织是基本前题。
3、模块通信接口分析。
通信接口是一个模块与外部系统交互的接口,与外部系统沟通的完整与否,正确与否完全取决于模块的通信接口。
4、模块规范分析。
模块的规范是模块所有要素所必须遵守的规则,也就是模块所有成员之间达成的一致共识。包括相互调用规则、命令规则、注释说明规则、调试规则等等,是所有成员通一行动的标准,这样才能保证所有成员不发生混乱。
5、模块内部任务分析。
模块内部任务是模块的核心,也是该模块存的主要依据,正是因为模块承担了该任务的实现,所以才需要设计、实现、维护该模块,一旦模块承担的任务不再需要,该模块也就失去了存在的价值。
作为一个模块的内部任务,因为需要一个独立的模块来承载它的实现,就必须考虑承载它的成本和代价,如果只需要输出一条语句(hello word!),就没有必须用一个专门的模块来实现它(除过学习和实验之外),因为任何一个模块都需要相关的4种约束条件,实现每一种约束条件和成本和代价都是相同的(因为约束条件只取决于模要达到的质量目标,而与模块的具体任务无关),同时,如果该模块实现的功能是不能大量应用的,也需要其实现方式。
所以,一个模块功能的承载,一要考虑任务量的适度,不能太多,也不能太少,太多会导致模块会出现混乱,太少会导致其成本增加;二要考虑模块的复用性,如果没有复用性,其存在的价值也不大。
2.3软件系统的原型
软件系统是软件模块的集成,其实现的最终功能要比软件模块的功能大的多,但实际开发中发现一个系统,需求具备的条件与模块具备的条件非常相似:
1、良好的用户操作接口。
2、良好的内部模块之间的组织。
3、良好的系统通信接口。
4、良好的系统规范。
5、清晰明确的功能任务(需求)。
之间的相互关系与模块5个要素之间关系一样,如下图:
2.4软件系统的构成因素分析
1、用户操作接口分析。用户操作接口是一个软件系统用户的使用界面,使用界面的好坏的评价,有两个方面的评价:一是使用界面是否能满足用户所希望的所有操作;二是使用界面是否简单好用。
使两者要达到的目的来看,两者是相互矛盾的,因为能满足所有的操作就意味着界面的复杂,简单好用就意味着不能太复杂,但从一个软件系统实现的最终目的来看,系统是为了满足用户的具体需要,能为用户提供优质的服务,所以能否达到最终的目的,也是软件系统开发的挑战所在。软件开发团队的任务就是能开发出满足用户需求的系统,那么怎样才能解决开发过程中存在矛盾,也是我们要解决问题的出发点。
在解决既要实现最多的功能,又要降底最大的成本这一矛盾时,我们必须知道,同一工作量最终付出的成本是恒定的,不管是谁,都无法改变,但我们可以改变的方式有:1、成本转移到其它地方,降低本地的成本;2、将成本分解到不同阶段,降底每一阶段的成本;3、提高成果的复用率,通过降底后期成本来分摊前期的成本,从总体上降成总成本。
三种方式,第一种是做了转移,把自身成本转移给别人,实际上成本并没有降底;第二种方式是延长了成本支出的时间,降底了阶段性成本,总成本也没有降底;第三种方式,总成本从数量上也没有降底,但在总成本的范围内,增加了成本的复用率,所以只有这一方式真实的降底了成本。
而现实工作中,如果单一应用某种方式,是一种理想的情况,往往不旦达不到目的,而且容易引起其它方面的问题,最后反而造成总成本的不断上张。
2、内部模块之间的组织分析。
与软件模块的内部组织结构一样,软件系统内部组织结构也是整个系统一系列性能提升的基础,良好的内部组织,能使用系统承担的工作任务更加明确、清晰;良好的内部组织,能使用系统的开发工作更容易分隔;良好的内部组织,能使用系统更容易扩展,增加新的功能需求;良好的内部结构,能使系统更容易维护;良好的内部结构,能使用系统的运行配置更容易操作等等。
所以如何判断一个系统是否具有良好的内部组织结构,可以得出以下评价指标:
系统承担的工作任务是否与系统需求一致、是否在每个模块中是清晰的;
系统开发工作是否能明确的分配到开发小组每一个成员;
系统开发工作是否具有更大的并行开发的可能性;
假设系统需求增加一项功能,是否能在修改的过程中不影响其它功能,对它的修改是否影响到一半以上的模块的改动;
假设系统出现BUG,能否准确定位,并能很容易修改(不包括操作接口和通信接口、数据库接口的修改引起接口级的改动)。
系统原型,在进行配置、维护时是否具很好的操作性,即有操作工具去修改配置信息等等。
3、系统通信接口分析。
系统通信接口属于系统扩展的一部分,其并不是系统必须的要素,但随着目前系统越来越依赖于网络和其它系统,以及系统越来越并行化,越来越需要和其它系统配合才能工作,真实开发中独立存在的系统已经很少见,所以通信接口也越来越成为一个软件系统的一个重要属性。
做为系统的通信接口,其展现给系统的是一组符合标准的信息组合,而从系统中出去的也是一组符合标准的信息组合。因此,一个良好的通信接口应该对系统屏蔽通信过程中细节,如数据在网络上的传输过程、不同机器之间数据编码的不同,也就是说,通信接口展现给程序员的工作是,按照标准构造要发送的数据,根据标准处理接收到的数据。
从另一个方面来看,一个良好的通信接口,还必须具备良好的扩展性,扩展性有三个方面,一是在一个通信接口上增加新的消息,不影响其它消息的处理。二、接口中的所有消息都可以随时增加、删除字段。三、接口应具备版本信息。
4、系统规范分析。
系统规范是对系统的基本约束,是指对项目把有要素的命令规则、编码风格、文档格式、开发流程、开发规范等一系列的一种约束。
虽然各种约束都有其不足的地方,但我们必须要相信,约束是为了更好的理解的控制系统的方法,他带来的好处远远大于存在的不足,而且存在的不足是可以用其它方式弥补的。
一个系统的基本约束有:
管理约束:项目规划、项目开发规范流程、项目测试计划、项目验收计划、项目质量管理计划;
开发约束:项目需求、项目技术文档、项目设计规范、项目编码规范、项目测试规范等。
5、功能任务分析。
系统的功能任务就是指系统的需求规格,需求规格决定了系统要实现的具体功能,因此,系统需求就是系统生命中的最终目标,系统功能的变化取决于系统需求的变化。
在实际项目开发过程中,需求从项目开始就是一直在不断的变化,所在在项目开发过程中,我们必须明确一点,我们要不断的修改系统功能,大量开发人员最头痛的问题就是在开发过程不停的修改程序,这种修改60%以上是由于需求的变动引起的。所以在开发过程中我们必须要有这样的心里准备,不要因为大量的改动工作产生厌烦情绪,这在中小开发团队当中是十分明显的。从心里学的角度讲,对工作厌烦是因为工作的结果与所想象的不一致,如果与想象的一致,就会以一种积极的心态去对待工作,尤其是开发工作。
功能任务的分解,系统在设计时必须根据所承担的功能任务,进行明确的分解,制定合理的系统架构,并把所有功能进行分类,分解到相应的模块中去,从理论上讲,一个系统所承担的功能任务是恒定的,但采用不同的方式,系统的开发成本、维护成本会有很大的不同,系统的最终受益也不同,所以一个项目能不能有较底的成本和最大的受益,功能任务的分解超着决定性的作用:
1、功能任务分解的是否明确,直接影响着项目的开发进度和质量。
2、功能任务分解的是否合理,直接影响着项目后期维护的难度。
3、功能任务分解的是否合理,直接影响着项目因为需求变动而带来的修改难度。
4、功能任务分解的是否合理,直接影响着项目成员开发工作的并行程度。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dahuaixiaohuai/archive/2011/02/18/6193017.aspx