软件工程学中国科学技术大学网络学院4.1软件设计的目标和任务4.2软件设计基础4.3模块独立性4.4结构化设计方法4.5数据设计和文件设计4.6过程设计第4章软件设计方法4.1软件设计的目标和任务•根据用信息域表示的软件需求,以及功能和性能需求,进行数据设计系统结构设计接口设计过程设计。•数据设计需求分析阶段创建的信息模型转变成实现软件所需要的数据结构。•系统结构设计确定程序由哪些模块组成以及这些模块相互间的关系。•接口设计的结果描述了软件内部、软件与协作系统之间以及软件与使用它的人之间的通信方式。•过程设计则是把结构成份转换成软件的过程性描述。在编码步骤,根据这种过程性描述,生成源程序代码,然后通过测试最终得到完整有效的软件。开发阶段的信息流程序模块测试编码设计信息域需求功能与性能需求数据设计过程设计系统结构设计组装好的有效的软件•软件设计是后续开发步骤及软件维护工作的基础。如果没有设计,只能建立一个不稳定的系统结构软件设计任务•从工程管理的角度来看,软件设计分两步完成。–概要设计,将软件需求转化为数据结构和软件的系统结构。–详细设计,即过程设计。通过对结构表示进行细化,得到软件的详细的数据结构和算法。软件设计过程1.制定规范•在进入软件开发阶段之初,首先应为软件开发组制定在设计时应该共同遵守的标准,以便协调组内各成员的工作。包括:–阅读和理解软件需求说明书,确认用户要求能否实现,明确实现的条件,从而确定设计的目标,以及它们的优先顺序–根据目标确定最合适的设计方法–规定设计文档的编制标准–规定编码的信息形式,与硬件,操作系统的接口规约,命名规则2.软件系统结构的总体设计•基于功能层次结构建立系统。–采用某种设计方法,将系统按功能划分成模块的层次结构–确定每个模块的功能–建立与已确定的软件需求的对应关系–确定模块间的调用关系–确定模块间的接口–评估模块划分的质量3.处理方式设计•确定为实现系统的功能需求所必需的算法,评估算法的性能•确定为满足系统的性能需求所必需的算法和模块间的控制方式–周转时间–响应时间–吞吐量–精度•确定外部信号的接收发送形式4.数据结构设计•确定软件涉及的文件系统的结构以及数据库的模式、子模式,进行数据完整性和安全性的设计•确定输入,输出文件的详细的数据结构•结合算法设计,确定算法所必需的逻辑数据结构及其操作•确定对逻辑数据结构所必需的那些操作的程序模块(软件包)•限制和确定各个数据设计决策的影响范围•若需要与操作系统或调度程序接口所必须的控制表等数据时,确定其详细的数据结构和使用规则•数据的保护性设计–防卫性设计:在软件设计中就插入自动检错,报错和纠错的功能•一致性设计:–保证软件运行过程中所使用的数据的类型和取值范围不变–在并发处理过程中使用封锁和解除封锁机制保持数据不被破坏•冗余性设计:针对同一问题,由两个开发者采用不同的程序设计风格不同的算法设计软件,当两者运行结果之差不在允许范围内时,利用检错系统予以纠正,或使用表决技术决定一个正确结果。5.可靠性设计•可靠性设计也叫做质量设计•在运行过程中,为了适应环境的变化和用户新的要求,需经常对软件进行改造和修正。在软件开发的一开始就要确定软件可靠性和其它质量指标,考虑相应措施,以使得软件易于修改和易于维护。6.编写概要设计阶段的文档•概要设计阶段完成时应编写以下文档:–概要设计说明书–数据库设计说明书–用户手册–制定初步的测试计划7.概要设计评审•可追溯性:确认该设计是否复盖了所有已确定的软件需求,软件每一成份是否可追溯到某一项需求•接口:确认该软件的内部接口与外部接口是否已经明确定义。模块是否满足高内聚和低耦合的要求。模块作用范围是否在其控制范围之内•风险:确认该设计在现有技术条件下和预算范围内是否能按时实现•实用性:确认该设计对于需求的解决方案是否实用•技术清晰度:确认该设计是否以一种易于翻译成代码的形式表达•可维护性:确认该设计是否考虑了方便未来的维护•质量:确认该设计是否表现出良好的质量特征•各种选择方案:看是否考虑过其它方案,比较各种选择方案的标准是什么•限制:评估对该软件的限制是否现实,是否与需求一致•其它具体问题:对于文档、可测试性、设计过程..等进行评估•在详细设计过程中,需要完成的工作是:–确定软件各个组成部分内的算法以及各部分的内部数据组织–选定某种过程的表达形式来描述各种算法。–进行详细设计的评审详细设计4.2软件设计基础自顶向下,逐步细化软件结构程序结构结构图模块化抽象化信息隐蔽自顶向下,逐步细化•将软件的体系结构按自顶向下方式,对各个层次的过程细节和数据细节逐层细化,直到用程序设计语言的语句能够实现为止,从而最后确立整个的体系结构。软件结构•软件结构包括两部分。程序的模块结构和数据的结构•软件的体系结构通过一个划分过程来完成。该划分过程从需求分析确立的目标系统的模型出发,对整个问题进行分割,使其每个部分用一个或几个软件成份加以解决,整个问题就解决了程序结构•程序结构表明了程序各个部件(模块)的组织情况,是软件的过程表示。结构图•结构图反映程序中模块之间的层次调用关系和联系:它以特定的符号表示模块、模块间的调用关系和模块间信息的传递①模块:模块用矩形框表示,并用模块的名字标记它。②模块的调用关系和接口:模块之间用单向箭头联结,箭头从调用模块指向被调用模块。③模块间的信息传递:当一个模块调用另一个模块时,调用模块把数据或控制信息传送给被调用模块,以使被调用模块能够运行。而被调用模块在执行过程中又把它产生的数据或控制信息回送给调用模块④在模块A的箭头尾部标以一个菱形符号,表示模块A有条件地调用另一个模块B。当一个在调用箭头尾部标以一个弧形符号,表示模块A反复调用模块C和模块D。程序的系统结构图模块化•软件系统的模块化是指整个软件被划分成若干单独命名和可编址的部分,称之为模块。这些模块可以被组装起来以满足整个问题的需求。•把问题/子问题的分解与软件开发中的系统/子系统或系统/模块对应起来,就能够把一个大而复杂的软件系统划分成易于理解的比较单纯的模块结构。抽象化•软件系统进行模块设计时,可有不同的抽象层次。•在最高的抽象层次上,可以使用问题所处环境的语言概括地描述问题的解法。•在较低的抽象层次上,则采用过程化的方法。(1)过程的抽象在软件工程中,从系统定义到实现,每进展一步都可以看做是对软件解决方法的抽象化过程的一次细化。在软件需求分析阶段,用“问题所处环境的为大家所熟悉的术语”来描述软件的解决方法。在从概要设计到详细设计的过程中,抽象化的层次逐次降低。当产生源程序时到达最低抽象层次。(2)数据抽象抽象是人类在认识复杂现象、解决复杂问题的过程中使用的最强有用的思维工具。•在现实世界中,一定事物、状态或过程之间总会存在某些相似的方面(共性),把这些相似的方面集中和概括起来,暂时忽略它们之间的差异,这就是抽象。•或者说抽象就是提取出事物的本质特性而暂时不考虑它们的细节。•由于人数思维能力的限制,如果一次面临的因素太多,是不可能做出精确思维的•设计复杂系统的惟一有效的方法是用层次的方式分析和构造它•一个复杂的软件系统应该首先用一些高级的抽象概念来理解和构造,这些高级概念又可以用一些较低级的概念来理解和构造,如此进行下去,直至最低层的具体元素信息隐蔽•由parnas方法提倡的信息隐蔽是指,每个模块的实现细节对于其它模块来说是隐蔽的。也就是说,模块中所包含的信息(包括数据和过程)不允许其它不需要这些信息的模块使用。模块的独立性•模块(Module)“模块”,又称“组件”。它一般具有如下三个基本属性:–功能:描述该模块实现什么功能–逻辑:描述模块内部怎么做–状态:该模块使用时的环境和条件•在描述一个模块时,还必须按模块的外部特性与内部特性分别描述•模块的外部特性–模块的模块名、参数表、其中的输入参数和输出参数,以及给程序以至整个系统造成的影响•模块的内部特性–完成其功能的程序代码和仅供该模块内部使用的数据4.3模块独立性–模块独立性,是指软件系统中每个模块只涉及软件要求的具体的子功能,而和软件系统中其它的模块的接口是简单的–例如,若一个模块只具有单一的功能且与其它模块没有太多的联系,则称此模块具有模块独立性–一般采用两个准则度量模块独立性。即模块间耦合和模块内聚–耦合是模块之间的互相连接的紧密程度的度量。–内聚是模块功能强度(一个模块内部各个元素彼此结合的紧密程度)的度量。–模块独立性比较强的模块应是高内聚低耦合的模块。模块间的耦合非直接耦合(NondirectCoupling)两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的。非直接耦合的模块独立性最强。数据耦合(DataCoupling)一个模块访问另一个模块时,彼此之间是通过简单数据参数(不是控制参数、公共数据结构或外部变量)来交换输入、输出信息的。标记耦合(StampCoupling)一组模块通过参数表传递记录信息,就是标记耦合。这个记录是某一数据结构的子结构,而不是简单变量。控制耦合(ControlCoupling)如果一个模块通过传送开关、标志、名字等控制信息,明显地控制选择另一模块的功能,就是控制耦合。外部耦合(ExternalCoupling)一组模块都访问同一全局简单变量而不是同一全局数据结构,而且不是通过参数表传递该全局变量的信息,则称之为外部耦合。公共耦合(CommonCoupling)若一组模块都访问同一个公共数据环境,则它们之间的耦合就称为公共耦合。公共的数据环境可以是全局数据结构、共享的通信区、内存的公共覆盖区等。•公共耦合的复杂程度随耦合模块的个数增加而显著增加。若只是两模块间有公共数据环境,则公共耦合有两种情况。松散公共耦合和紧密公共耦合。内容耦合(ContentCoupling)如果发生下列情形,两个模块之间就发生了内容耦合(1)一个模块直接访问另一个模块的内部数据;(2)一个模块不通过正常入口转到另一模块内部;(3)两个模块有一部分程序代码重迭(只可能出现在汇编语言中);(4)一个模块有多个入口。c模块内聚功能内聚(FunctionalCohesion)一个模块中各个部分都是完成某一具体功能必不可少的组成部分,或者说该模块中所有部分都是为了完成一项具体功能而协同工作,紧密联系,不可分割的。则称该模块为功能内聚模块。信息内聚(InformationalCohesion)这种模块完成多个功能,各个功能都在同一数据结构上操作,每一项功能有一个唯一的入口点。这个模块将根据不同的要求,确定该执行哪一个功能。由于这个模块的所有功能都是基于同一个数据结构(符号表),因此,它是一个信息内聚的模块。•信息内聚模块可以看成是多个功能内聚模块的组合,并且达到信息的隐蔽。即把某个数据结构、资源或设备隐蔽在一个模块内,不为别的模块所知晓。通信内聚(CommunicationCohesion)如果一个模块内各功能部分都使用了相同的输入数据,或产生了相同的输出数据,则称之为通信内聚模块。通常,通信内聚模块是通过数据流图来定义的。过程内聚(ProceduralCohesion)使用流程图做为工具设计程序时,把流程图中的某一部分划出组成模块,就得到过程内聚模块。例如,把流程图中的循环部分、判定部分、计算部分分成三个模块,这三个模块都是过程内聚模块。时间内聚(ClassicalCohesion)时间内聚又称为经典内聚。这种模块大多为多功能模块,但模块的各个功能的执行与时间有关,通常要求所有功能必须在同一时间段内执行。例如初始化模块和终止模块。逻辑内聚(LogicalCohesion)这种模块把几种相关的功能组合在一起,每次被调用时,由传送给模块的判定参数来确定该模块应执行哪一种功能。巧合内聚(CoincidentalCohesion)巧合内聚(偶然内聚)。当模块内各部分之间没有联系,或者即使有联系,这种联系也很松散,则称这种模块为巧合内聚模块,它是内聚程度最低的模块。4.4结构化设计方法•首先研究、分析和审查数据流图。从软件的需求