基于结构化方法编写软件设计说明
2022-07-07陈丽于霞李晓利余俊
陈丽 于霞 李晓利 余俊
(1.中国人民解放军63892部队 河南省洛阳市 471003 2.中国兵器工业导航与控制技术研究所 北京市 100000)
1 引言
软件设计是从软件需求出发,根据需求分析阶段确定的能力需求设计软件系统的整体架构、功能模块划分、接口设计以及模块实现的算法和数据结构要求。如果说软件需求阶段编写的软件需求规格说明文档记录了软件系统要“做什么”,那么在软件设计阶段就要明确软件系统“如何做”才能满足需求。软件设计阶段的输出是软件设计说明文档。如果说用户对你编写的软件需求规格说明文档还能看懂“你在说什么,说的全不全,对不对”的话,到了编写软件设计说明时,部分用户就已经看不懂你编写的软件设计说明文档是否满足相关要求了。加上很多软件设计说明是软件编码人员负责编写的,标准如何要求,如何把软件实现过程文档化,也是很多软件设计说明文档编写人员比较头疼的问题。
为了帮助用户读懂软件设计说明,也为了帮助软件设计说明编写者更好地落实标准要求,本文针对GJB438B-2009《军用软件开发文档通用要求》中关于软件设计说明文档的要求,详细阐述如何编写软件设计说明文档中的重要章节。
2 编写软件设计说明
软件设计说明文档中的主要章节和常出现问题的章节内容有设计决策、体系结构设计、执行方案、接口设计和详细设计等。本节基于结构化方法分别对以上内容如何编写进行详细阐述。
2.1 CSCI级设计决策
在GJB438B中,要求本章需分条给出软件的CSCI级设计决策。所谓CSCI设计决策,应是从其行为方面进行设计的决策,或者对其他影响组成该CSCI的软件单位的选择并进行设计的决策。如果在需求中已经明确了这些决策,或者有些决策需要推迟到软件单元设计时指出,那么,应在本章节相应位置明确加以叙述。此外,若是这些决策依赖于系统的状态或者方式,则应该指明它们的依赖性。
顾名思义,“决策”就是要写那些指导软件设计的顶层思路。也就是说,在进行决策时,应忽略CSCI内部的实现,站在用户的角度,详细描述系统运转时所要采用的方式方法,同时,还要说明影响CSCI软件单元的选择、设计的决策。根据标准要求,通常从以下几方面进行阐述:
CSCI将接收的输入和将产生的输出的设计决策。这个决策主要以CSCI为研究对象,描述外部环境对CSCI的影响,如其他系统、HWCI、CSCI和用户的接口等对本CSCI的输入和输出。有时,上述信息可能会在接口设计说明中给出全部或者部分的说明,这种情况下,可以直接引用接口设计说明文档即可。
CSCI对每一个输入或者条件的行为设计决策作出响应。决策关注的主要是CSCI的内部响应行为设计决策,主要包括内容有:针对每个输入或条件CSCI要执行的动作、响应的时间,及其他性能特性,选定的方程/算法/规则,模型化的物理系统的说明,以及CSCI对不允许的输入或条件需要进行的处理等。
CSCI数据显示的设计决策。这个决策主要关注CSCI的数据库或数据文件如何呈现给用户的,如用文字、图像、符号、表格、编辑框等。当上述信息在数据库设计说明中给出全部或部分的说明时,此处可以不必赘述,直接引用数据库设计说明文档即可。
CSCI安全性和保密性设计决策。这个决策主要从软件为了满足安全性和保密性要求而考虑将采取哪些措施选择哪些方法。如对输入信息进行合法性检查、防止信息误删除、数据库访问权限控制、数据传输的加密处理等措施。
其他CSCI设计决策。这个决策是除了上述分类说明的决策以外可能还有其他决策,应在此处说明。如软件灵活性设计决策、可用性和可维护性设计决策等。为了确保软件的灵活性需求,通常采用模块化的设计决策,易于扩展和使用维护。
该章节设计决策应与软件需求规格说明中明确的相关内容相一致。如果在软件需求规格说明中明确了保密性和安全性需求,那么在设计说明的本章节就要考虑如何落实这些需求,首先在设计决策上要进行考虑,然后指导后续的设计实现。
2.2 CSCI体系结构设计
GJB438B标准规定该章节应对CSCI体系结构设计进行分条描述。若是设计的全部或部分与系统的状态或方式存在依赖关系,应在文档中明确说明。而且如果有其他设计约定,在此处应明确说明或进行引用。
体系结构设计也称“架构设计”,是从高层抽象的角度刻画组成CSCI的部件以及它们之间的逻辑关联。基于结构化方法设计CSCI的体系结构是采用分层和部件的形式的表示。通常体系结构分层有三层:用户界面层、业务逻辑层、底层支撑层(也可称为“设备驱动层”),如图1所示。每一层包含若干CSCI的部件。分小节描述每个部件的用途、开发状态、分配的需求和设计决策、分配的计算机资源等信息。标识每个部件的软件放置在哪个程序库中。
图1:体系结构示意图
本节主要从静态角度刻画CSCI的体系结构和组成部件,下一节从动态角度进一步阐述每个部件的运行关系。
2.3 部件设计
本小节是上一节体系结构设计中的一个小章节。之所以将其独立成小节,是因为该节在体系结构设计章节的地位很重要,是CSCI体系结构设计章节的主体内容。
本节中需要对组成CSCI的所有软件单元进行明确的描述,并对明确的软件单位赋予一个项目唯一的标识符。此外,还需要说明软件单元的静态关系,如它们由哪些单元组成的。也要对软件单元的用途进行逐个说明,并指明与之相关的CSCI需求、CSCI级设计决策。另外,每个软件单元的开发状态或是类型,比如新研、重用还是改进,也应一并说明。说明CSCI中每个软件单元计划使用的计算机硬件资源,如处理机能力、内存能力、输入输出设备能力、辅助存储能力等。这些说明应该覆盖在CSCI的资源使用需求中、软件开发计划的资源使用策划中、以及影响该CSCI的系统级资源分配中等方面包含的全部的计算机硬件资源。若是在某一部分已经给出了针对指定计算机硬件资源所有使用数据,那么,在本节就可以直接引用。
在上一小节中我们重点介绍了体系架构设计,本小节详细介绍组成体系架构的元素,即组件或部件的设计方法。我们都知道部件是由单元组成,单元可以由更小的单元组成。在概要设计过程中,应尽早明确谁是配置项,谁是部件,谁是单元,然后按照这样的粒度进行后续的设计。
根据标准要求对部件进行设计,首先要唯一标识部件,并说明部件的用途。然后根据前面的设计,如决策设计、资源设计等,将这些设计分配到部件设计中。说明哪些部件应满足哪些设计决策,所需的计算机资源有哪些。以及这些部件将分配到哪个程序文件中。
在具体实现方式上,我们通常采用结构图(如图2所示)加属性表格的形式对其进行表述。
图2:CSCI的部件组成示意图
2.4 执行方案
GJB438标准要求在“执行方案”小节中应该对软件单元间的执行方案进行说明,可运用语言描述或者采用图表来说明软件单元之间的动态关系。所谓动态关系,指的是在CSCI运行期间,软件单元之间的相互作用的情况。结构化的执行方案表示方法通常采用执行控制流程、数据流,面向对象的表示方法通常采用时序图、动态控制序列,用以说明单元间的中断处理、优先关系、时序或排序关系、并发执行、例外处理、对象/进程/任务的动态创建或者删除、动态分配与去除分配,以及动态行为的其他方面等。
根据标准要求本节详细说明CSCI软件单元间的执行方案。因为软件单元的粒度是不确定的,一个功能需求可以称为一个部件也可以称为一个单元,因此在实际编写过程中,为了充分说明CSCI的运行过程,通常分为两个层次来说明执行方案:部件间执行方案和部件内执行方案。
为了说明软件部件间和软件部件内的相互作用,结构化的方法通常采用流程图(如图3所示)和数据流图(如图4所示)的形式加以描述。描述的要素主要有:名称和标识、功能描述、输入输出、行为处理、性能参数、异常处理、优先级顺序等。此外如果部件与人机界面有关,还应增加人机界面示意图。
图3:流程图示意图
图4:数据流图示意图
2.5 接口设计
在GJB438B中关于接口的要求都是一样的,无论是在需求规格说明文档还是在设计说明文档中。唯一区别是落实标准要求时,在需求规格说明中应重点阐述外部接口特性,在软件设计说明中要重点描述内部接口特性,因为在软件设计阶段,关注的内容就是软件自身是如何实现的。
本节中,应对每个接口赋予项目唯一的标识符,可以通过编号、名称、版本以及文档引用等要素来标识接口实体。接口标识应该能够对哪些实体具有固定的接口特性进行说明,也就是需要将接口需求分配给接口实体;也应说明哪些实体正在修改或是开发,以此对接口需求分配进行明确。
接口设计分为外部接口和内部接口。外部接口在需求规格说明中已详细描述,在此处可以将其拷贝过来,或者再简要描述一下外部接口实体和传递的信息。在描述内部接口时也应详细描述以下要素:接口类型、接口通信方法、接口协议、接口传递信息的数据和数据组合体,明确数据传输的信源和信宿。
接口的表示方式有接口图(如图5)和接口表(如表1)。
图5:内部接口的示意图
表1:一种接口详细信息示例表
原总装软件工程规范中将软件设计分为概要设计说明和详细设计说明,而GJB438B中只有软件设计说明。但是大家通常这么认为,软件设计说明到此处为止,以上内容属软件概要设计,如果甲方要求写软件概要设计说明,但是没有提供具体模板时,可以将软件设计说明中的详细设计章节删除算作软件概要设计说明。但是从一份文档的完整性上来讲,如果对GJB438B中软件设计说明文档进行了裁剪,而且裁剪的是技术内容时,就不能说裁剪后的文档仍然是遵循了GJB438B的标准规范。
2.6 CSCI详细设计
在软件工程领域要求“三分离”:需求、设计、实现三分离,如果将设计人员与实现人员进行分离,那么本节内容就尤为重要了。本节详细设计是直接指导软件编码实现的重要依据。
标准中要求本节应通过项目唯一标识符来标识软件单元,并对软件单元进行说明。说明的主要内容有:软件单元设计决策,比如使用的算法;软件单元设计中的任务约束、有关限定,或是非常规的特征;若是软件单元使用的编程语言与之前明确的不一致,需要给出说明,并给出使用的理由;要对软件软件单元包含的过程性命令进行说明或是列出组成过程性的命令组;当软件单元包含、接收或是输出数据时,应需要对其输入输出、数据元素组合体或是数据元素进行说明。软件单元的输入数据、输出数据应该与局部数据分开进行描述。若是软件单元是一个数据库,则应该引用对应的数据库设计说明;当软件单元包含逻辑时,需要对该软件单元所用到的逻辑给出说明。
详细设计关注的是软件单元间和单元内部的具体实现,是对体系结构设计的进一步细化和精化,是软件设计的最后一个环节。在这个章节中要求关注的要素主要有:软件单元的名称和标识、单元功能描述、输入输出、内部函数、局部变量、数据结构、处理流程、行为参数、异常处理等。
软件单元的详细设计粒度应具体到函数层级。详细说明软件单元由哪些函数组成,函数的参数有哪些,参数的返回值是什么类型,函数需要的全局数据或局部数据有哪些等等。此外,还包括函数的异常情况,即异常分支也应在此考虑。前面设计的性能指标,尤其是安全性、可靠性、保密性等非功能指标,在软件单位的详细设计中应重点考虑。因为如果此时不注意这些指标对设计的影响,那么这些问题都将在最后软件进行软件测试时暴露无疑,而且这种软件问题在软件编码完成后再进行修改,影响域是很大的。很多时候还出现越改越乱的情况。
采用结构化方法描述单元的详细设计时通常采用“一表加两图”的形式:用表格描述各个要素,用流程图和数据流图描述动态关系。
3 结束语
本文重点对GJB438B的《软件设计说明》文档中重要的和常出现问题的章节如何编写进行了详细分析,笔者结合多年文档审核经验和编写经验,指明了在依据标准要求进行编写时应注意的方面,给出了如何落实标准要求的具体的示例。
编写软件设计说明可以采用结构化的方法来写,也可以采用面向对象的方法来写,对嵌入式软件和FPGA软件通常采用结构化的描述方法会多些,其他软件采用结构化或面向对象的方法都比较多。这两种方法各有优点:结构化方法描述简单,容易上手,比较好理解,符合逐步细化的设计思路。面向对象方法要求有一定的UML基础,采用类和对象的描述方式进行设计,易于组件封装和重用。本文主要阐述了结构化的方法,后续将阐述如何用面向对象的方法编写软件设计说明。