第4章 系统开发和运行知识

    本章的主要内容包括软件工程基础知识、软件项目管理基础知识、软件过程改进、系统分析与设计基础知识,以及系统运行维护和系统评价基础知识等。

    在系统分析与系统设计知识部分,主要以结构化分析设计方法为主,面向对象分析与设计方法参见本书第10章。

    4.1 软件工程基础知识

    自从1968年首次提出“软件工程”这个名词以来,软件工程已经成为计算机软件的一个重要分支和研究方向。软件工程是指应用计算机科学、数学及管理科学等原理,以工程化的原则和方法来解决软件问题的工程,其目的是提高软件生产率、提高软件质量、降低软件成本。

    软件工程涉及到软件开发、维护、管理等多方面的原理、方法、工具与环境,限于篇幅,本章不能对软件工程做全面的介绍。根据软件设计师级考试大纲的要求,本章着重介绍软件开发过程中的原理,其他内容只作简单的介绍。

    4.1.1 软件工程概述

    早期的软件主要指程序,程序的开发采用个体工作方式,开发工作主要依赖于开发人员的个人技能和程序设计技巧。当时的软件通常缺少与程序有关的文档,软件开发的实际成本和进度往往与预计的相差甚远,软件的质量得不到保证,开发出来的软件常常不能使用户满意。随着计算机应用的需求不断增长,软件的规模也越来越大,然而软件开发的生产率远远跟不上计算机应用的迅速增长。此外,由于软件开发时缺少好的方法指导和工具辅助,同时又缺少相关文档,使得大量已有的软件难以维护。上述这些问题严重地阻碍了软件的发展,20世纪60年代中期,人们把上述软件开发和维护过程中所遇到的各种问题称为“软件危机”。

    1968年,在德国召开的NATO(North Atlantic Treaty Organization,北大西洋公约组织)会议上,首次提出了“软件工程”这个名词,希望用工程化的原则和方法来克服软件危机。在此以后,人们开展了软件开发模型、开发方法、工具与环境的研究,提出了瀑布模型、演化模型、螺旋模型和喷泉模型等开发模型,出现了面向数据流方法、面向数据结构的方法、面向对象方法等开发方法,以及一批CASE(Computer Aided Software Engineering,计算机辅助的软件工程)工具和环境。

    1.软件生存周期

    同任何事物一样,一个软件产品或软件系统也要经历孕育、诞生、成长、成熟、衰亡的许多阶段,一般称为软件生存周期。把整个软件生存周期划分为若干阶段,使得每个阶段有明确的任务,使规模大、结构复杂和管理复杂的软件开发变得容易控制和管理。通常,软件生存周期包括可行性分析与项目开发计划、需求分析、设计(概要设计和详细设计)、编码、测试、维护等活动,可以将这些活动以适当的方式分配到不同的阶段去完成。

    1)可行性分析与项目开发计划

    这个阶段主要确定软件的开发目标及其可行性。必须要回答的问题是:要解决的问题是什么?该问题有可行的解决办法吗?若有解决的办法,则需要多少费用?需要多少资源?需要多少时间?要回答这些问题,就要进行问题定义、可行性分析,制订项目开发计划。

    可行性分析与项目计划阶段的参加人员有用户、项目负责人和系统分析师。该阶段所产生的文档有可行性分析报告和项目开发计划。

    2)需求分析

    需求分析阶段的任务不是具体地解决问题,而是准确地确定软件系统必须做什么,确定软件系统的功能、性能、数据和界面等要求,从而确定系统的逻辑模型。该阶段的参加人员有用户、项目负责人和系统分析师。产生的文档有软件需求说明书。

    3)概要设计

    在概要设计阶段,开发人员要把确定的各项功能需求转换成需要的体系结构。在该体系结构中,每个成分都是意义明确的模块,即每个模块都和某些功能需求相对应,因此,概要设计就是设计软件的结构,明确软件由哪些模块组成,这些模块的层次结构是怎样的,这些模块的调用关系是怎样的,每个模块的功能是什么。同时,还要设计该项目的应用系统的总体数据结构和数据库结构,即应用系统要存储什么数据,这些数据是什么样的结构,它们之间有什么关系。

    概要设计阶段参加的人员有系统分析师和软件设计师。该阶段的主要文档有概要设计说明书。

    4)详细设计

    详细设计阶段的主要任务就是对每个模块完成的功能进行具体描述,要把功能描述转变为精确的、结构化的过程描述。即该模块的控制结构是怎样的,先做什么,后做什么,有什么样的条件判定,有些什么重复处理等,并用相应的表示工具把这些控制结构表示出来。

    详细设计阶段参加的人员有软件设计师和程序员。该阶段的主要文档有详细设计文档。

    5)编码

    编码阶段就是把每个模块的控制结构转换成计算机可接受的程序代码,即写成某种特定程序设计语言表示的源程序清单。

    6)测试

    测试是保证软件质量的重要手段,其主要方式是在设计测试用例的基础上检查软件的各个组成部分。测试阶段的参加人员通常由另一部门(或单位)的软件设计师或系统分析师承担。该阶段产生的文档有软件测试计划、测试用例和软件测试报告。

    7)维护

    软件维护是软件生存周期中时间最长的阶段。已交付的软件投入正式使用后,便进入软件维护阶段,它可以持续几年甚至几十年。软件运行过程中可能由于各方面的原因,需要对它进行修改。其原因可能是运行中发现了软件隐含的错误而需要修改;也可能是为了适应变化了的软件工作环境而需要做适当变更;也可能是因为用户业务发生变化而需要扩充和增强软件的功能;还可能是为将来的软件维护活动预先做准备等。

    2.软件生存周期模型

    软件生存周期模型是描述软件开发过程中各种活动如何执行的模型。软件生存周期模型确立了软件开发和演绎中各阶段的次序限制以及各阶段或机动的准则,确立开发过程所遵守的规定和限制,便于各种活动的协调,便于各种人员的有效通信,有利于活动重用,有利于活动管理。常见的软件生存周期模型有瀑布模型、演化模型、螺旋模型和喷泉模型等。

    1)瀑布模型(waterfall model)

    瀑布模型是将软件生存周期各个活动规定为依线性顺序连接的若干阶段的模型。它包括可行性分析、项目开发计划、需求分析、概要设计、详细设计、编码、测试和维护。它规定了由前至后、相互衔接的固定次序,如同瀑布流水,逐级下落。

    瀑布模型为软件的开发和维护提供了一种有效的管理模式,根据这一模式制定开发计划,进行成本预算,组织开发力量,以项目的阶段评审和文档控制为手段有效地对整个开发过程进行指导,所以它是以文档作为驱动、适合于软件需求很明确的软件项目的模型。

    但是,瀑布模型在大量的软件开发实践中也逐渐暴露出它的严重缺点。它是一种理想的线性开发模式,缺乏灵活性,特别是无法解决软件需求不明确或不准确的问题。

    2)演化模型(evolutionary model)

    大量的软件开发实践表明,许多开发项目在开始时对软件需求的认识是模糊的,因此很难一次开发成功。为了减少因对软件需求的了解不够确切而给开发工作带来的风险,可以在获取了一组基本的需求后,通过快速分析构造出该软件的一个初始可运行版本,这个初始的软件通常称为原型(Prototype),然后根据用户在使用原型的过程中提出的意见和建议对原型进行改进,获得原型的新版本。重复这一过程,最终可得到令用户满意的软件产品。采用演化模型的开发过程,实际上就是从初始的原型逐步演化成最终软件产品的过程。演化模型特别适用于对软件需求缺乏准确认识的情况。

    3)螺旋模型(spiral model)

    对于复杂的大型软件,开发一个原型往往达不到要求。螺旋模型将瀑布模型和演化模型结合起来,加入了两种模型均忽略的风险分析,弥补了这两种模型的不足。

    螺旋模型将开发过程分为几个螺旋周期,每个螺旋周期大致和瀑布模型相符合。在每个螺旋周期分为如下4个工作步。

    (1)制定计划。确定软件的目标,选定实施方案,明确项目开发的限制条件。

    (2)风险分析。分析所选的方案,识别风险,消除风险。

    (3)实施工程。实施软件开发,验证阶段性产品。

    (4)用户评估。评价开发工作,提出修正建议,建立下一个周期的开发计划。

    4)喷泉模型(water fountain model)

    喷泉模型是一种以用户需求为动力,以对象作为驱动的模型,适合于面向对象的开发方法。它克服了瀑布模型不支持软件重用和多项开发活动集成的局限性。喷泉模型使开发过程具有迭代性和无间隙性。迭代意味着模型中的开发活动常常需要重复多次,在迭代过程中不断地完善软件系统。无间隙是指在开发活动(如分析、设计、编码)之间不存在明显的边界,也就是说,它不像瀑布模型那样,需求分析活动结束后才开始设计活动,设计活动结束后才开始编码活动,而是允许各开发活动交叉、迭代地进行。

    3.软件开发方法

    软件开发方法是一种使用早已定义好的技术集及符号表示习惯来组织软件生产的过程。

    1)结构化方法

    结构化方法由结构化分析、结构化设计、结构化程序设计构成,它是一种面向数据流的开发方法。结构化分析是根据分解与抽象的原则,按照系统中数据处理的流程,用数据流图来建立系统的功能模型,从而完成需求分析工作。结构化设计是根据模块独立性准则、软件结构优化准则将数据流图转换为软件的体系结构,用软件结构图来建立系统的物理模型,实现系统的概要设计。结构化程序设计是根据结构程序设计原理,将每个模块的功能用相应的标准控制结构表示出来,从而实现详细设计。

    结构化方法总的指导思想是自顶向下、逐层分解,它的基本原则是功能的分解与抽象。它是软件工程中最早出现的开发方法,特别适合于数据处理领域的问题,但是不适合解决大规模的、特别复杂的项目,且难以适应需求的变化。

    2)Jackson方法

    Jackson方法是一种面向数据结构的开发方法。因为一个问题的数据结构与处理该数据结构的控制结构有着惊人的相似之处,该方法就是根据这一思想而形成了最初的JSP(Jackson Structure Programming)方法。首先描述问题的输入、输出数据结构,分析其对应性,然后推出相应的程序结构,从而给出问题的软件过程描述。

    JSP方法是以数据结构为驱动的,适合于小规模的项目。当输入数据结构与输出数据结构之间没有对应关系时,难以应用此方法。基于JSP方法的局限性,又发展了JSD(Jackson System Development)方法,它是JSP方法的扩充。

    JSD方法是一个完整的系统开发方法。首先建立现实世界的模型,再确定系统的功能需求,对需求的描述特别强调操作之间的时序性。它是以事件作为驱动的,是一种基于进程的开发方法,所以应用于时序特点较强的系统,包括数据处理系统和一些实时控制系统。

    3)原型化方法

    并非所有的需求都能够预先定义,而且反复修改是不可避免的。当然,能够采用原型化方法是因为开发工具的快速发展,使得可以迅速地开发出一个可以让用户看得见、摸得着的系统框架,这样,对于计算机不是很熟悉的用户就可以根据这个样板提出自己的需求。开发原型化系统首先确定用户需求,开发原始模型,然后征求用户对初始原型的改进意见,并根据意见修改原型。

    原型化开发比较适合于用户需求不清、业务理论不确定、需求经常变化的情况。当系统规模不是很大也不太复杂时,采用该方法是比较好的。

    4)面向对象开发方法

    面向对象开发方法的基本出发点是尽可能按照人类认识世界的方法和思维方法来分析和解决问题。客观世界是由许多具体的事物、事件、概念和规则组成,这些均可被看成对象,面向对象方法正是以对象作为最基本的元素,它也是分析问题、解决问题的核心。

    面向对象开发方法包括面向对象分析、面向对象设计和面向对象实现。面向对象开发方法有Booch方法、Coad方法和OMT方法等。为了统一各种面向对象方法的术语、概念和模型,1997年推出了统一建模语言(Unified Modeling Language, UML)。它是面向对象的标准建模语言,通过统一的语义和符号表示,使各种方法的建模过程和表示统一起来,已成为面向对象建模的工业标准。本节对面向对象方法不做详细讨论,详细内容参见本书第10章的面向对象方法。

    4.1.2 软件需求分析

    需求分析是软件生存周期中相当重要的一个阶段。由于开发人员熟悉计算机但不熟悉应用领域的业务,用户熟悉应用领域的业务但不熟悉计算机,因此对于同一个问题,开发人员和用户之间可能存在认识上的差异。在需求分析阶段,通过开发人员与用户之间的广泛交流,不断澄清一些模糊的概念,最终形成一个完整的、清晰的、一致的需求说明。可以说,需求分析的好坏将直接影响到所开发的软件的成败。

    1.需求分析的任务

    需求分析主要是确定待开发软件的功能、性能、数据和界面等要求。具体来说,可有以下几点。

    (1)确定软件系统的综合要求。

    ① 系统界面要求。描述软件系统的外部特性,即系统从外部输入哪些数据,系统向外部输出哪些数据。

    ② 系统的功能要求。列出软件系统必须完成的所有功能。

    ③ 系统的性能要求。如响应时间、吞吐量、处理时间、对主存和外存的限制等。

    ④ 安全性、保密性和可靠性方面的要求。

    ⑤ 系统的运行要求。如对硬件、支撑软件和数据通信接口等的要求。

    ⑥ 异常处理要求。在运行过程中出现异常情况(如临时性或永久性的资源故障,不合法或超出范围的输入数据、非法操作和数组越界等)时应采取的行动以及希望显示的信息。

    ⑦ 将来可能提出的要求。主要是为将来可能的扩充和修改作准备。

    (2)分析软件系统的数据要求。包括基本数据元素、数据元素之间的逻辑关系、数据量和峰值等。常用的数据描述手段是实体—关系模型。

    (3)导出系统的逻辑模型。在结构化分析方法中可用数据流图来描述;在面向对象分析方法中可用类模型来描述。

    (4)修正项目开发计划。在明确了用户的真正需求后,可以更准确地估算软件的成本和进度,从而修正项目开发计划。

    (5)如有必要,可开发一个原型系统。对一些需求不够明确的软件,可以先开发一个原型系统,以验证用户的需求。

    需要再次强调的是,需求分析阶段主要解决“做什么”的问题,而“怎么做”则由设计阶段来完成。

    2.需求的分类

    软件需求就是系统必须完成的事以及必须具备的品质。软件需求包括功能需求、非功能需求和设计约束三方面的内容。

    (1)功能需求。所开发的软件必须具备什么样的功能。

    (2)非功能需求。是指产品必须具备的属性或品质,如可靠性、性能、响应时间、容错性和扩展性等。

    (3)设计约束。也称为限制条件、补充规约,这通常是对解决方案的一些约束说明。

    3.软件需求分析方法

    需求分析方法由对软件的数据域和功能域的系统分析过程及其表示方法组成。它定义了表示系统逻辑视图和物理视图的方式。大多数的需求分析方法是由数据驱动的,也就是说,这些方法提供了一种表示数据域的机制,开发人员根据这种表示,确定软件功能及其他特性,最终建立一个待开发软件的抽象模型,即目标系统的逻辑模型。数据域具有三种属性:数据流、数据内容和数据结构。通常,一种需求分析方法总要利用其中的一种或几种属性。

    目前已经出现了许多需求分析方法,每一种分析方法都引入了不同的记号和分析策略,但是它们都具有以下的共性。

    (1)支持数据域分析的机制。

    (2)功能表示的方法。

    (3)接口的定义。

    (4)问题分解的机制以及对抽象的支持。

    (5)逻辑视图和物理视图。

    (6)系统抽象模型。

    4.需求工程

    需求工程就是包括创建和维护系统需求文档所必须的一切活动的过程,也就是指需求开发和需求管理两个工作。

    (1)需求开发。包括需求捕获、需求分析、编写规格说明书和需求验证四个阶段。在这个阶段需要确定产品所期望的用户类型、获取每种用户类型的需求、了解实际用户的任务和目标,以及这些任务所支持的业务需求、分析源于用户的信息、对需求进行优先级分类、将所搜集的需求编写成软件规格说明书和需求分析模型、对需求进行评审等工作。

    (2)需求管理。通常包括定义需求基线、处理需求变更和需求跟踪等方面的工作。

    4.1.3 软件开发项目管理

    软件项目管理的对象是软件项目。为了使软件项目开发获得成功,必须对软件开发项目的工作范围、可能遇到的风险、需要的资源(人、硬/软件)、要实现的任务、经历的里程碑、花费的工作量(成本)以及进度的安排等做到心中有数。而软件项目管理可以提供这些信息。这种管理的范围覆盖了整个软件工程过程,即开始于技术工作开始之前,在软件从概念到实现的过程中持续进行,最后终止于软件工程过程结束。

    1.成本估算

    由于软件具有可见性差、定量化难等特殊性,因此很难在项目完成前准确地估算出开发软件所需的工作量和费用。通常可以根据以往开发类似软件的经验(也可以是别人的经验)来进行成本估算。也可以将软件项目划分成若干个子系统或按照软件生存周期的各个阶段分别估算其成本,然后汇总出整个软件的成本。此外,还可以使用经验公式和成本估算模型来进行估算。

    1)成本估算方法

    (1)自顶向下估算方法。估算人员参照以前完成的项目所耗费的总成本(或总工作量),来推算将要开发的软件的总成本(或总工作量),然后把它们按阶段、步骤和工作单元进行分配,这种方法称为自顶向下估算方法。

    自顶向下估算方法的主要优点是对系统级工作的重视,所以估算中不会遗漏诸如集成、配置管理之类的系统级事务的成本估算,且估算工作量小、速度快。它的缺点是往往不清楚低级别上的技术性困难问题,而这些困难将会使成本上升。

    (2)自底向上估算方法。自底向上估算方法是将待开发的软件细分,分别估算每一个子任务所需要的开发工作量,然后将它们加起来,得到软件的总开发量。这种方法的优点是对每一部分的估算工作交给负责该部分工作的人来做,所以估算较为准确。其缺点是其估算往往缺少各项子任务之间相互联系所需要的工作量和与软件开发有关的系统级工作量,所以估算往往偏低。

    (3)差别估算方法。差别估算方法的思想是将待开发项目与一个或多个已完成的类似项目进行比较,找出与某个相类似项目的若干不同之处,并估算每个不同之处对成本的影响,导出待开发项目的总成本。该方法的优点是可以提高估算的准确度,缺点是不容易明确“差别”的界限。

    除了以上方法之外,还有专家估算法、类推估算法和算式估算法等。

    · 专家估算法。依靠一个或多个专家对要求的项目做出估算,其精确性取决于专家估算项目的定性参数的了解和他们的经验。

    · 类推估算法。在自顶向下的方法中,它是将估算项目的总体参数与类似项目进行直接比较得到结果;在自底向上方法中,类推是在两个具有相似条件的工作单元之间进行。

    · 算式估算法。专家估算法和类推估算法的缺点在于它们依靠带有一定盲目性和主观性的猜测对项目进行估算。算式估算法则是企图避免主观因素的影响。用于估算的方法有两种基本类型:由理论导出和由经验导出。

    2)成本估算模型

    常用的软件成本估算模型有Putnam模型和COCOMO模型。

    Putnam模型是一种动态多变量模型,它是假设在软件开发的整个生存期中工作量有特定的分布。

    结构性成本模型COCOMO是最精确、最易于使用的成本估算模型之一。该模型可以分为如下几种。

    (1)基本COCOMO模型。是一个静态单变量模型,它是对整个软件系统进行估算。

    (2)中级COCOMO模型。是一个静态多变量模型,它将软件系统模型分为系统和部件两个层次,系统由部件构成,它把软件开发所需人力(成本)看作是程序大小和一系列“成本驱动属性”的函数。

    (3)详细COCOMO模型。它将软件系统模型分为系统、子系统和模块三个层次,它除包括中级模型所考虑的因素外,还考虑了在需求分析、软件设计等每一步的成本驱动属性的影响。

    2.风险分析

    当在软件工程环境中考虑风险时,主要是基于关心未来、关心变化、关心选择这三个概念提出的。在进行软件工程分析时,项目管理人员要进行4种风险评估活动,包括建立表示风险概念的尺度,描述风险引起的后果,估计风险影响的大小,确定风险估计的正确性。

    风险分析实际上是4个不同的活动:风险识别,风险预测,风险评估和风险控制。

    1)风险识别

    风险识别是试图系统化地确定对项目计划(估算、进度、资源分配)的威胁。风险识别的一种方法是建立风险条目检查表。该检查表可以用于识别风险,并使得人们集中来识别下列常见的已知的及可预测的风险。

    (1)产品规模。与要建造或要修改的软件的总体规模相关的风险。

    (2)商业影响。与管理或市场所加诸的约束相关的风险。

    (3)客户特性。与客户的素质以及开发者和客户定期通信的能力相关的风险。

    (4)过程定义。与软件过程被定义的程度以及它们被开发组织所遵守的程序相关的风险。

    (5)开发环境。与用以构建产品的工具的可用性及质量相关的风险。

    (6)构建的技术。与待开发软件的复杂性及系统所包含技术的“新奇性”相关的风险。

    (7)人员数目及经验。与参与工作的软件工程师的总体技术水平及项目经验相关的风险。

    2)风险预测

    风险预测,又称风险估算,它从两个方面评估一个风险:风险发生的可能性或概率;以及如果风险发生了,所产生的后果。通常,项目计划人员与管理人员、技术人员一起进行4种风险预测活动。

    (1)建立一个尺度或标准,以反映风险发生的可能性。

    (2)描述风险的后果。

    (3)估计风险对项目和产品的影响。

    (4)标注风险预测的整体精确度,以免产生误解。

    3)风险评估

    在进行风险评估时,建立了如下形式的三元组:

    alt

    其中,ri表示风险,li表示风险发生的概率,xi则表示风险产生的影响。

    一种对风险评估很有用的技术就是定义风险参照水准。对于大多数软件项目来说,成本、进度和性能就是三种典型的风险参照水准。也就是说,对于成本超支、进度延期、性能降低(或它们的某种组合),有一个表明导致项目终止的水准。

    在风险评估过程中,需要执行以下4个步骤。

    (1)定义项目的风险参考水平值。

    (2)建立每一组(ri,li,xi)与每一个参考水平值之间的关系。

    (3)预测一组临界点以定义项目终止区域,该区域由一条曲线或不确定区域所界定。

    (4)预测什么样的风险组合会影响参考水平值。

    4)风险控制

    这一步的所有风险分析活动只有一个目的——辅助项目组建立处理风险的策略。一个有效的策略必须考虑如下三个问题。

    (1)风险避免。

    (2)风险监控。

    (3)风险管理及意外事件计划。

    如果软件项目组对于风险采用主动的方法,则避免永远是最好的策略。这可以通过建立一个风险缓解计划来达到。

    风险管理策略可以包含在软件项目计划中,或者风险管理步骤也可以组织成一个独立的风险缓解、监控和管理计划(RMMM计划)。RMMM计划将所有风险分析工作文档化,并由项目管理者作为整个项目计划中的一部分来使用。

    3.进度管理

    进度的合理安排是如期完成软件项目的重要保证,也是合理分配资源的重要依据,因此进度安排是管理工作的一个重要组成部分。软件开发项目的进度安排有如下两种方式。

    (1)系统最终交付日期已经确定,软件开发部门必须在规定期限内完成。

    (2)系统最终交付日期只确定了大致的年限,最后交付日期由软件开发部门确定。

    进度安排的常用图形描述方法有Gantt图(甘特图)和项目计划评审技术(Program Evaluation & Review Technique, PERT)图。

    1)Gantt图

    Gantt图是一种简单的水平条形图,它以日历为基准描述项目任务。水平轴表示日历时间线(如时、天、周、月和年等),每个条形表示一个任务,任务名称垂直地列在左边的列中,图中水平条的起点和终点对应水平轴上的时间,分别表示该任务的开始时间和结束时间,水平条的长度表示完成该任务所持续的时间。当日历中同一时段存在多个水平条时,表示任务之间的并发。图4-1所示的Gantt图描述了三个任务的进度安排。任务1首先开始,完成它需要6个月时间;任务2在1个月后开始,完成它需要9个月时间;任务3在6个月后开始,完成它需要5个月时间。

    alt

    图4-1 Gantt图实例

    Gantt图能清晰地描述每个任务从何时开始,到何时结束,任务的进展情况以及各个任务之间的并行性。但是它不能清晰地反映出各任务之间的依赖关系,难以确定整个项目的关键所在,也不能反映计划中有潜力的部分。

    2)PERT图

    PERT图是一个有向图,图中的箭头表示任务,它可以标上完成该任务所需的时间;图中的节点表示流入节点的任务的结束,并开始流出节点的任务,这里把节点称为事件。只有当流入该节点的所有任务都结束时,节点所表示的事件才出现,流出节点的任务才可以开始。事件本身不消耗时间和资源,它仅表示某个时间点。一个事件有一个事件号和出现该事件的最早时刻和最迟时刻。最早时刻表示在此时刻之前从该事件出发的任务不可能开始;最迟时刻表示从该事件出发的任务必须在此时刻之前开始,否则整个工程就不能如期完成。每个任务还可以有一个松弛时间(slack time),表示在不影响整个工期的前提下,完成该任务有多少机动余地。为了表示任务间的关系,图中还可以加入一些空任务(用虚线箭头表示),完成空任务的时间为0。

    图4-2是PERT图的一个实例。不难看出,图4-2中的松弛时间为0的这些任务是完成整个工程的关键路径,其事件流为1→2→3→4→6→8→10→11。

    PERT图不仅给出了每个任务的开始时间、结束时间和完成该任务所需的时间,还给出了任务之间的关系,即哪些任务完成后才能开始另外一些任务,以及如期完成整个工程的关键路径。图中的松弛时间则反映了完成某些任务时可以推迟其开始时间或延长其所需完成的时间。但是,PERT图不能反映任务之间的并行关系。

    alt

    图4-2 PERT图实例

    4.人员管理

    合理地组织好参加软件项目的人员,有利于发挥每个人的作用,有利于软件项目的成功开发。在人员组织时,应考虑软件项目的特点、软件人员的素质等多方面的因素。

    可以按软件项目对软件人员分组,如需求分析组、设计组、编码组、测试组和维护组等,为了控制软件的质量,还可以有质量保证组。

    程序设计小组的组织形式也可以有多种,如主程序员组、无主程序员组和层次式程序员组等。

    (1)主程序员组。主程序员组由一名主程序员、一名后备程序员(back up programmer)、一名资料员和若干名程序员组成。主程序员由经验丰富、能力强的高级程序员担任,他是该组织的技术领导和项目负责人,全面负责软件项目的开发。后备程序员是主程序员的助手,协助主程序员工作,必要时能代替主程序员工作。资料员负责保存和管理所有的软件配置元素,如文档资料、程序清单和存储介质等,还编译和链接代码、对提交的所有模块进行初步的测试。程序员则集中精力负责完成主程序员分配给他最擅长的任务——编程。这种组织形式便于集中领导,步调统一,容易按规范办事,但不利于发挥个人的积极性。

    (2)无主程序员组。无主程序员组中的成员之间相互平等,工作目标和决策都由全体成员民主讨论,根据需要也可以轮流坐庄。这种组民主气氛比较足,依赖个人的成分少,有利于发挥每个人的积极性。但这种组中交流量大,往往职责不明确,出了问题谁也不负责,而且不利于与外界的联系。

    (3)层次式程序员组。层次式组中有一位组长,组长负责全面的工作,他领导若干名高级程序员,每个高级程序员又领导若干名程序员。这种组适合于具有层次结构特点的更大型的软件项目,该项目可分成若干个子项目,每个高级程序员负责一个子项目,然后再对子项目分解,并分配给程序员。

    4.1.4 软件配置管理

    在软件建立时变更是不可避免的,而变更时由于没有进行变更控制,可能加剧了项目中的混乱,为协调软件开发使得混乱减到最小,使用配置管理技术,使变更所产生的错误达到最小并最有效地提高生产率。

    软件配置管理(Software Configure Management, SCM)用于整个软件工程过程。其主要目标是标识变更;控制变更;确保变更正确地实现;报告有关变更。SCM是一组管理整个软件生存期各阶段中变更的活动。

    1.基线

    基线是软件生存期中各开发阶段的一个特定点,它的作用是把开发各阶段工作的划分更加明确化,使本来连续的工作在这些点上断开,以便于检查与肯定阶段成果。因此,基线可以作为一个检查点,在开发过程中,当采用的基线发生错误时,可以知道所处的位置,返回到最近和最恰当的基线上。

    2.软件配置项

    软件配置项(Software Configure Item, SCI)是软件工程中产生的信息项,它是配置管理的基本单位,对已经成为基线的SCI,虽然可以修改,但必须按照一个特殊的、正式的过程进行评估,确认每一处修改。以下的SCI是SCM的对象,并可形成基线。

    (1)系统规格说明书。

    (2)软件项目实施计划。

    (3)软件需求规格说明书。

    (4)设计规格说明书(数据设计、体系结构设计、模块设计、接口设计、对象描述(使用面向对象技术时))。

    (5)源代码清单。

    (6)测试计划和过程、测试用例和测试结果记录。

    (7)操作和安装手册。

    (8)可执行程序(可执行程序模块、连接模块)。

    (9)数据库描述(模式和文件结果、初始内容)。

    (10)用户手册。

    (11)维护文档(软件问题报告、维护请求、工程变更次序)。

    (12)软件工程标准。

    (13)项目开发小结。

    此外,许多软件工程组织把配置控制之下的软件工具,即编辑程序、编译程序、其他CASE工具的特定版本都作为软件配置的一部分列入其中。

    3.版本控制

    软件配置实际上是一个动态的概念,它一方面随着软件生存期向前推进,SCI的数量在不断增多,一些文档经过转换生成另一些文档,并产生一些信息;另一方面又随时会有新的变更出现,形成新的版本。

    alt

    图4-3 版本演变

    表达系统不同版本的一种表示如图4-3所示的演变图,在图中各个节点是一个完全的软件版本。软件的每一个版本都是SCI(源代码、文档、数据)的一个汇集,且各个版本都可能由不同的变种组成。

    4.变更控制

    软件工程过程中某一阶段的变更,均要引起软件配置的变更,这种变更必须严格加以控制和管理,保持修改信息,并把精确、清晰的信息传递到软件工程过程的下一步骤。

    对于一个大型软件来说,不加控制的变更很快就会引起混乱。因此,变更控制是一项最重要的软件配置任务。为有效地实现变更控制,需借助于配置数据库和基线的概念。

    配置数据库可以分为如下三类。

    (1)开发库。专供开发人员使用,其中的信息可能作频繁修改,对其控制相当宽松。

    (2)受控库。在生存期某一阶段工作结束时发布的阶段产品,这些是与软件开发工作相关的计算机可读信息和人工可读信息。软件配置管理正是对受控库中的各个软件项进行管理,受控库也称为软件配置库。

    (3)产品库。在开发的软件产品完成系统测试后,作为最终产品存入产品库,等待交付用户或现场安装。

    4.1.5 软件工具与软件开发环境

    用来辅助软件开发、运行、维护、管理和支持等过程中的活动的软件称为软件工具。早期的软件工具主要用来辅助程序员编程,如编辑程序、编译程序和排错程序等。在提出了软件工程的概念以后,又出现了软件生存周期的概念,出现了许多开发模型和开发方法,同时软件管理也开始受到人们的重视。与此同时,出现了一批软件工具来辅助软件工程的实施,这些软件工具涉及到软件开发、维护、管理过程中的各项活动,并辅助这些活动高效、高质量地进行。因此,软件工具通常也称为CASE工具。

    软件开发环境是指支持软件产品开发的软件系统,它由软件工具集和环境集成机制构成。工具集应包括支持软件开发相关过程、活动、任务的软件工具,以对软件开发提供全面的支持。环境集成机制为工具集成和软件开发、维护和管理提供统一的支持,通常包括数据集成、控制集成和界面集成。

    1.软件工具

    软件工具的种类繁多,很难有一种统一的分类方法,通常从不同的观点来进行分类。由于大多数软件工具仅支持软件生存周期过程中的某些特定活动,因此通常可以按软件过程的活动来进行分类。

    1)软件开发工具

    对应于软件开发过程的各种活动,软件开发工具通常有需求分析工具、设计工具、编码与排错工具、测试工具等。

    (1)需求分析工具。用以辅助软件需求分析活动的软件称为需求分析工具,它辅助系统分析员从需求定义出发,生成完整的、清晰的、一致的功能规范(functional specification)。功能规范是软件所要完成功能的准确而完整的陈述,它描述该软件要做什么及只做什么。

    按照需求定义的方法可将需求分析工具分为基于自然语言或图形描述的工具和基于形式化需求定义语言的工具。

    (2)设计工具。用以辅助软件设计活动的软件称为设计工具,它辅助设计人员从软件功能规范出发,得到相应的设计规范(design specification)。对应于概要设计活动和详细设计活动,设计工具通常可分为概要设计工具和详细设计工具。

    概要设计工具用以辅助设计人员设计目标软件的体系结构、控制结构和数据结构,详细设计工具用以辅助设计人员设计模块的算法和内部实现细节。除此之外,还有基于形式化描述的设计工具和面向对象分析与设计工具。

    (3)编码与排错工具。辅助程序员进行编码活动的工具有编码工具和排错工具。编码工具辅助程序员用某种程序设计语言编制源程序,并对源程序进行翻译,最终转换成可执行的代码。因此,编码工具通常与编码所使用的程序语言密切相关。排错工具用来辅助程序员寻找源程序中错误的性质和原因,并确定其出错的位置。

    (4)测试工具。用于支持进行软件测试的工具称为测试工具,分为数据获取工具、静态分析工具、动态分析工具、模拟工具以及测试管理工具。其中,静态分析工具通过对源程序的程序结构、数据流和控制流进行分析,得出程序中函数(过程)的调用与被调用关系、分支和路径、变量定义和引用等情况,发现语义错误。动态分析工具通过执行程序,检查语句、分支和路径覆盖,测试有关变量值的断点,即对程序的执行流进行探测。

    2)软件维护工具

    辅助软件维护过程中活动的软件称为软件维护工具,它辅助维护人员对软件代码及其文档进行各种维护活动。软件维护工具主要有版本控制工具、文档分析工具、开发信息库工具、逆向工程工具和再工程工具。

    (1)版本控制工具。在软件开发和维护过程中,一个软件往往有多个版本,版本控制工具用来存储、更新、恢复和管理一个软件的多个版本。

    (2)文档分析工具。文档分析工具用来对软件开发过程中形成的文档进行分析,给出软件维护活动所需的维护信息。例如,基于数据流图的需求文档分析工具可给出对数据流图的某个成分(如加工)进行维护时的影响范围及被影响范围,以便在该成分修改的同时考虑其影响范围内的其他成分是否也要修改。除此之外,利用文档分析工具还可以得到被分析文档的有关信息,如文档各种成分的个数、定义及引用情况等。

    (3)开发信息库工具。开发信息库工具用来维护软件项目的开发信息,包括对象、模块等。它记录每个对象的修改信息(已确定的错误及重要改动)和其他变形(如抽象数据结构的多种实现),还必须维护对象和与之有关信息之间的关系。

    (4)逆向工程工具。逆向工程工具辅助软件人员将某种形式表示的软件(源程序)转换成更高抽象形式表示的软件。这种工具力图恢复源程序的设计信息,使软件变得更容易理解。逆向工程工具分为静态的和动态的两种。

    (5)再工程工具。再工程工具用来支持重构一个功能和性能更为完善的软件系统。目前的再工程工具主要集中在代码重构、程序结构重构和数据结构重构等方面。

    3)软件管理和软件支持工具

    软件管理和软件支持工具用来辅助管理人员和软件支持人员的管理活动和支持活动,以确保软件高质量地完成。辅助软件管理和软件支持的工具很多,其中常用的工具有项目管理工具、配置管理工具和软件评价工具。

    (1)项目管理工具。项目管理工具用来辅助软件的项目管理活动。通常项目管理活动包括项目的计划、调度、通信、成本估算、资源分配及质量控制等。一个项目管理工具通常把重点放在某一个或某几个特定的管理环节上,而不提供对管理活动包罗万象的支持。

    (2)配置管理工具。配置管理工具用来辅助完成软件配置项的标识、版本控制、变化控制、审计和状态统计等基本任务,使得各配置项的存取、修改和系统生成易于实现,从而简化了审计过程,改进状态统计,减少错误,提高系统的质量。

    (3)软件评价工具。软件评价工具用来辅助管理人员进行软件质量保证的有关活动。它通常可以按照某个软件质量模型(如McCall软件质量模型,ISO软件质量度量模型等)对被评价的软件进行度量,然后得到相关的软件评价报告。软件评价工具有助于软件质量控制,对确保软件质量有重要的作用。

    软件工具的种类非常多,上面只列举了一些主要的也是常用的工具。软件工具可以从不同的角度进行分类,上述分类只是其中较流行的一种,而且这种分类并非是严格的,有些工具可以属于这一类,也可以属于另一类。

    2.软件开发环境

    软件开发环境(software development environment)是支持软件产品开发的软件系统。它由软件工具集和环境集成机制构成,前者用来支持软件开发的相关过程、活动和任务;后者为工具集成和软件开发、维护和管理提供统一的支持,通常包括数据集成、控制集成和界面集成。通过环境集成机制,各工具用统一的数据接口规范存储或访问环境信息库;各工具采用统一的界面形式,保证各工具界面的一致性,同时为各工具或开发活动之间的通信、切换、调度和协同工作提供支持。在软件开发环境中进行软件开发,可以使用环境中提供的各种工具,同时在环境信息库的支持下,一个工具所产生的结果信息可以为其他工具利用,使得软件开发的各项活动得到连续的支持,从而大大提高了软件的开发效率,提高了软件的质量。

    软件开发环境的特征如下。

    (1)环境的服务是集成的。软件开发环境应支持多种集成机制,如平台集成、数据集成、界面集成、控制集成和过程集成等。

    (2)环境应支持小组工作方式,并为其提供配置管理。

    (3)环境的服务可用于支持各种软件开发活动,包括分析、设计、编程、测试、调试和文档等。

    集成型开发环境是一种把支持多种软件开发方法和开发模型的软件工具集成在一起的软件开发环境。这种环境应该具有开放性和可剪裁性。开放性为环境外的工具集成到环境中来提供了方便,可剪裁性可根据不同的应用和不同的用户需求进行剪裁,以形成特定的开发环境。

    3.计算机辅助软件工程

    CASE是一组工具和方法的集合,可以辅助软件开发生命周期各阶段进行软件开发。CASE把软件开发技术、软件工具和软件开发方法集成到一个统一而一致的框架中,并且吸收了CAD(计算机辅助设计)、软件工程、操作系统、数据库、网络和许多其他计算机领域的原理和技术。

    4.1.6 软件过程管理

    软件过程是软件生存周期中的一系列相关活动,即用于开发和维护软件及相关产品的一系列活动。

    软件产品的质量取决于软件开发过程,具有良好软件过程的软件机构能够开发出高质量的软件产品。这一点虽然早已为人们公认,但切实地在软件过程方面开展工作也只是十多年前的事。1987年,在美国国防部支持下,卡内基·梅隆大学率先推出了软件工程评估项目的研究成果——软件过程能力成熟度模型(CMM)。很快就引起了软件界的广泛关注,并在此后引发了一系列反响,以至在其基础上形成了国际标准(ISO/IEC 15504)。

    1.软件过程评估的意义

    软件过程评估是软件改进和软件能力评价的前提环节。

    1)软件过程改进的需要

    (1)软件过程不断改进是软件工程的基本原理之一。

    1983年,美国TRW公司的B. W. Boehm总结了该公司在12年内总共花了15000人年,先后开发5代指挥控制软件的经验,得出了以下7条原则。

    ① 按软件生存周期分阶段制定计划并认真实施。

    ② 逐阶段进行确认。

    ③ 坚持严格的产品控制。

    ④ 使用现代程序设计技术。

    ⑤ 明确责任。

    ⑥ 用人少而精。

    ⑦ 不断改进开发过程。

    这就是著名的软件工程七原理。由此可见,不断改进软件开发过程是软件工程的基本原理之一。

    (2)软件过程改进是软件生存周期的基本过程之一。

    软件工程界始终十分重视对软件过程的研究。20世纪70年代中期形成了软件生存周期的概念,1995年正式发布了一项国际标准,即ISO/IEC 12207信息技术——软件生存周期过程,这是软件过程研究的一个重要成果。这项标准科学地定义了软件生存周期的过程,总共17个,其中一个就是改进过程。

    2)降低软件风险的需要

    (1)软件采购者的需要。软件产品或软件服务的采购单位进行招标、选择承制者时,为了降低风险,需要对备选单位的软件过程能力进行评价,而这种评价的依据是对该单位的软件过程的评估结果。

    (2)软件承制者的需要。软件产品研制单位和软件服务单位在响应顾客的需要、进行投标时,为了降低风险,需要对自己的软件过程能力进行评价,避免承担力所不及的任务,而这种评价的依据仍然是根据实际需要,对相应软件过程的评估结果。

    2.软件能力成熟度模型简介

    1)软件能力成熟度模型简介

    软件能力成熟度模型是对软件组织进化阶段的描述,随着软件组织定义、实施、测量、控制和改进其软件过程,软件组织的能力经过这些阶段逐步前进。这个能力成熟度模型使软件组织能够较容易地确定其当前过程的成熟度并识别出其软件过程执行中的薄弱环节,确定对软件质量和过程改进最为关键的几个问题,从而形成对其过程的改进策略。软件组织只要关注并认真实施一组有限的关键实践活动,就能稳步地改善其全组织的软件过程,使全组织的软件过程能力持续增长。

    软件过程能力成熟度模型将软件过程能力成熟度划分为如下5级。

    (1)初始级(initial)。软件过程是无序的,有时甚至是混乱的,对过程几乎没有定义,项目的成功完全依赖个人努力和英雄式核心人物。

    (2)可重复级(repeatable)。建立了基本的项目管理过程和实践来跟踪项目费用、进度和功能特性。制定了必要的过程纪律,能重复早先类似应用项目取得的成功。

    (3)已定义级(defined)。已将软件管理和工程两方面的过程文档化、标准化,并综合成该组织的标准软件过程。所有项目均使用经批准、剪裁的标准软件过程来开发和维护软件。

    (4)已管理级(managed)。收集对软件过程和产品质量的详细度量,对软件过程和产品都有定量的理解与控制。

    (5)优化级(optimized)。过程的量化反馈和先进的新思想、新技术促使过程不断改进。

    每一个成熟度等级为过程改进达到下一个等级提供一个基础。当前一个等级没有达到时,不能进入下一个等级。

    2)能力成熟度集成模型

    能力成熟度集成模型(Capacity Maturity Model Integrated, CMMI)是CMM模型的最新版本。随着应用的推广与模型本身的发展,该方法演绎成为一种被广泛应用的综合性模型。

    CMMI有两种不同的表述方式,不同的表述方式,其级别表示不同的内容。CMMI的一种表述方式为连续表述,主要是关注某特定域的过程改进和能力评估;另一种表述方式为阶段式,主要是衡量一个企业的成熟度,而不把单个过程是否完成作为重点。

    和CMM的5个成熟度等级一样,基于阶段式表述的CMMI有5个成熟度级别:初始级、已管理级、已定义级、量化管理级(quantitatively managed)和优化级。这5个成熟度等级中,要一级一级逐级进行。每一个成熟度等级为过程改进达到下一个等级提供基础。企业在实施CMMI的时候,当前一个等级没有达到时,不能进入下一个等级。

    基于连续表述的CMMI共有6个(0~5)能力等级,未完整级(incomplete)、已执行级(performed)、已管理级、已定义级、量化管理级和优化级。这样的描述方式主要强调能力度等级,一个过程是否完成非常重要,因此分为6个等级。每个能力等级对应到一个一般目标,以及一组一般执行方法和特定方法。

    3.统一过程(UP)

    统一过程模型是一种“用例和风险驱动,以架构为中心,迭代并且增量”的开发过程,由UML方法和工具支持。迭代的意思是将整个软件开发项目划分为许多个小的“袖珍项目”,每个“袖珍项目”都包含正常软件项目的所有元素:计划、分析和设计、构造、集成和测试,以及内部和外部发布。

    统一过程定义了5个阶段及其制品。

    (1)起始阶段。专注于项目的初创活动。产生的主要工作产品有愿景文档、初始用例模型、初始项目术语表、初始业务用例、初始风险评估、项目计划(阶段及迭代)、业务模型以及一个或多个原型(需要时)。

    (2)精化阶段。理解了最初的领域范围之后,进行需求分析和架构演进方面。产生的主要工作产品有用例模型、补充需求(包括非功能需求)、分析模型、软件体系结构描述、可执行的软件体系结构原型、初步的设计模型、修订的风险列表、项目计划(包括迭代计划、调整的工作流、里程碑和技术工作产品)以及初始用户手册。

    (3)构建阶段。关注系统的构建,产生实现模型。产生的主要工作产品有设计模型、软件构件、集成的软件增量、测试计划及步骤、测试用例以及支持文档(用户手册、安装手册和对于并发增量的描述)。

    (4)移交阶段。关注于软件提交方面的工作,产生软件增量。产生的主要工作产品有提交的软件增量、β测试报告和综合用户反馈。

    (5)产生阶段。运行软件并监控软件的持续使用,提供运行环境的支持,提交并评估缺陷报告和变更请求。

    每次迭代产生包括最终系统的部分完成的版本和任何相关的项目文档的基线,通过逐步迭代基线之间相互构建,直到完成最终系统。在每个迭代中,有5个核心工作流:捕获系统应该做什么的需求工作流,精化和结构化需求的分析工作流,在系统构架内实现需求的设计工作流,构造软件的实现工作流,验证实现是否如期望那样工作的测试工作流。随着UP的阶段进展,每个核心工作流的工作量发生了变化。前4个技术阶段由主要里程碑所终止。

    alt

    统一过程的典型代表是RUP(Rational Unified Process)。RUP是UP的商业扩展,完全兼容UP,但比UP更完整、更详细。

    4.敏捷方法

    敏捷开发的总体目标是通过“尽可能早地、持续地对有价值的软件的交付”使客户满意。通过在软件开发过程中加入灵活性,敏捷方法可以使用户能够在开发周期的后期增加或改变需求。

    敏捷过程的典型方法有很多,每一种方法基于一套原则,这些原则实现了敏捷方法所宣称的理念(敏捷宣言)。这些方法如下。

    (1)极限编程(XP)。XP是一种轻量级(敏捷)、高效、低风险、柔性、可预测的、科学的软件开发方式。它由价值观、原则、实践和行为4个部分组成,彼此相互依赖、关联,并通过行为贯穿于整个生存周期。

    · 4大价值观:沟通、简单性、反馈和勇气。

    · 5个原则:快速反馈、简单性假设、逐步修改、提倡更改和优质工作。

    · 12个最佳实践:计划游戏(快速制定计划、随着细节的不断变化而完善)、小型发布(系统的设计要能够尽可能早地交付)、隐喻(找到合适的比喻传达信息)、简单设计(只处理当前的需求,使设计保持简单)、测试先行(先写测试代码,然后再编写程序)、重构(重新审视需求和设计,重新明确地描述它们以符合新的和现有的需求)、结队编程、集体代码所有制、持续集成(可以按日甚至按小时为客户提供可运行的版本)、每周工作40个小时、现场客户和编码标准。

    (2)水晶法(Crystal)。它认为每一个不同的项目都需要一套不同的策略、约定和方法论。

    (3)并列争求法(Scrum)。该方法使用迭代的方法,其中把每30天一次的迭代称为一个“冲刺”,并按需求的优先级别来实现产品。多个自组织和自治的小组并行地递增实现产品。协调是通过简短的日常情况会议来进行,就像橄榄球中的“并列争球”。

    (4)自适应软件开发(ASD)。它有6个基本的原则:有一个使命作为指导;特征被视为客户价值的关键点;过程中的等待是很重要的,因此“重做”与“做”同样关键;变化不被视为改正,而是被视为对软件开发实际情况的调整;确定的交付时间迫使开发人员认真考虑每一个生产的版本的关键需求;风险也包含其中。

    4.1.7 软件质量管理与质量保证

    软件质量是指反映软件系统或软件产品满足规定或隐含需求的能力的特征和特性全体。软件质量管理是指对软件开发过程进行独立的检查活动,由质量保证、质量规划和质量控制三个主要活动构成。软件质量保证是指为保证软件系统或软件产品充分满足用户要求的质量而进行的有计划、有组织的活动,其目的是生产高质量的软件。

    1.软件质量特性

    讨论软件质量首先要了解软件的质量特性。目前已经有多种软件质量模型来描述软件质量特性,如ISO/IEC 9126软件质量模型和Mc Call软件质量模型。

    1)ISO/IEC 9126软件质量模型

    ISO/IEC 9126软件质量模型由三个层次组成:第一层是质量特性,第二层是质量子特性,第三层是度量指标。该模型的质量特性和质量子特性如图4-4所示。

    其中各质量特性和质量子特性的含义如下。

    (1)功能性(functionality)。与一组功能及其指定的性质的存在有关的一组属性。功能是指满足规定或隐含需求的那些功能。

    · 适应性(suitability)。与对规定任务能否提供一组功能以及这组功能是否适合有关的软件属性。

    · 准确性(accurateness)。与能够得到正确或相符的结果或效果有关的软件属性。

    · 互用性(interoperability)。与同其他指定系统进行交互操作的能力相关的软件属性。

    · 依从性(compliance)。使软件服从有关的标准、约定、法规及类似规定的软件属性。

    · 安全性(security)。与避免对程序及数据的非授权故意或意外访问的能力有关的软件属性。

    alt

    图4-4 ISO/IEC软件质量模型

    (2)可靠性(reliability)。与在规定的一段时间内和规定的条件下,软件维持在其性能水平有关的能力。

    · 成熟性(maturity)。与由软件故障引起失效的频度有关的软件属性。

    · 容错性(fault tolerance)。与在软件错误或违反指定接口的情况下,维持指定的性能水平的能力有关的软件属性。

    · 易恢复性(recoverability)。与在故障发生后,重新建立其性能水平并恢复直接受影响数据的能力,以及为达到此目的所需的时间和努力有关的软件属性。

    (3)易使用性(usability)。与为使用所需的努力和由一组规定或隐含的用户对这样使用所作的个别评价有关的一组属性。

    · 易理解性(understandability)。与用户为理解逻辑概念及其应用所付出的劳动有关的软件属性。

    · 易学性(learnability)。与用户为学习其应用(例如操作控制、输入、输出)所付出的努力相关的软件属性。

    · 易操作性(operability)。与用户为进行操作和操作控制所付出的努力有关的软件属性。

    (4)效率(efficiency)。在规定条件下,软件的性能水平与所用资源量之间的关系有关的软件属性。

    · 时间特性(time behavior)。与响应和处理时间以及软件执行其功能时的吞吐量有关的软件属性。

    · 资源特性(resource behavior)。与软件执行其功能时,所使用的资源量以及使用资源的持续时间有关的软件属性。

    (5)可维护性(maintainability)。与进行规定的修改所需要的努力有关的一组属性。

    · 易分析性(analyzability)。与为诊断缺陷或失效原因,或为判定待修改的部分所需努力有关的软件属性。

    · 易改变性(changeability)。与进行修改、排错或适应环境变换所需努力有关的软件属性。

    · 稳定性(stability)。与修改造成未预料效果的风险有关的软件属性。

    · 易测试性(testability)。为确认经修改软件所需努力有关的软件属性。

    (6)可移植性(portability)。与软件可从某一环境转移到另一环境的能力有关的一组属性。

    · 适应性(adaptability)。与软件转移到不同环境时的处理或手段有关的软件属性。

    · 易安装性(installability)。与在指定环境下安装软件所需努力有关的软件属性。

    · 一致性(conformance)。使软件服从与可移植性有关的标准或约定的软件属性。

    · 易替换性(replaceability)。与一软件在该软件环境中用来替代指定的其他软件的可能和努力有关的软件属性。

    2)Mc Call软件质量模型

    Mc Call软件质量模型从软件产品的运行、修正和转移三个方面确定了11个质量特性(如图4-5所示)。Mc Call也给出了一个三层模型框架,第一层是质量特性,第二层是评价准则,第三层是度量指标。

    alt

    图4-5 Mc Call软件质量模型

    2.软件质量保证

    软件质量保证是指为保证软件系统或软件产品充分满足用户要求的质量而进行的有计划、有组织的活动,其目的是生产高质量的软件。在软件质量方面强调如下三个要点。

    (1)软件必须满足用户规定的需求,与用户需求不一致的软件就无质量可言。

    (2)软件应遵循规定标准所定义的一系列开发准则,不遵循这些准则的软件,其质量难以得到保证。

    (3)软件还应满足某些隐含的需求,例如希望有好的可理解性、可维护性等,而这些隐含的需求可能未被明确地写在用户规定的需求中,如果软件只满足它的显式需求而不满足其隐含需求,那么该软件的质量是令人置疑的。

    软件质量保证包括了与以下7个主要活动相关的各种任务。

    (1)应用技术方法。应该把软件质量设计到软件产品或软件系统中去,而不是在事后再施加质量保证。由于这个原因,软件质量保证首先从选择一组技术方法和工具开始,这些方法和工具帮助分析人员形成高质量的规格说明和高质量的设计。

    (2)进行正式的技术评审。一旦形成了规格说明和设计,就要对它们进行质量评估。完成质量评估的中心活动是正式的技术评审。正式的技术评审是一种由技术人员实施的程式化会议,其唯一的目的是揭露质量问题。在多数情况下,评审能像测试一样有效地揭露软件中的缺陷。

    (3)测试软件。软件测试组合了多种测试策略,这些测试策略带有一系列有助于有效地检测错误的测试用例设计方法。许多软件开发人员把软件测试用作质量保证的“安全网”,也就是说,开发人员以为通过测试能揭露最多的错误,借此减轻对其他软件质量保证活动的需要。遗憾的是,即使是完成得很好的测试也不会像我们所期望的那样揭露所有的错误种类。

    (4)标准的实施。对软件工程过程应用正式的开发标准和过程的程度在各公司中是不同的。多数情况,标准由客户或者某些章程确定。某些场合下标准是自己确定的。如果存在正式的标准,软件质量保证活动必须保证遵循这些标准。与标准是否一致的评估可以被软件开发者作为正式技术评审的一部分来进行。

    (5)控制变更。对软件质量的主要威胁来自“变更(change)”。对软件的每次变更都有可能引入错误或者引起传播错误的副作用。变更控制过程是通过对变更的正式申请、评价变更的特性和控制变更的影响等直接提高软件的质量。变更控制应用在软件开发期间和较后的软件维护阶段。

    (6)度量(metrics)。度量是任何工程科学必备的活动。软件质量保证的重要目标是跟踪软件质量和评价方法学及程序上的变更对软件质量的影响程度。要达到这个目标,应该收集软件度量。软件度量包括某些技术上的和面向管理的度量。

    (7)记录保存和报告。记录保存和报告为软件质量保证提供收集和传播软件质量保证信息的过程。评审、检查、变更控制、测试和其他软件质量保证活动的结果必须变成项目历史记录的一部分,并且应该把它传播给需要知道这些结果的开发人员。例如,记录过程设计的每次正式技术评审结果,并把记录放置在文件夹中,该文件夹包含了有关模块的所有技术信息和软件质量保证信息。

    3.软件复杂性

    软件度量的一个重要分支就是软件复杂性度量。对于软件复杂性度量的参数很多,主要有如下几个。

    · 规模。即总共的指令数,或源程序行数。

    · 难度。通常由程序中出现的操作数的数目所决定的量来表示。

    · 结构。通常用与程序结构有关的度量来表示。

    · 智能度。即算法的难易程度。

    软件复杂性主要表现在程序的复杂性。程序的复杂性主要指模块内程序的复杂性。程序复杂性主要有以下几种度量方法。

    (1)代码行度量法。度量程序的复杂性,最简单的方法就是统计程序的源代码行数。此方法的基本考虑是统计一个程序的源代码行数,并以源代码行数作为程序复杂性的度量。

    (2)McCabe度量法。McCabe度量法是由Thomas McCabe提出的一种基于程序控制流的复杂性度量方法。McCabe复杂性度量又称为环路度量,它认为程序的复杂性很大程度上取决于控制的复杂性。单一的顺序程序结构最为简单,循环和选择所构成的环路越多,程序就越复杂。这种方法以图论为工具,先画出程序图,然后用该图的环路数作为程序复杂性的度量值。程序图是退化的程序流程图,也就是说,把程序流程图中每个处理符号都退化成一个节点,原来连接不同处理符号的流线变成连接不同点的有向弧,这样得到的有向图就叫做程序图,如图4-6所示。程序图仅描述程序内部的控制流程,完全不表现对数据的具体操作以及分支和循环的具体条件。

    alt

    图4-6 程序图的复杂性

    根据图论,在一个强连通的有向图G中,环的个数V(G)由以下公式给出:

    alt

    其中,V(G)是有向图G中的环路数,m是图G中弧的个数,n是图G中的节点数,p是G中的强连通分量个数。在一个程序中,从程序图的入口点总能到达图中的任何一个节点,因此,程序总是连通的,但不是强连通的。为了使程序图成为强连通图,从图的入口点到出口点加一条用虚线表示的有向边,使图成为强连通图。这样就可以使用上式计算环路复杂性了。

    以图4-6为例,其中节点数n=6,弧数m=9,p=1,则有:

    alt

    即McCabe环路复杂的度量值为5。

    4.软件评审

    通常,把“质量”理解为“用户满意程度”。为了使得用户满意,有如下两个必要条件。

    (1)设计的规格说明书符合用户的要求,这称为设计质量。

    (2)程序按照设计规格说明所规定的情况正确执行,这称为程序质量。

    软件的规格说明分为外部规格说明和内部规格说明。外部规格说明是从用户角度来看的规格,包括硬件/软件系统设计、功能设计;而内部规格说明是为了实现外部规格的更详细的规格,即软件模块结构与模块处理过程的设计。因此,内部规格说明是从开发者角度来看的规格说明。设计质量是由外部规格说明决定的,程序是由内部规格说明决定的。

    1)设计质量的评审内容

    设计质量评审的对象是在需求分析阶段产生的软件需求规格说明、数据需求规格说明,在软件概要设计阶段产生的软件概要设计说明书等。通常从以下几个方面进行评审。

    (1)评价软件的规格说明是否合乎用户的要求,即总体设计思想和设计方针是否明确;需求规格说明是否得到了用户或单位上级机关的批准;需求规格说明与软件的概要设计规格说明是否一致等。

    (2)评审可靠性,即是否能避免输入异常(错误或超载等)、硬件失效及软件失效所产生的失效,一旦发生应能及时采取代替手段或恢复手段。

    (3)评审保密措施实现情况,即是否对系统使用资格进行检查;是否对特定数据、特定功能的使用资格进行检查;在检查出有违反使用资格的情况后,能否向系统管理人员报告有关信息;是否提供对系统内重要数据加密的功能等。

    (4)评审操作特性实施情况,即操作命令和操作信息的恰当性,输入数据与输入控制语句的恰当性;输出数据的恰当性;应答时间的恰当性等。

    (5)评审性能实现情况,即是否达到所规定性能的目标值。

    (6)评审软件是否具有可修改性、可扩充性、可互换性和可移植性。

    (7)评审软件是否具有可测试性。

    (8)评审软件是否具有复用性。

    2)程序质量的评审内容

    程序质量评审通常是从开发者的角度进行评审,与开发技术直接相关。它是着眼于软件本身的结构、与运行环境的接口以及变更带来的影响而进行的评审活动。

    软件的结构如下。

    (1)功能结构。在软件的各种结构中,功能结构是用户唯一能见到的结构。因此,功能结构是联系用户与开发者的规格说明,它在软件的设计中占有极其重要的地位。在评审软件的功能结构时,必须明确软件的数据结构。需要检查的项目如下。

    · 数据结构。包括数据名和定义;构成该数据的数据项;数据与数据间的关系。

    · 功能结构。包括功能名和定义;构成该功能的子功能;功能与子功能之间的关系。

    · 数据结构和功能结构之间的对应关系。包括数据元素与功能元素之间的对应关系;数据结构与功能结构的一致性。

    (2)功能的通用性。在软件的功能结构中,某些功能有时可以作为通用功能反复出现多次。从功能便于理解、增强软件的通用性及降低开发的工作量等观点出发,希望尽可能多地使功能通用化。需检查的项目包括抽象数据结构(抽象数据的名称和定义、抽象数据组成元素的定义);抽象功能结构。

    (3)模块的层次。模块的层次是指程序模块结构。由于模块是功能的具体体现,所以模块层次应当根据功能层次来设计。

    (4)模块结构。上述的模块层次结构是模块的静态结构。现在要检查模块的动态结构。模块分为处理模块和数据模块两类。模块间的动态结构也与这些模块分类有关。对这样的模块结构进行检查的项目如下。

    · 控制流结构。规定了处理模块与处理模块之间的流程关系。检查处理模块之间的控制转移关系与控制转移形式(调用方式)。

    · 数据流结构。规定了数据模块是如何被处理模块进行加工的流程关系。检查处理模块与数据模块之间的对应关系;处理模块与数据模块之间的存取关系。

    · 模块结构与功能结构之间的对应关系。包括功能结构与控制流结构的对应关系;功能结构与数据流结构之间的对应关系;每个模块的定义(功能、输入输出数据)。

    (5)处理过程的结构。处理过程是最基本的加工逻辑过程。对它的检查项目有模块的功能结构与实现这些功能的处理过程的结构应明确对应;控制流应是结构化的;数据的结构与控制流之间的对应关系应是明确的,并且可根据这种对应关系来明确数据流程的关系;用于描述的术语标准化。

    3)与运行环境的接口

    运行环境包括硬件、其他软件和用户。主要的检查项目如下。

    (1)与硬件的接口。包括与硬件的接口约定,即根据硬件的使用说明等所做出的规定;硬件故障时的处理和超载时的处理。

    (2)与用户的接口。包括与用户的接口约定,即输入数据的结构;输出数据的结构;异常输入时的处理,超载输入时的处理;用户存取资格的检查等。

    5.软件容错技术

    提高软件质量和可靠性的技术大致可分为两类,一类是避开错误,即在开发的过程中不让差错潜入软件的技术;另一类是容错技术,即对某些无法避开的差错,使其影响减至最小的技术。

    1)容错软件定义

    归纳容错软件的定义,有以下4种。

    (1)规定功能的软件,在一定程度上对自身错误的作用(软件错误)具有屏蔽能力,则称此软件为具有容错功能的软件,即容错软件。

    (2)规定功能的软件,在一定程度上能从错误状态自动恢复到正常状态,则称之为容错软件。

    (3)规定功能的软件,在因错误而发生错误时,仍然能在一定程度上完成预期的功能,则把该软件称为容错软件。

    (4)规定功能的软件,在一定程度上具有容错能力,则称之为容错软件。

    2)容错的一般方法

    实现容错的主要手段是冗余。冗余是指对于实现系统规定功能是多余的那部分资源,包括硬件、软件、信息和时间。由于加入了这些资源,有可能使系统的可靠性得到较大的提高。通常冗余技术分为4类。

    (1)结构冗余。结构冗余是通常采用的冗余技术。按其工作方法,可以分为静态、动态和混合冗余三种。

    ① 静态冗余。常用的有三模冗余(Triple Module Redundancy, TMR)和多模冗余。静态冗余通过表决和比较来屏蔽系统中出现的错误。如三模冗余,是对三个功能相同但由不同的人采用不同的方法开发出来的模块的运行结果通过表决,以多数结果作为系统的最终结果。即如果模块中有一个出错,这个错误能够被其他模块的正确结果“屏蔽”。由于无须对错误进行特别的测试,也不必进行模块的切换就能实现容错,故称为静态容错。

    ② 动态冗余。动态冗余的主要方式是多重模块待机储备。当系统测试到某工作模块出现错误时,就用一个备用模块来顶替它并重新运行。这里包括检测、切换和恢复过程,故称其为动态冗余。每当一个出错模块被其他备用模块顶替后,冗余系统相当于进行了一次重构。各备用模块在其待机时,可与主模块一同工作,也可不工作。前者叫做热备份系统,后者叫做冷备份系统。在热备份系统中,备用模块在待机过程中的失效率为0。

    ③ 混合冗余。它兼有静态冗余和动态冗余的长处。

    (2)信息冗余。为检测或纠正信息在运算或传输中的错误须外加一部分信息,这种现象称为信息冗余。在通信和计算机系统中,信息常以编码的形式出现。采用奇偶码、循环码等冗余码制式就可以发现甚至纠正这些错误。为了达到此目的,这些码(统称为误差校验码)的码长远远大于不考虑误差校正时的码长,增加了计算量和信道占用的时间。

    (3)时间冗余。时间冗余是指以重复执行指令或程序来消除瞬时错误带来的影响。多余重复执行不成功的情况,通常的处理办法是发出中断,转入错误处理程序,或对程序进行复算,或重新组合系统,或放弃程序处理。在程序复算中比较常用的方法是程序滚回(Program Rollback)技术。

    (4)冗余附加技术。冗余附加技术是指为实现上述冗余技术所需的资源和技术,包括程序、指令、数据、存放和调动它们的空间和通道等。

    在屏蔽硬件错误的容错技术中,冗余附加技术包括:

    ① 关键程序和数据的冗余存储及调用。

    ② 检测、表决、切换、重构、纠错和复算的实现。

    在屏蔽软件错误的容错系统中,冗余附加技术的构成包括:

    ① 冗余备份程序的存储及调用。

    ② 实现错误检测和错误恢复的程序。

    ③ 实现容错软件所需的固化程序。

    4.2 系统分析基础知识

    4.2.1 系统分析概述

    1.系统分析的目的和任务

    系统分析的主要任务是对现行系统进一步详细调查,将调查中所得到的文档资料集中,对组织内部整体管理状况和信息处理过程进行分析,为系统开发提供所需资料,并提交系统方案说明书。系统分析侧重于从业务全过程的角度进行分析,主要内容有业务和数据的流程是否通畅,是否合理;数据、业务过程和组织管理之间的关系;原系统管理模式改革和新系统管理方法的实现是否具有可行性等。

    确定的分析结果包括开发者对于现有组织管理状况的了解,用户对信息系统功能的需求,数据和业务流程,管理功能和管理数据指标体系以及新系统拟改动和新增的管理模型等。

    最后,提出信息系统的各种设想和方案,并对所有的设想和方案进行分析、研究、比较、判断和选择,获得一个最优的新系统的逻辑模型,并在用户理解计算机系统的工作流程和处理方式的情况下,将它明确地表达成书面资料——系统分析报告,即系统方案说明书。

    2.系统分析的主要步骤

    企业信息系统是一个具有业务复杂性和技术复杂性的大系统,为的是目标系统既能实现当前系统的基本职能,又能改进和提高。系统开发人员首先必须理解并描述出已经实际存在的当前系统,然后进行改进,从而创造出基于当前系统,又高于当前系统的目标系统,即新系统。

    系统分析过程一般按图4-7所示的逻辑进行。

    alt

    图4-7 系统分析过程图

    (1)认识、理解当前的现实环境,获得当前系统的“物理模型”。

    (2)从当前系统的“物理模型”抽象出当前系统的“逻辑模型”。

    (3)对当前系统的“逻辑模型”进行分析和优化,建立目标系统的“逻辑模型”。

    (4)对目标系统的逻辑模型具体化(物理化),建立目标系统的物理模型。

    系统开发的目的是把现有系统的物理模型转化为目标系统的物理模型,即图4-7中双虚线所描述的路径,而系统分析阶段的结果是得到目标系统的逻辑模型。逻辑模型反应了系统的功能和性质,而物理模型反映的是系统的某一种具体实现方案。

    按照图4-7所示,可将系统分析阶段的主要工作分为如下几步。

    (1)对当前系统进行详细调查,收集数据。

    (2)建立当前系统的逻辑模型。

    (3)对现状进行分析,提出改进意见和新系统应达到的目标。

    (4)建立新系统的逻辑模型。

    (5)编写系统方案说明书。

    4.2.2 结构化分析方法

    结构化分析(Structured Analysis, SA)方法是一种面向数据流的需求分析方法,适用于分析大型数据处理系统,是一种简单、实用的方法,现在已经得到广泛的使用。

    结构化分析方法的基本思想是自顶向下逐层分解。分解和抽象是人们控制问题复杂性的两种基本手段。对于一个复杂的问题,人们很难一下子考虑问题的所有方面和全部细节,通常可以把一个大问题分解成若干个小问题,每个小问题再分解成若干个更小的问题,经过多次逐层分解,每个最底层的问题都是足够简单,容易解决的,于是复杂的问题也就迎刃而解了。这个过程就是分解的过程。

    SA方法的分析结果由以下几部分组成:一套分层的数据流图、一本数据词典、一组小说明(也称加工逻辑说明)、补充材料。

    1.数据流图

    数据流图或称数据流程图(Data Flow Diagram, DFD),是一种便于用户理解、分析系统数据流程的图形工具。它摆脱了系统的物理内容,精确地在逻辑上描述系统的功能、输入、输出和数据存储等,是系统逻辑模型的重要组成部分。

    1)DFD的基本成份

    DFD的基本成份及其图形表示方法如图4-8所示。

    alt

    图4-8 DFD的基本成份

    · 数据流。数据流由一组固定成分的数据组成,表示数据的流向。值得注意的是,DFD中描述的是数据流,而不是控制流。除了流向数据存储或从数据存储流出的数据流不必命名外,每个数据流都必须有一个合适的名字,以反映该数据流的含义。

    · 加工。加工描述了输入数据流到输出数据流之间的变换,也就是输入数据流经过什么处理后变成了输出数据流。每个加工有一个名字和编号。编号能反映出该加工位于分层DFD中的哪个层次和哪张图中,也能够看出它是哪个加工分解出来的子加工。

    · 数据存储。数据存储用来表示存储的数据,每个数据存储都有一个名字。

    · 外部实体。外部实体是指存在于软件系统之外的人员或组织,它指出系统所需数据的发源地和系统所产生的数据的归宿地。

    2)分层数据流图的画法

    (1)画系统的输入和输出。把整个软件系统看作一个大的加工,然后根据系统从哪些外部实体接收数据流,以及系统发送数据流到哪些外部实体,就可以画出系统的输入和输出图,这张图称为顶层图。

    (2)画系统的内部。将顶层图的加工分解成若干个加工,并用数据流将这些加工连接起来,使得顶层图中的输入数据经过若干个加工处理后变换成顶层图的输出数据流。这张图称为0层图。从一个加工画出一张数据流图的过程实际上就是对这个加工的分解。

    可以用下述的方法来确定加工:在数据流的组成或值发生变化的地方应画一个加工,这个加工的功能就是实现这一变化;也可根据系统的功能确定加工。

    确定数据流的方法:当用户把若干个数据看作一个单位来处理(这些数据一起到达,一起加工)时,可把这些数据看成一个数据流。

    对于一些以后某个时间要使用的数据可以组织成一个数据存储来表示。

    (3)画加工的内部。把每个加工看作一个小系统,该加工的输入输出数据流看成小系统的输入输出数据流。于是可以用与画0层图同样的方法画出每个加工的DFD子图。

    (4)对第(3)步分解出来的DFD子图中的每个加工,重复第(3)步的分解,直至图中尚未分解的加工都足够简单(也就是说这种加工不必再分解)为止。至此,得到了一套分层数据流图。

    3)对图和加工进行编号

    对于一个软件系统,其数据流图可能有许多层,每一层又有许多张图。为了区分不同的加工和不同的DFD子图,应该对每张图和每个加工进行编号,以利于管理。

    (1)父图与子图。

    假设分层数据流图里的某张图(记为图A)中的某个加工可用另一张图(记为图B)来分解,称图A是图B的父图,图B是图A的子图。在一张图中,有些加工需要进一步分解,有些加工则不必分解。因此,如果父图中有n个加工,那么它可以有0~n张子图(这些子图位于同一层),但每张子图都只对应于一张父图。

    (2)编号。

    ① 顶层图只有一张,图中的加工也只有一个,所以不必编号。

    ② 0层图只有一张,图中的加工号可以分别是0.1,0.2,…或者是1,2,…。

    ③ 子图号就是父图中被分解的加工号。

    ④ 图的加工号由图号、圆点和序号组成。

    例如,某图中的某加工号为2.4,这个加工分解出来的子图号就是2.4,子图中的加工号分别为2.4.1,2.4.2,…。

    4)实例

    某考务处理系统有如下功能。

    (1)对考生送来的报名单进行检查。

    (2)对合格的报名单进行检查。

    (3)对阅卷站送来的成绩清单进行检查,并根据考试中心指定的合格标准审定合格者。

    (4)制作考生通知单(内含成绩合格/不合格标志)送给考生。

    (5)按地区、年龄、文化程度、职业和考试级别等进行成绩分类统计和试题难度分析,产生统计分析表。

    该考务处理系统的分层数据流图如图4-9所示。

    5)应注意的问题

    (1)适当地为数据流、加工、数据存储、外部实体命名,名字应反映该成分的实际含义,避免空洞的名字。

    (2)画数据流而不要画控制流。

    (3)每条数据流的输入或者输出是加工。

    (4)一个加工的输出数据流不应与输入数据流同名,即使它们的组成成分相同。

    (5)允许一个加工有多条数据流流向另一个加工,也允许一个加工有两个相同的输出数据流流向两个不同的加工。

    (6)保持父图与子图平衡。也就是说,父图中某加工的输入输出数据流必须与它的子图的输入输出数据流在数量和名字上相同。值得注意的是,如果父图的一个输入(或输出)数据流对应于子图中几个输入(或输出)数据流,而子图中组成这些数据流的数据项全体正好是父图中的这一个数据流,那么它们仍然算是平衡的。

    (7)在自顶向下的分解过程中,若一个数据存储首次出现时只与一个加工有关,那么这个数据存储应作为这个加工的内部文件而不必画出。

    (8)保持数据守恒。也就是说,一个加工所有输出数据流中的数据必须能从该加工的输入数据流中直接获得,或者是通过该加工能产生的数据。

    (9)每个加工必须既有输入数据流,又有输出数据流。

    (10)在整套数据流图中,每个数据存储必须既有读的数据流,又有写的数据流。但在某一张子图中可能只有读没有写,或者只有写没有读。

    alt

    图4-9 考务处理系统分层数据流图

    2.数据字典(DD)

    数据流图描述了系统的分解,但没有对图中各成分进行说明。数据字典就是为数据流图中的每个数据流、文件、加工,以及组成数据流或文件的数据项做出说明。其中对加工的描述称为“小说明”,也可以称为“加工逻辑说明”。

    1)数据字典的内容

    数据字典有以下4类条目:数据流、数据项、数据存储和基本加工。数据项是组成数据流和数据存储的最小元素。源点、终点不在系统之内,故一般不在字典中说明。

    (1)数据流条目。数据流条目给出了DFD中数据流的定义,通常列出该数据流的各组成数据项。在定义数据流或数据存储组成时,使用表4-1给出的符号。

    表4-1 在数据字典的定义式中出现的符号

    alt

    (2)数据存储条目。数据存储条目是对数据存储的定义。

    (3)数据项条目。数据项条目是不可再分解的数据单位。

    (4)加工条目。加工条目是用来说明DFD中基本加工的处理逻辑的,由于上层的加工是由下层的基本加工分解而来,只要有了基本加工的说明,就可理解其他加工。

    2)数据词典管理

    词典管理主要是把词典条目按照某种格式组织后存储在词典中,并提供排序、查找和统计等功能。如果数据流条目包含了来源和去向,文件条目包含了读文件和写文件,还可以检查数据词典与数据流图的一致性。

    3.加工逻辑的描述

    加工逻辑也称为“小说明”。常用的加工逻辑描述方法有结构化语言、判定表和判定树三种。

    1)结构化语言

    结构化语言(如结构化英语)是一种介于自然语言和形式化语言之间的半形式化语言,是自然语言的一个受限子集。

    结构化语言没有严格的语法,它的结构通常可分为内层和外层。外层有严格的语法,而内层的语法比较灵活,可以接近于自然语言的描述。

    (1)外层。用来描述控制结构,采用顺序、选择和重复三种基本结构。

    ① 顺序结构。一组祈使语句、选择语句、重复语句的顺序排列。祈使语句是指至少包含一个动词及一个名词,指出要执行的动作及接受动作的对象。

    ② 选择结构。一般用IF-THEN-ELSE-ENDIF、CASE-OF-ENDCASE等关键词。

    ③ 重复结构。一般用DO-WHILE-ENDDO、REPEAT-UNTIL等关键词。

    (2)内层。一般是采用祈使语句的自然语言短语,使用数据字典中的名词和有限的自定义词,其动词含义要具体,尽量不用形容词和副词来修饰。还可使用一些简单的算法运算和逻辑运算符号。

    2)判定表

    在有些情况下,数据流图中某个加工的一组动作依赖于多个逻辑条件的取值。这时,用自然语言或结构化语言都不易于清楚地描述出来,而用判定表就能够清楚地表示复杂的条件组合与应做的动作之间的对应关系。

    判定表由4部分组成,用双线分割成4个区域,如图4-10所示。

    alt

    图4-10 判定表结构

    3)判定树

    判定树是判定表的变形,一般情况下它比判定表更直观,且易于理解和使用。

    4.2.3 系统分析报告

    完成整个系统分析阶段的工作后,作为工作成果,应提交一份完整的系统分析报告。系统分析报告一经确认,就成为具有约束力的指导性文件,成为下一阶段系统设计工作的依据和今后验收目标系统的检验标准。系统分析报告形成后必须组织各方面的人员(包括组织的领导、管理人员、专业技术人员和系统分析人员等)一起对已经形成的方案进行论证,尽可能发现其中的问题和不足。对于有争论的问题要重新核实当初的原始调查资料或进一步地深入调查研究,对于重大的问题甚至可能需要调整或修改系统目标,重新进行系统分析。

    在系统分析报告中,数据流图、数据字典和加工说明这三部分是主体,是系统分析报告中必不可少的组成部分。而其他各部分的内容,则应根据所开发的目标系统的规模、性质等具体情况酌情选用,不必生搬硬套。总之,系统分析报告必须简明扼要、抓住本质,反映出目标系统的全貌和开发人员的设想。

    1.系统分析报告的主要作用

    系统分析报告主要有以下三个作用。

    (1)描述了目标系统的逻辑模型,作为开发人员进行系统设计和实施的基础。

    (2)作为用户和开发人员之间的协议或合同,为双方的交流和监督提供基础。

    (3)作为目标系统验收和评价的依据。

    因此,系统分析报告是系统开发过程中的一份重要文档,必须完整、一致、精确且简明易懂。

    2.系统分析报告的主要内容

    一份完整的系统分析报告应该包括下述内容。

    (1)组织情况概述。

    ① 对分析对象的基本情况作概括性的描述,包括组织的结构、组织的目标、组织的工作过程和性质、业务功能。

    ② 系统与外部实体(其他系统或机构)间有哪些物质以及信息的交换关系和联系。

    ③ 参考资料和专门术语说明。

    (2)现行系统概述。

    ① 现行系统现状调查说明。通过现行系统的组织结构图、数据流图和概况表等,说明现行系统的目标、规模、主要功能、组织机构、业务流程、数据存储和数据流,以及存在的薄弱环节。

    ② 系统需求说明。用户要求以及现行系统主要存在的问题等。

    (3)系统逻辑模型

    ① 新系统拟定的业务流程及业务处理方式。提出明确的功能目标、并与现行系统进行比较和分析,重点要突出计算机处理的优越性。

    ② 新系统拟定的数据指标体系和分析优化后的数据流程,各个层次的数据流图、数据字典和加工说明,以及计算机系统将完成的工作部分。

    ③ 出错处理要求。

    ④ 其他特性要求。例如系统的输入输出格式、启动和退出等。

    ⑤ 遗留问题。根据目前条件,暂时不能满足的一些用户要求或设想,并提出今后解决的措施和途径。

    (4)新系统在各个业务处理环节拟采用的管理方法、算法或模型。

    (5)与新系统相配套的管理制度和运行体制的建立。

    (6)系统设计与实施的初步计划。

    ① 工作任务的分解。根据资源及其他条件确定各子系统开发的先后次序,在此基础上分解工作任务,落实到具体组织和个人。

    ② 根据系统开发资源与时间进度估计,指定进度安排计划。

    ③ 预算。对开发费用的进一步估计。

    (7)用户领导审批意见。

    4.3 系统设计知识

    4.3.1 系统设计的内容和步骤

    在系统分析阶段,已经搞清楚了软件“做什么”的问题,并把这些需求通过规格说明书描述了出来,这也是目标系统的逻辑模型。进入设计阶段,要把软件“做什么”的逻辑模型转换成“怎么做”的物理模型,即着手实现软件系统的需求。

    系统设计的主要目的就是为系统制定蓝图,在各种技术和实施方法中权衡利弊,精心设计,合理使用各种资源,最终勾画出新系统的详细设计方案。

    系统设计的主要内容包括新系统总体结构设计、代码设计、输出设计、输入设计、处理过程设计、数据存储设计、用户界面设计和安全控制设计等。

    系统设计的基本任务大体上可以分为概要设计和详细设计两个步骤。

    1.概要设计的基本任务

    1)设计软件系统总体结构

    其基本任务是采用某种设计方法,将一个复杂的系统按功能划分成模块;确定每个模块的功能;确定模块之间的调用关系;确定模块之间的接口,即模块之间传递的信息;评价模块结构的质量。

    软件系统总体结构的设计是概要设计关键的一步,直接影响到下一个阶段详细设计与编码的工作。软件系统的质量及一些整体特性都在软件系统总体结构的设计中决定。

    2)数据结构及数据库设计

    (1)数据结构的设计。逐步细化的方法也适用于数据结构的设计。在需求分析阶段,已经通过数据字典对数据的组成、操作约束和数据之间的关系等方面进行了描述,确定了数据的结构特性,在概要设计阶段要加以细化,详细设计阶段则规定具体的实现细节。在概要设计阶段,宜使用抽象的数据类型。

    (2)数据库的设计。数据库的设计是指数据存储文件的设计,主要进行以下几方面设计。

    ① 概念设计。在数据分析的基础上,采用自底向上的方法从用户角度进行视图设计,一般用ER模型来表述数据模型。ER模型既是设计数据库的基础,也是设计数据结构的基础。

    ② 逻辑设计。ER模型是独立于数据库管理系统(DBMS)的,要结合具体的DBMS特征来建立数据库的逻辑结构。

    ③ 物理设计。对于不同的DBMS,物理环境不同,提供的存储结构与存取方法各不相同。物理设计就是设计数据模式的一些物理细节,如数据项存储要求、存取方法和索引的建立等。

    本节对数据库技术不做详细讨论,详细内容参见本书第7章。

    3)编写概要设计文档

    文档主要有概要设计说明书、数据库设计说明书、用户手册以及修订测试计划。

    4)评审

    对设计部分是否完整地实现了需求中规定的功能、性能等要求,设计方法的可行性,关键的处理及内外部接口定义的正确性、有效性、各部分之间的一致性等都一一进行评审。

    2.详细设计的基本任务

    (1)对每个模块进行详细的算法设计。用某种图形、表格和语言等工具将每个模块处理过程的详细算法描述出来。

    (2)对模块内的数据结构进行设计。

    (3)对数据库进行物理设计,即确定数据库的物理结构。

    (4)其他设计。根据软件系统的类型,还可能要进行以下设计。

    ① 代码设计。为了提高数据的输入、分类、存储和检索等操作,节约内存空间,对数据库中某些数据项的值要进行代码设计。

    ② 输入输出格式设计。

    ③ 用户界面设计。

    (5)编写详细设计说明书。

    (6)评审。对处理过程的算法和数据库的物理结构都要评审。

    系统设计的结果是一系列的系统设计文件,这些文件是物理实现一个信息系统(包括硬件设备和编制软件程序)的重要基础。

    4.3.2 系统设计的基本原理

    1.抽象

    抽象是一种设计技术,重点说明一个实体的本质方面,而忽略或者掩盖不很重要或非本质的方面。抽象是一种重要的工具,用来将复杂的现象简化到可以分析、实验或者可以理解的程度。软件工程中从软件定义到软件开发要经历多个阶段,在这个过程中每前进一步都可看作是对软件解法的抽象层次的一次细化。抽象的最低层就是实现该软件的源程序代码。在进行模块化设计时也可以有多个抽象层次,最高抽象层次的模块用概括的方式叙述问题的解法,较低抽象层次的模块是对较高抽象层次模块对问题解法描述的细化。

    2.模块化

    模块在程序中是数据说明、可执行语句等程序对象的集合,或者是单独命名和编址的元素,如高级语言中的过程、函数和子程序等。在软件的体系结构中,模块是可组合、分解和更换的单元。

    模块化是指将一个待开发的软件分解成若干个小的简单部分——模块,每个模块可独立地开发、测试,最后组装成完整的程序。这是一种复杂问题“分而治之”的原则。模块化的目的是使程序的结构清晰,容易阅读、理解、测试和修改。

    3.信息隐蔽

    信息隐蔽是开发整体程序结构时使用的法则,即将每个程序的成分隐蔽或封装在一个单一的设计模块中,定义每一个模块时尽可能少地显露其内部的处理。在设计时首先列出一些可能发生变化的因素,在划分模块时将一个可能发生变化的因素隐蔽在某个模块的内部,使其他模块与这个因素无关。在这个因素发生变化时,只需修改含有这个因素的模块,而与其他模块无关。

    信息隐蔽原则对提高软件的可修改性、可测试性和可移植性都有重要的作用。

    4.模块独立

    模块独立是指每个模块完成一个相对独立的特定子功能,并且与其他模块之间的联系简单。衡量模块独立程度的标准有两个:耦合性和内聚性。

    1)耦合

    耦合性是指模块之间联系的紧密程度。耦合性越高,则模块的独立性越差。模块间耦合的高低取决于模块间接口的复杂性、调用的方式及传递的信息。模块的耦合有以下几种类型。

    · 无直接耦合。指两个模块间没有直接的关系,它们分别从属于不同模块的控制与调用,它们之间不传递任何信息。因此,模块间耦合性最弱,模块独立性最高。

    · 数据耦合。指两个模块之间有调用关系,传递的是简单的数据值,相当于高级语言中的值传递。这种耦合程度较低,模块的独立性较高。

    · 标记耦合。指两个模块之间传递的数据结构,如高级语言中的数据组名、记录名、文件名等这些名字即为标记,其实传递的是这个数据结构的地址。

    · 控制耦合。指一个模块调用另一个模块时,传递的是控制变量,被调模块通过该控制变量的值有选择地执行块内的某一功能。

    · 公共耦合。指通过一个公共数据环境相互作用的那些模块之间的耦合。

    · 内容耦合。这是程度最高的耦合。当一个模块直接使用另一个模块的内部数据,或通过非正常入口而转入另一个模块内部,这种模块之间的耦合为内容耦合,这种情况往往出现在汇编程序设计中。

    2)内聚

    内聚是指模块内部各元素之间联系的紧密程度,例如一个完成多个功能的模块的内聚度就比完成单一功能的模块的内聚度低。内聚度越低,模块的独立性越差。内聚性有以下几种类型。

    · 偶然内聚。指一个模块内的各个处理元素之间没有任何联系。

    · 逻辑内聚。指模块内执行几个逻辑上相似的功能,通过参数确定该模块完成哪一个功能。

    · 时间内聚。把需要同时执行的动作组合在一起形成的模块为时间内聚模块。

    · 通信内聚。指模块内所有处理元素都在同一个数据结构上操作,或者指各处理使用相同的输入数据或者产生相同的输出数据。

    · 顺序内聚。指一个模块中各个处理元素都密切相关于同一功能且必须顺序执行,前一功能元素的输出就是下一功能元素的输入。

    · 功能内聚。这是最强的内聚。指模块内所有元素共同完成一个功能,缺一不可。耦合性和内聚性是模块独立性的两个定性标准,将软件系统划分模块时,尽量做到高内聚、低耦合,提高模块的独立性。

    4.3.3 系统总体结构设计

    系统总体结构设计是要根据系统分析的要求和组织的实际情况来对新系统的总体结构形式和可利用的资源进行大致设计,这是一种宏观、总体上的设计和规划。下面介绍系统总体设计的主要内容。

    1.系统结构设计原则

    为保证总体结构设计的顺利完成,主要应遵循以下几条原则。

    (1)分解—协调原则。整个系统是一个整体,具有整体目的和功能。但这些目的和功能的实现又是由相互联系的各个组成部分共同工作的结果。解决复杂问题的一个很重要的原则就是把它分解成多个小问题分别处理,在处理过程中根据系统总体要求协调各部门的关系。

    (2)自顶向下的原则。首先抓住系统总的功能目的,然后逐层分解,即先确定上层模块的功能,再确定下层模块的功能。

    (3)信息隐蔽、抽象的原则。上层模块只规定下层模块做什么和所属模块间的协调关系,但不规定怎么做,以保证各模块的相对独立性和内部结构的合理性,使得模块与模块之间层次分明,易于理解、实施和维护。

    (4)一致性原则。要保证整个软件设计过程中具有统一的规范、统一的标准和统一的文件模式等。

    (5)明确性原则。每个模块必须功能明确、接口明确,消除多重功能和无用接口。

    (6)模块之间的耦合尽可能小,模块的内聚度尽可能高。

    (7)模块的扇入系数和扇出系数要合理。一个模块直接调用其他模块的个数称为模块的扇出系数;反之,一个模块被其他模块调用时,直接调用它的模块个数称为模块的扇入系数。模块的扇入、扇出系数必须适当。经验表明,一个设计得好的系统的平均扇入、扇出系数通常是3或4,一般不应超过7,否则会引起出错概率的增大。但菜单调用型模块扇入与扇出系数可以大一些,公用模块扇入系数可以大一些。

    (8)模块的规模适当。过大的模块常常使系统分解得不充分,其内部可能包含了若干部分的功能,因此有必要进一步把原有的模块分解成若干功能尽可能单一的模块。但分解也必须适度,因为过小的模块有可能降低模块的独立性,造成系统接口的复杂性。

    2.子系统划分

    1)子系统划分的原则

    为了便于今后系统开发和系统运行,子系统的划分应遵循如下几点原则。

    (1)子系统要具有相对独立性。子系统的划分,必须使得子系统的内部功能、信息等各方面的凝聚性较好。子系统独立可以减少子系统间的相互影响,有利于多人分工开发不同的模块,从而提高软件产品的生产率,保证软件产品的质量,同时也增强了系统的可维护性和适应性。

    (2)子系统之间数据的依赖性尽量小。子系统之间的联系要尽量减少,接口要简单明确。一个内部联系强的子系统对外部的联系必然很少,所以划分的时候,应将联系较多者列入子系统内部,剩余的一些分散、跨度比较大的联系,就成为这些子系统间的联系和接口。这样划分的子系统,将来调试、维护和运行都是非常方便的。

    (3)子系统划分的结果应使数据冗余较小。如果把相关的功能数据分布到各个不同的子系统中,则会有大量的原始数据需要调用,大量的中间结果需要保存和传递,大量计算工作将要重复进行。从而使得程序结构紊乱,数据冗余,不但给软件编制工作带来很大的困难,而且系统的工作效率也大大降低。

    (4)子系统的设置应考虑今后管理发展的需要。子系统的设置仅依靠上述系统分析的结构是不够的,因为现存的系统由于各种原因,很可能没有考虑到一些高层次管理决策的要求。

    (5)子系统的划分应便于系统分阶段实现。信息系统的开发是一项较大的工程,它的实现一般都要分批进行,所以子系统的划分应能适应这种分期分批的实施。另外,子系统的划分还必须兼顾组织结构的要求。

    (6)子系统的划分应考虑到各类资源的充分利用。一个适当的子系统划分应该既考虑有利于各种设备资源在开发过程中的搭配使用,又考虑到各类信息资源的合理分布和充分使用,以减少系统对网络资源的过分依赖,减少输入、输出和通信等设备压力。

    2)子系统结构设计

    子系统结构设计的任务是确定划分后的子系统模块结构,并画出模块结构图。这个过程中必须考虑以下几个问题。

    (1)每个子系统如何划分成多个模块。

    (2)如何确定子系统之间、模块之间传送的数据及其调用关系。

    (3)如何评价并改进模块结构的质量。

    (4)如何从数据流图导出模块结构图。

    3.系统模块结构设计

    1)模块的概念

    模块是组成系统的基本单位,它的特点是可以组合、分解和更换。系统中任何一个处理功能都可以看成是一个模块。根据模块功能具体化程度的不同,可以分为逻辑模块和物理模块。在系统逻辑模型中定义的处理功能可视为逻辑模块。物理模块是逻辑模块的具体化,可以是一个计算机程序、子程序或若干条程序语句,也可以是人工过程的某项具体工作。

    一个模块应具备以下4个要素。

    (1)输入和输出。模块的输入来源和输出去向都是同一个调用者,即一个模块从调用者那里取得输入,进行加工后再把输出返回给调用者。

    (2)处理功能。指模块把输入转换成输出所作的工作。

    (3)内部数据。指仅供该模块本身引用的数据。

    (4)程序代码。指用来实现模块功能的程序。

    前两个要素是模块外部特性,即反映了模块的外貌。后两个要素是模块的内部特性。在结构化设计中,主要考虑的是模块的外部特性,其内部特性只做必要了解,具体的实现将在系统实施阶段完成。

    2)模块结构图

    为了保证系统设计工作的顺利进行,结构设计应遵循如下原则。

    (1)所划分的模块其内部的凝聚性要强,模块之间的联系要少,即模块具有较强的独立性。

    (2)模块之间的连接只能存在上下级之间的调用关系,不能有同级之间的横向联系。

    (3)整个系统呈树状结构,不允许网状结构或交叉调用关系出现。

    (4)所有模块(包括后继IPO图)都必须严格地分类编码并建立归档文件。

    模块结构图主要关心的是模块的外部属性,即上下级模块、同级模块之间的数据传递和调用关系,并不关心模块的内部。

    模块结构图是结构化设计中描述系统结构的图形工具。作为一种文档,它必须严格地定义模块的名字、功能和接口,同时还应当在模块结构图上反映出结构化设计的思想。模块结构图由模块、调用、数据、控制和转接5种基本符号组成,如图4-11所示,现说明如下。

    alt

    图4-11 模块结构图的基本符号

    · 模块。这里所说的模块通常是指用一个名字就可以调用的一段程序语句。长方形中间标上能反映模块处理功能的模块名字。

    · 调用。箭头总是由调用模块指向被调用模块,但是应该理解被调用模块执行后又返回到调用模块。

    如果一个模块是否调用一个从属模块,决定于调用模块内部的判断条件,则该调用模块间的判断调用采用菱形符号表示。如果一个模块通过其内部的循环功能来循环调用一个或多个从属模块,则该调用称为循环调用,用弧形箭头表示。判断调用和循环调用的表示方法如图4-12所示。

    alt

    图4-12 模块调用示例

    · 数据。当一个模块调用另一个模块时,调用模块可以把数据传送到被调用模块供处理,而被调用模块又可以将处理的结构送回到被调用模块。在模块之间传送的数据,使用与调用箭头平行的带空心圆的箭头表示,并在旁边标上数据名。图4-13(a)表示模块A调用模块B时,A将数据x、y传送给B,B将处理结果数据z返回给A。

    · 控制信息。模块间有时还必须传送某些控制信息。例如,数据输入完成后给出的结束标志,文件读到末尾时所产生的文件结束标志等。控制信息与数据的主要区别是前者只反映数据的某种状态,不必进行处理。图4-13(b)中“无此职工”就是用来表示送来的职工号有误的控制信息。

    · 转接符号。当模块结构图在一张纸上画不下,需要转接到另一张纸上,或者为了避免图上线条交叉时,都可以使用转接符号,圆圈内加上标号,如图4-14所示。

    alt

    图4-13 模块间的数据传递

    alt

    图4-14 转接符号的使用

    4.数据存储设计

    信息系统的主要任务是通过大量的数据获得管理所需要的信息,这就必须存储和管理大量的数据。因此,建立一个良好的数据组织结构和数据库,使整个系统都可以迅速、方便、准确地调用和管理所需的数据,是衡量信息系统开发工作好坏的主要指标之一。

    数据结构组织和数据库或文件设计,就是要根据数据的不同用途、使用要求、统计渠道和安全保密性等,来决定数据的整体组织形式、表或文件的形式,以及决定数据的结构、类别、载体、组织方式、保密级别等一系列的问题。

    一个好的数据结构和数据库应该充分反映物流发展变化的状况,充分满足组织的各级管理要求。同时还应该使得后继系统开发工作方便、快捷、系统开销(如占用空间、网络传输频度、磁盘或光盘读写次数等)小、易于管理和维护。有关数据库及数据库设计的相关内容可参见本书第7章。

    在建立了数据的整体关系结构之后,剩下的就是要确定数据资源分布和安全保密属性了。其中数据资源的分布是针对分布数据库系统而言的,而安全保密属性的定义则是针对某些特殊信息,如财务数据等而言的。

    (1)数据资源分布。如果所规划和设计的系统是在网络环境之下,那么数据库设计必须考虑整个数据资源在网络各节点(包括网络服务器)上的分配问题。

    (2)数据的安全保密。一般数据库软件都提供定义数据安全保密性的基本功能。系统所提供的安全保密功能一般有8个等级(0~7级),4种不同方式(只读、只写、删除、修改),而且允许用户利用这8个等级的4种方式对每一个表自由地进行定义。

    4.3.4 结构化设计方法

    结构化设计(structured design, SD)方法是一种面向数据流的设计方法,它可以与SA方法衔接。结构化设计方法的基本思想是将系统设计成由相对独立、功能单一的模块组成的结构。

    1.信息流的类型

    在需求分析阶段,用SA方法产生了数据流图。面向数据流的设计能方便地将DFD转换成程序结构图。DFD中从系统的输入数据流到系统的输出数据流的一连串连续变换形成了一条信息流。DFD的信息流大体上可以分为两种类型:变换流和事务流。

    (1)变换流。信息沿着输入通路进入系统,同时将信息的外部形式转换成内部表示,然后通过变换中心(也称主加工)处理,再沿着输出通路转换成外部形式离开系统。具有这种特性的信息流称为变换流。变换流型的DFD可以明显地分成输入、变换(主加工)和输出三大部分。

    (2)事务流。信息沿着输入通路到达一个事务中心,事务中心根据输入信息(即事务)的类型在若干个动作序列(称为活动流)中选择一个来执行,这种信息流称为事务流。事务流有明显的事务中心,各活动流以事务中心为起点呈辐射状流出。

    2.变换分析

    变换分析是从变换流型的DFD导出程序结构图。

    1)确定输入流和输出流,分离出变换中心

    把DFD中系统输入端的数据流称为物理输入,系统输出端的数据流称为物理输出。物理输入通常要经过编辑、格式转换、合法性检查、预处理等辅助性的加工才能为主加工的真正输入(称为逻辑输入)。从物理输入端开始,一步步向系统的中间移动,可找到离物理输入端最远,但仍可被看作系统输入的那个数据流,这个数据流就是逻辑输入。同样,由主加工产生的输出(称为逻辑输出)通常也要经过编辑、格式转换、组成物理块、缓冲处理等辅助加工才能变成物理输出。从物理输出端开始,一步步向系统的中间移动,可找到离物理输出端最远,但仍可被看作系统输出的那个数据流,这个数据流就是逻辑输出。

    DFD中从物理输入到逻辑输入的部分构成系统的输入流,从逻辑输出到物理输出的部分构成系统的输出流,位于输入流和输出流之间的部分就是变换中心。

    2)第一级分解

    第一级分解主要是设计模块结构的顶层和第一层。一个变换流型的DFD可映射成图4-15所示的程序结构图。图中顶层模块的功能就是整个系统的功能。输入控制模块用来接收所有的输入数据,变换控制模块用来实现输入到输出的变换,输出控制模块用来产生所有的输出数据。

    alt

    图4-15 变换分析的第一级分解

    3)第二级分解

    第二级分解主要是设计中、下层模块。

    (1)输入控制模块的分解。从变换中心的边界开始,沿着每条输入通路,把输入通路上的每个加工映射成输入控制模块的一个低层模块。

    (2)输出控制模块的分解。从变换中心的边界开始,沿着每条输出通路,把输出通路上的每个加工映射成输出控制模块的一个低层模块。

    (3)变换控制模块的分解。变换控制模块通常没有通用的分解方法,应根据DFD中变换部分的实际情况进行设计。

    4)事务分析

    事务分析是从事务流型DFD导出程序结构图。

    (1)确定事务中心和每条活动流的流特性。图4-16给出了事务流型DFD的一般形式。其中事务中心(图中的T)位于数条活动流的起点,这些活动流从该点呈辐射状地流出。每条活动流也是一条信息流,它可以是变换流,也可以是另一条事务流。一个事务流型的DFD由输入流、事务中心和若干条活动流组成。

    (2)将事务流型DFD映射成高层的程序结构。事务流型DFD的高层结构如图4-17所示。顶层模块的功能就是整个系统的功能。接收模块用来接收输入数据,它对应于输入流。发送模块是一个调度模块,控制下层的所有活动模块。每个活动流模块对应于一条活动流,它也是该活动流映射成的程序结构图中的顶层模块。

    alt

    图4-16 事务流

    alt

    图4-17 事务流型DFD的高层程序结构

    (3)进一步分解。接收模块的分解类同于变换分析中输入控制模块的分解。每个活动流模块根据其流特性(变换流或事务流)进一步采用变换分析或事务分析进行分解。

    5)SD方法的设计步骤

    (1)复查并精化数据流图。

    (2)确定DFD的信息流类型(变换流或事务流)。

    (3)根据流类型分别实施变换分析或事务分析。

    (4)根据系统设计的原则(参见4.3.3节)对程序结构图进行优化。

    4.3.5 面向数据结构的设计方法

    面向数据结构的设计方法以数据结构作为设计的基础,它根据输入输出数据结构导出程序的结构,适用于规模不大的数据处理系统。Jackson方法是一种典型的面向数据结构的设计方法。

    1.Jackson图

    尽管程序中实际使用的数据结构有许多种,但这些数据结构中数据元素间的逻辑关系只有顺序、选择和重复三类。表示数据元素间逻辑关系的Jackson图如图4-18所示。

    alt

    图4-18 Jackson图的基本符号

    图4-18(a)表示数据结构A由B、C、D三个成分顺序组成,其次序是从左到右;图4-18(b)表示数据结构A是B或C或D中的一个;图4-18(c)表示数据结构A由B重复出现多次(可以是0次)组成。

    Jackson图同样也可用来表示程序结构,此时图中的方框表示模块。图4-18(a)表示程序的顺序结构,图4-18(b)表示程序的分支结构,图4-18(c)表示程序的重复结构。

    2.Jackson方法的设计步骤

    (1)分析并确定输入和输出数据的逻辑结构,并用Jackson图表示。

    (2)找出输入数据结构与输出数据结构间有对应关系的数据单元。所谓有对应关系的数据单元,是指有直接因果关系,在程序中可以同时处理的数据单元。对于重复结构的数据单元,必须在重复次数和次序都相同时才有对应关系。

    (3)用下述的三条规则从描述数据结构的Jackson图导出描述程序结构的Jackson图。

    ① 为每对有对应关系的数据单元,按照它们在数据结构图中的层次在程序结构图的相应层次画一个处理框。如果这对有对应关系的数据单元在输入数据结构图中所处的层次与输出数据结构图中所处的层次不同,则取它们中较低的层次作为处理框在程序结构图中的层次。

    ② 为输入数据结构图中剩余的每个数据单元,在程序结构图的相应层次上画一对应的处理框。

    ③ 为输出数据结构图中剩余的每个数据单元,在程序结构图的相应层次上画一处理框。

    (4)列出所有的操作,并把它们分配到程序结构图的适当位置上。

    (5)用伪码表示程序。与描述程序结构的Jackson图对应的伪码如图4-19所示。

    alt

    图4-19 Jackson图对应的伪码

    4.3.6 系统详细设计

    1.代码设计

    代码是用来表征客观事物的一组有序的符号,以便于计算机和人工识别与处理。代码的类指代码符号的表示形式,一般有数字型、字母型和数字字母混合型。三种类型的代码各有所长,应根据使用者的要求、信息量的多少、信息交换的频度和使用者的习惯等方面综合考虑。

    代码设计应该遵循以下基本原则。

    (1)唯一性。一个对象可能有多个名称,也可按不同的方式对它进行描述。但在一个编码体系中,一个对象只能赋予它唯一的代码。最简单的就是职工编号、学生的学号等。

    (2)合理性。代码结构与相应的分类体系相对应。

    (3)可扩充性。应留有充分的余地,以备将来不断扩充的需要。

    (4)简单性。结构尽可能简单,以减少各种差错。

    (5)适用性。代码尽可能反映对象的特点,以助记忆,便于填写。

    (6)规范性。国家有关编码标准是代码设计的重要依据,已有标准的必须遵循。在一个代码体系中,代码结构、类型和编写格式必须统一。

    (7)系统性。有一定的分组规则,从而在整个系统中具有通用性。例如,在会计领域中,一级会计科目由国家财政部进行标准分类,二级会计科目由各部委或行业协会统一进行标准分类,并且这个分类还必须参照一二级科目的规律进行。

    代码设计可以按照以下步骤来进行。

    (1)确定代码对象。

    (2)考察是否已有标准代码。如果国家或者某个部门对某些事物已经规定了标准代码,那么应遵循这些标准代码。

    (3)根据代码的使用范围、使用时间和实际情况选择代码的种类与类型。

    (4)考虑检错功能。

    (5)编写代码表。代码编好后,要编制代码表,做详细说明,通知有关部门组织学习,以便正确使用。

    目前常用的编码有顺序码、数字码、字符码和混合码,限于篇幅,这里不做详细论述。

    2.输出设计

    从系统开发的角度看,输出决定输入,即输入信息只有根据输出要求才能确定。输出设计包括以下几方面的内容。

    (1)确定输出内容。输出内容的设计首先要确定用户在使用信息方面的要求。根据用户要求,设计输出信息的内容,包括信息形式(表格、图形、文字)、输出项目及数据结构、数据类型、位数及取值范围、数据的生成途径、完整性及一致性的考虑等。

    (2)选择输出设备与介质。常用的输出设备有显示终端、打印机、磁带机、绘图仪、缩微胶卷输出器和多媒体设备。输出介质有纸张、磁带、磁盘、缩微胶卷、光盘和多媒体介质等。这些设备和介质各有特点,应根据用户对输出信息的要求,结合现有设备和资金条件选择。

    (3)确定输出格式。输出格式要满足使用者的要求和习惯,做到格式清晰、美观、易于阅读和理解。

    最终输出方式常用的只有两种:报表输出和图形输出。采用哪种输出形式为宜,应根据系统分析和管理业务的要求而定。一般来说,对于基层和具体事务的管理者,应用报表方式给出详细的记录数据为宜;而对于高层领导或宏观、综合管理部门,则应该使用图形方式用以显示综合数据或发展趋势等信息。

    3.输入设计

    输入设计的目的是保证向系统输入正确的数据。在此前提下,做到输入方法简单、迅速、经济、方便。为此,输入设计应遵循以下原则。

    (1)最小量原则。这就是保证满足处理要求的前提下使输入量最小。输入量越少,出错机会越小,花费时间越少,数据一致性越好。

    (2)简单性原则。输入的准备、输入过程应尽量容易,以减少错误的发生。

    (3)早检验原则。对输入数据的检验尽量接近源数据发生点,使错误能及时得到改正。

    (4)少转换原则。输入数据尽量使用其处理所需的形式记录,以免数据转换介质时发生错误。

    输入设计的内容如下。

    (1)确定输入数据内容。包括确定输入数据项名称、数据内容、精度和数值范围。

    (2)输入方式设计。主要是根据总体设计和数据库设计的要求来确定数据输入的具体形式。常用的输入方式有键盘输入,模/数、数/模输入,网络数据传送,磁/光盘读入等。通常在设计新系统的输入方式时,应尽量利用已有的设备和资源,避免大批量的数据通过键盘输入。

    (3)输入格式设计。实际设计数据输入(特别是大批量的数据统计报表输入)时,常常遇到统计报表(文件)结构与数据库文件结构不完全一致的情况,如有可能,应尽量改变统计报表或数据库关系表二者之一的结构,使其一致,以减少输入格式设计的难度。现在还可采用智能输入方式,由计算机自动将输入送至不同表格。

    (4)校对方式设计。特别是针对数字、金额数等字段,没有适当的校对措施作保证是很危险的。所以对一些重要的报表,输入设计一定要考虑适当的校对措施,以减少出错的可能性。但应指出的是,绝对保证不出错的校对方式是没有的。

    常用的校对方式有人工校对、二次输入校对(同一批数据两次输入)和数据平衡校对。

    4.处理过程设计

    总体结构设计将系统分解成许多模块,并决定了每个模块的外部特征:功能和界面。计算机处理过程的设计则要确定每个模块的内部特征,即内部的执行过程,包括局部的数据组织、控制流、每一步的具体加工要求及种种实施细节。通过这样的设计,为编写程序制定一个周密的计划。

    处理过程设计的关键是用一种合适的表达方法来描述每个模块的执行过程。这种表示方法应该简明、精确,并由此能直接导出用编程语言表示的程序。常用的描述方式有图形、语言和表格三类,如传统的框图、各种程序语言和判定表等。

    1)程序流程图

    流程图(flow chart)即程序框图,是历史最久、流行最广的一种图形表示方法。程序流程图包括三种基本成分:加工步骤,用方框表示;逻辑条件,用菱形表示;控制流,用箭头表示。

    图形表示的优点是直观、形象、容易理解。但从结构化程序设计的角度看,流程图不是理想的表达工具。缺点之一是表示控制的箭头过于灵活。使用得当,流程图简单易懂;使用不当,流程图可能非常难懂,而且无法维护。流程图的另一个缺点是只描述执行过程而不能描述有关数据。

    2)盒图(NS图)

    盒图是结构化程序设计出现之后,为支持这种设计方法而产生的一种描述工具。在NS图中,每个处理步骤用一个盒子表示,盒子可以嵌套。盒子只能从上头进入,从下头走出,除此之外别无其他出入口,所以盒图限制了随意的控制转移,保证了程序的良好结构。

    3)形式语言

    形式语言是用来描述模块具体算法的、非正式的、比较灵活的语言。其外层语法是确定的,而内层语法不确定。外层语法描述控制结构时使用类似于一般编程语言的保留字,所以是确定的。内层语法故意不确定,可以按系统的具体情况和不同层次灵活选用,实际上可用自然语言来描述具体操作。

    可以看出,形式语言同结构性语言的想法是一致的。形式语言的优点是接近自然语言(英语),所以易于理解。另外,它可以作为注释嵌套在程序中成为内部文档,提高程序的自我描述性。同时,由于是语言形式,易于被计算机处理,所以可用行编辑程序或字处理系统对形式语言进行编辑修改。

    4)决策树

    如果一个加工决策或判断的步骤较多,则使用形式语言时,语句的嵌套层次太多,不便于基本加工的逻辑功能的清晰描述。决策树是一种图形工具,适合于描述加工中具有多个策略且每个策略和若干条件有关的逻辑功能。

    5)决策表

    在基本加工中,如果判断的条件较多,各条件又相互组合且相应的决策方案较多的情形下用决策树来描述,树的结构比较复杂,图中各项注释比较繁琐。决策表也是一种图形工具,呈表形。决策表将比较复杂的决策问题简洁、明确、一目了然地描述出来。

    5.用户界面设计

    用户界面是系统与用户之间的接口,也是控制和选择信息输入输出的主要途径。用户界面设计应坚持友好、简便、实用、易于操作的原则。例如,在设计菜单时应尽量避免菜单嵌套层次过多和每选择一次还需再确认一次的设计方式。在设计大批数据输入屏幕界面时,应避免颜色过于鲜艳和多变。

    界面设计包括菜单方式、会话方式、操作提示方式以及操作权限管理方式等。

    1)菜单方式

    菜单是信息系统功能选择操作的最常用方式。按目前软件所提出的菜单设计工具,菜单的形式可以是下拉式、弹出式的,也可以是按钮选择方式的。

    2)会话管理方式

    在所有的用户界面中,几乎毫无例外地会遇到人机会话问题。最为常见的有当用户操作错误时,系统向用户发出提示和警告性信息;当系统执行用户操作命令遇到多种可能时,系统会要求用户进一步说明;系统定量分析的结果通过屏幕向用户发出控制性的信息等。这类会话的处理方式是让系统开发人员根据实际系统操作过程将会话语句写在程序中。

    一般会话系统是面向企业领导的,会话系统设计必须满足会话的基本要求,如画面清晰、直观形象,明了简洁,具有容错和纠错能力,提供信息汉字化、图形化和表格化等。

    因此,会话设计重点解决会话方式、容错能力和系统的模块结构。

    在语音会话方式还没有广泛使用的今天,会话的基本工具是键盘、屏幕和打印机,常用的方式是回答式、菜单式、表格式和图形式。

    纠错、容错的目的是保证会话的正确性,提高会话的效率,在系统中可采用如下方法。

    · 提示法:分简单提示和重复提示法。

    · 确认回答法:为用户误操作提供改错机会。

    · 无效处理法:系统拒绝接收错误操作。

    · 返回处理法:拒绝不熟悉系统的用户使用操作。

    · 延时处理法:让用户有足够的时间理解系统的提问内容,防止错误回答。

    · 帮助处理法:给用户提供帮助信息,并给予重新操作的机会。

    3)提示方式与权限管理

    为了操作使用方便,在设计系统时,常常把操作提示和要点同时显示在屏幕的旁边,以使用户操作方便,这是当前比较流行的用户界面设计方式。另一种操作提示设计方式则是将整个系统操作说明书全送入到系统文件中,并设置系统运行状态指针。当系统运行操作时,指针随着系统运行状态来改变,当用户按“求助”键时,系统则立刻根据当前指针调出相应的操作说明。

    与操作方式有关的另一个内容就是对数据操作权限的管理。权限管理一般都是通过入网口令和建网时定义该节点级别相结合来实现的。

    6.安全控制设计

    从数据环境和数据处理两方面看,影响系统安全的因素有如下几个。

    · 环境性因素。是指管理机构的组织、硬件和系统软件、系统开发、自然环境等方面的因素。例如,组织方面职责不分,没有监督机构等;硬件软件方面,硬件失灵,系统软件失灵,逻辑线路错误等;系统开发方面,没有按科学的方法开发系统和设计程序、系统未经测试和调试等;自然环境方面,火灾、水灾、风灾和地震等;安全管理方面,数据处理资源的接触是随意的、无必要的限制等。

    · 数据处理因素。是指数据处理行为引起的各种情况。例如,输入环节录入错误信息,使用无效代码,按错功能键,丢失数据,重复输入,没有将数据存盘等;处理环节使用了错误的程序、错误的数据文件,处理不及时,丢失数据文件和程序等;输出环节错误地发送报表或不及时发送,报告中的错误未加更正等。

    要进行系统的安全控制,应针对影响系统安全的两方面因素入手,有的放矢,相应地进行环境和数据处理两方面的有效控制,以保证系统安全有效地运行。

    4.4 系统实施知识

    4.4.1 系统实施概述

    1.系统实施的目的和任务

    系统实施是新系统开发工作的最后一个阶段。所谓实施,指的是将系统设计阶段的结果在计算机上实现,将原来纸面上的、类似于设计图式的新系统方案转换成可执行的应用软件系统。系统实施阶段的主要任务如下。

    (1)按总体设计方案购置和安装计算机网络系统。硬件准备包括计算机主机、输入输出设备、存储设备、辅助设备(稳压电源、空调设备等)和通信设备等。购置、安装和调试这些设备要花费大量的人力、物力,并且持续相当长的时间。

    (2)软件准备。软件准备包括系统软件、数据库管理系统以及一些应用程序。这些软件有些需要购买,有些需要组织人力编写。编写程序是系统实施阶段的重要任务之一。

    (3)培训。主要指用户的培训,包括主管人员和业务人员。这些人多数来自现行系统,精通业务,但往往缺乏计算机知识。为了保证系统调试和运行顺利进行,应根据他们的基础提前进行培训,使他们适应、逐步熟悉新的操作方法。

    (4)数据准备。数据的收集、整理、录入是一项既繁重、劳动量又大的工作。而没有一定基础数据的准备,系统调试就不可能很好地进行。一般来说,确定数据库模型之后,就应进行数据的整理、录入。这样既分散了工作量,又可以为系统调试提供真实的数据。

    (5)投入转换和试运行。

    在系统实施过程中,还有若干非技术因素的影响。信息系统的最终受益人是企业的最高领导层,信息系统建设涉及到企业机构、权限的重组,只有具备进行变革权利的人才能真正地推进企业信息化。

    企业在推行管理信息化时,总经理首先要了解企业一些公众的心理,如企业的各级员工的习惯心理,对信息系统使用持不信任态度的怀疑性排斥心理。此外,信息系统的使用将传统的金字塔管理变为扁平管理,使以前无法暴露的灰色行为被一览无遗;素质较低或年龄较大的员工对操作计算机系统具有畏惧心理。如果没有妥善的培训或疏导,这些都将成为系统应用的极大障碍。

    2.系统实施的步骤

    系统开发工作沿着信息系统的生命周期逐渐推进,经过详细设计阶段后,便进入系统实施阶段。

    (1)按总体设计方案购置和安装计算机网络系统。购置和安装硬件是比较简单的事情,只需要按总体设计的要求和可行性报告中财力资源的分析,选择好价格性能比高的设备,通知供货厂家按要求供货并安装即可。

    (2)建立数据库系统。如果前面数据与数据流程分析以及数据库设计工作进行得比较规范,而且开发者又对数据库技术比较熟悉的话,按照数据库设计的要求只需1~2个人一天即可建立起一个大型数据库结构。

    (3)程序设计。

    (4)收集有关数据并进行录入工作,然后进行系统测试。

    (5)人员培训、系统转换和试运行。

    4.4.2 程序设计

    程序设计的主要依据是系统设计阶段的HIPO图(Hierarchy Plus Input-Process-output,层次式输入—处理—输出)及数据库结构和编码设计。

    1.程序设计方法

    目前程序设计的方法大多按照结构化方法、原型方法、面向对象的方法进行。

    程序设计的目的是为了实现开发者在系统分析和系统设计中提出管理方法和处理构想。所以在程序设计和实现中,应尽量借用已有的程序和各种开发工具,尽快尽好地实现系统,而不要在具体的程序设计和调试工作中花费过多的精力和时间。

    1)结构化程序设计方法

    若遇到某些开发过程不规范,模块划分不细,或者是因特殊业务处理的需要模块程序量较大时,结构化程序设计方法是一种非常有效的方法。结构化的程序设计方法主要强调三点。

    (1)模块内部程序各部分要自顶向下地结构化划分。

    (2)各程序部分应按功能组合。

    (3)各程序部分的联系尽量使用调用子程序(CALL-RETURN)方式,不用或少用GOTO方式。

    2)快速原型式的程序开发方法

    具体实施方法是首先将HIPO图中类似带有普遍性的功能模块集中,如菜单模块、报表模块、查询模块、统计分析和图像模块等,这些模块几乎是每个子系统必不可少的;然后再去寻找有无相应、可用的软件工具,如果没有则可以考虑开发一个能够适合各子系统情况的通用模块;最后用这些工具生成这些程序模块原型。如果HIPO图中有一些特定的处理功能和模块,而这些功能和模块又是现有工具不可能生成出来的,则再考虑编制一段程序加进去,利用现有的工具和原型方法可以很快地开发出所要的程序。

    3)面向对象程序设计方法

    面向对象程序设计方法一般应与OOD所设计的内容相对应。它是一个简单直接的映射过程,即将OOD中所定义的范式直接用面向对象程序如C++、Smalltalk和Java等来取代即可。

    2.程序设计基本模块

    一个信息系统的应用软件由很多程序模块组成,这些程序模块可以归纳成为几种基本类型,其结构如图4-20所示。

    alt

    图4-20 基本程序模块图

    1)控制模块

    控制模块包括主控制模块和各级控制模块。控制模块的主要功能是根据用户要求信息,由用户确定处理顺序,然后控制转向各处理模块的入口。

    2)输入模块

    主要用来输入数据,输入方式有键盘输入和软盘输入两种。

    3)输入数据校验模块

    该模块对已经输入计算机中的数据进行校验,以保证原始数据的正确性。校验的方法通常有重复输入校验和程序校验两种。

    4)输出模块

    输出模块用来将计算机的运行结果通过屏幕、打印机或磁盘、磁带等设备输出给用户。在信息系统中,一般都有大量的表格、图表需要输出,因此输出模块的质量直接关系到整个系统的性能。

    5)处理模块

    根据信息系统的不同应用要求,有不同的处理功能,通常有以下几种类型。

    (1)文件更新模块。当系统应用的数据发生变化时,需要修改数据文件。例如,增加新的记录、修改数据项或记录、删除某些不需要的记录等。一般来说,文件更新模块应该具有下述功能。

    ① 对记录中关键字的控制功能,通过关键字查找相应记录。

    ② 控制总记录数的功能,以便控制追加、插入记录的位置。

    ③ 具有按地址或字节访问的控制功能,以便确定修改数据的位置,控制插入或者追加的数据位置。

    (2)分类合并模块。分类合并模块的主要功能是对已经建立的文件,按某关键字进行分类合并。例如,在材料核算系统中耗用材料要按照材料类型合并处理。分类合并程序应该具有下述功能。

    ① 控制记录总数的功能。

    ② 字符串比较的功能。

    ③ 排序、统计和计数功能。

    (3)计算模块。该模块的主要功能是进行计算处理,包括同类记录中各数据项的运算。

    (4)数据检索模块。该模块的主要功能是为用户提供查询的有关信息,它包括输入查询要求和输出特定的查询结果。它是管理信息系统的人机接口,对于人机交互的友好程序以及查询响应时间等均有较高要求。

    (5)预测或优化模块。该模块的主要功能是使用预测或优化的数学模型,利用信息系统所提供的有关数据进行计算和分析并输出结果,用来辅助企业或部门的管理人员进行决策。例如,库存管理中的ABC分类、最佳订货量计算和财务管理中的资金分析等。

    3.程序设计语言的选择

    每种程序设计语言都有自己的特点,为一个特定的开发项目选择编程语言时通常可以考虑下列一些因素:应用领域、算法和计算的复杂性、软件运行的环境(包括可使用的编译程序)、用户需求(特别是性能需求)、数据结构的复杂性、开发人员的水平等。

    从应用领域来看,COBOL语言适用于商业领域的应用,FORTRAN语言适合于科学和工程计算的应用,PROLOG和LISP适合于人工智能的应用,对于一些采用面向对象方法的应用系统通常可选用C++或Java。有些程序设计语言可应用于多种应用领域。例如C语言,它原先是为辅助开发UNIX操作系统而设计的,主要用于开发系统软件,现在已经广泛应用于其他领域。

    开发和维护高级语言程序要比开发和维护低级语言程序容易得多,但是高级语言程序经过编译后所产生的目标程序要比完成相同功能的低级语言程序长得多。也就是说,前者的功效要比后者的功效低。因此,某些对运行时间或存储空间有过高要求的项目,或者在不能提供高级语言编译程序的计算机上开发程序,往往要使用低级语言。在某些大型系统中,为了提高系统的运行效率,有时也对系统中在执行时间上起关键作用的模块局部使用低级语言。

    当然,所选择的语言必须有可使用的编译程序。如果有多种语言都适合于某项目的开发时,也可以考虑选择开发人员比较熟悉的一种。

    4.4.3 系统测试与调试

    1.系统测试的意义、目的及原则

    系统测试是为了发现错误而执行程序的过程,成功的测试是发现了至今尚未发现的错误的测试。

    测试的目的就是希望能以最少的人力和时间发现潜在的各种错误和缺陷。应根据开发各阶段的需求、设计等文档或程序的内部结构精心设计测试实例,并利用这些实例来运行程序,以便发现错误的过程。信息系统测试应包括软件测试、硬件测试和网络测试。硬件测试、网络测试可以根据具体的性能指标来进行,此处所说的测试更多是指软件测试。

    系统测试是保证系统质量和可靠性的关键步骤,是对系统开发过程中的系统分析、系统设计和实施的最后复查。根据测试的概念和目的,在进行信息系统测试时应遵循以下基本原则。

    (1)应尽早并不断地进行测试。测试不是在应用系统开发完之后才进行的。由于原始问题的复杂性、开发各阶段的多样性以及参加人员之间的协调等因素,使得在开发各个阶段都有可能出现错误。因此,测试应贯穿在开发的各个阶段,尽早纠正错误,消除隐患。

    (2)测试工作应该避免由原开发软件的人或小组承担,一方面,开发人员往往不愿否认自己的工作,总认为自己开发的软件没有错误;另一方面,开发人员的错误很难由本人测试出来,很容易根据自己编程的思路来制定测试思路,具有局限性。测试工作应由专门人员来进行,会更客观,更有效。

    (3)设计测试方案时,不仅要确定输入数据,而且要根据系统功能确定预期输出结果。将实际输出结果与预期结果相比较就能发现测试对象是否正确。

    (4)在设计测试用例时,不仅要设计有效合理的输入条件,也要包含不合理、失效的输入条件。测试的时候,人们往往习惯按照合理的、正常的情况进行测试,而忽略了对异常、不合理、意想不到的情况进行测试,而这些可能就是隐患。

    (5)在测试程序时,不仅要检验程序是否做了该做的事,还要检验程序是否做了不该做的事。多余的工作会带来副作用,影响程序的效率,有时会带来潜在的危害或错误。

    (6)严格按照测试计划来进行,避免测试的随意性。测试计划应包括测试内容、进度安排、人员安排、测试环境、测试工具和测试资料等。严格地按照测试计划可以保证进度,使各方面都得以协调进行。

    (7)妥善保存测试计划、测试用例,作为软件文档的组成部分,为维护提供方便。

    (8)测试例子都是精心设计出来的,可以为重新测试或追加测试提供方便。当纠正错误、系统功能扩充后,都需要重新开始测试,而这些工作重复性很高,可以利用以前的测试用例,或在其基础上修改,然后进行测试。

    2.测试过程

    测试是开发过程中一个独立且非常重要的阶段。测试过程基本上与开发过程平行进行。

    一个规范化的测试过程通常包括以下基本的测试活动。

    (1)制定测试计划。在制定测试计划时,要充分考虑整个项目的开发时间和开发进度以及一些人为因素和客观条件等,使得测试计划是可行的。测试计划的内容主要有测试的内容、进度安排、测试所需的环境和条件、测试培训安排等。

    (2)编制测试大纲。测试大纲是测试的依据,它明确详尽地规定了在测试中针对系统的每一项功能或特性所必须完成的基本测试项目和测试完成的标准。

    (3)根据测试大纲设计和生成测试用例,产生测试设计说明文档,其内容主要有被测项目、输入数据、测试过程和预期输出结果等。

    (4)实施测试。测试的实施阶段是由一系列的测试周期组成的。在每个测试周期中,测试人员和开发人员将依据预先编制好的测试大纲和准备好的测试用例,对被测软件或设备进行完整的测试。

    (5)生成测试报告。测试完成后,要形成相应的测试报告,主要对测试进行概要说明,列出测试的结论,指出缺陷和错误。另外,给出一些建议,如可采用的修改方法,各项修改预计的工作量及修改的负责人员。

    4.4.4 测试策略和测试方法

    1.软件测试策略

    软件测试策略将软件测试用例的设计方法集成到一系列经过周密计划的步骤中去,从而使软件构造成功地完成。测试策略提供以下方面的路径图:描述将要进行的测试步骤,这些步骤计划和执行的时机,需要多少工作量、时间和资源。因此,任何测试策略都必须包含测试计划、测试用例设计、测试执行以及结果数据的收集和评估。

    软件测试策略应该具有足够的灵活性,以便促进测试方法的定制。同时,它必须足够严格,以便在项目进行过程中对项目进行合理地策划和追踪管理。

    有效的软件测试实际上分成4步进行。

    1)单元测试

    单元测试也称为模块测试,在模块编写完成且无编译错误后就可以进行。单元测试侧重于模块中的内部处理逻辑和数据结构。如果选用机器测试,一般用白盒测试法。这类测试可以对多个模块同时进行。

    单元测试主要检查模块的以下5个特征。

    (1)模块接口。模块的接口保证了测试模块的数据流可以正确地流入、流出。在测试中应检查以下要点。

    ① 测试模块的输入参数和形式参数在个数、属性、单位上是否一致。

    ② 调用其他模块时,所给出的实际参数和被调用模块的形式参数在个数、属性、单位上是否一致。

    ③ 调用标准函数时,所用的参数在属性、数目和顺序上是否正确。

    ④ 全局变量在各模块中的定义和用法是否一致。

    ⑤ 输入是否仅改变了形式参数。

    ⑥ 开/关的语句是否正确。

    ⑦ 规定的I/O格式是否与输入输出语句一致。

    ⑧ 在使用文件之前是否已经打开文件或使用文件之后是否已经关闭文件。

    (2)局部数据结构。在单元测试中,局部数据结构出错是比较常见的错误,在测试时应重点考虑以下因素。

    ① 变量的说明是否合适。

    ② 是否使用了尚未赋值或尚未初始化的变量。

    ③ 变量的初始值或默认值是否正确。

    ④ 变量名是否有错(例如拼写错)。

    (3)重要的执行路径。在单元测试中,对路径的测试是最基本的任务。由于不能进行穷举测试,需要精心设计测试例子来发现是否有计算、比较或控制流等方面的错误。

    ① 计算方面的错误。算术运算的优先次序不正确或理解错误;精度不够;运算对象的类型彼此不相容;算法错;表达式的符号表示不正确等。

    ② 比较和控制流的错误。本应相等的量由于精度造成不相等;不同类型进行比较;逻辑运算符不正确或优先次序错误;循环终止不正确(如多循环一次或少循环一次)、死循环;不恰当地修改循环变量;当遇到分支循环时,出口错误等。

    (4)出错处理。好的设计应该能预测到出错的条件并且有对出错处理的路径。虽然计算机可以显示出错信息的内容,但仍需要程序员对出错进行处理,保证其逻辑的正确性,以便于用户维护。

    (5)边界条件。边界条件的测试是单元测试的最后工作,也是非常重要的工作。软件容易在边界出现错误。

    由于模块不是独立运行的程序,各模块之间存在调用与被调用的关系。在对每个模块进行测试时,需要开发两种模块。

    · 驱动模块。相当于一个主程序,接收测试例子的数据,将这些数据送到测试模块,输出测试结果。

    · 桩模块,也称为存根模块。桩模块用来代替测试模块中所调用的子模块,其内部可进行少量的数据处理,目的是为了检验入口,输出调用和返回的信息。

    提高模块的内聚度可以简化单元测试。如果每个模块只完成一种功能,对于具体模块来讲,所需的测试方案数据就会显著减少,而且更容易发现和预测模块中的错误。

    对于面向对象软件,单元的概念发生了变化。封装导出了类的定义。每个类和类的实例(对象)包装有属性(数据)和处理这些数据的操作(函数或方法)。封装的类常是单元测试的重点,然而,类中包含的操作是最小的可测试单元。由于类中可以包含一些不同的操作,且特殊的操作可以作为不同的类的一部分存在,因此,面向对象软件的类测试是由封装在该类中的操作和类的状态行为驱动的。

    2)集成测试

    集成测试就是把模块按系统设计说明书的要求组合起来进行测试。即使所有模块都通过了测试,但在集成之后,仍可能会出现问题:穿过模块的数据丢失;一个模块的功能对其他模块造成有害的影响;各个模块集成起来没有达到预期的功能;全局数据结构出现问题。另外,单个模块的误差可以接受,但模块组合后,可能会出现误差累积,最后到不能接受的程度,所以需要集成测试。

    通常集成测试有两种方法:一种是分别测试各个模块,再把这些模块组合起来进行整体测试,即非增量式集成;另一种是把下一个要测试的模块组合到已测试好的模块中,测试完后再将下一个需要测试的模块组合起来进行测试,逐步把所有模块组合在一起,并完成测试,如自顶向下集成、自底向上集成,即增量式集成。非增量式集成可以对模块进行并行测试,能充分利用人力,并加快工程进度。但这种方法容易混乱,出现错误不容易查找和定位。增量式测试的范围一步步扩大,错误容易定位,而且已测试的模块可在新的条件下再测试,测试更彻底。

    面向对象软件没有明显的层次控制结构,类的成分间的直接或间接相互作用,使得每次将一个操作集成到类中往往不可能。因此,面向对象系统的集成有两种不同的策略:一是基于线程的测试,集成响应系统的一个输入或事件所需的一组类,每个线程单独地集成和测试;另一种方法是基于使用的测试,通过测试很少使用服务类的那些类(称为独立类)开始构建系统,独立类测试完后,利用独立类测试下一层的类(称为依赖类)。继续依赖类的测试直到完成整个系统。

    簇测试时面向对象软件集成测试中的一步。这里,利用试图发现协作中的错误的测试用例来测试协作的类簇。

    3)确认测试

    经过集成测试之后,软件就被集成起来,接口方面的问题已经解决,将进入软件测试的最后一个环节,即确认测试。确认测试的任务就是进一步检查软件的功能和性能是否与用户要求的一样。系统方案说明书描述了用户对软件的要求,所以是软件有效性验证的标准,也是确认测试的基础。

    确认测试,首先要进行有效性测试以及软件配置审查,然后进行验收测试和安装测试,经过管理部门的认可和专家的鉴定后,软件即可以交给用户使用。

    (1)有效性测试。就是在模拟环境下,通过黑盒测试检验所开发的软件是否与需求规格说明书一致。在设计测试例子时,除了检测软件的功能和性能之外,还需要对软件的容错性、维护性等其他方面进行检测。测试人员可由开发商的内部人员组成,但最好是没有参加该项目的有经验的软件设计人员。在所有测试例子完成之后,若发现测试结果与预期的不符,这时要列出缺陷清单。在这个阶段才发现的严重错误,一般很难在预定的时间内纠正,需要与用户协商,寻找妥善解决问题的办法。

    (2)软件配置审查。主要是检查软件(源程序、目标程序)和文档(包括面向开发和用户的文档)以及数据(程序内部的数据或程序外部的数据)是否齐全,分类是否有序。确保文档、资料的正确和完善,以便维护阶段使用。

    (3)验收测试。是以用户为主的测试。软件开发人员和质量保证人员也应该参加。在验收测试之前,需要对用户进行培训,以便熟悉该系统。验收测试的测试例子由用户参与设计,主要验证软件的功能、性能、可移植性、兼容性和容错性等,测试时一般采用实际数据。多数软件开发者使用α测试与β测试的过程,其中α测试是最终用户在开发者的场所进行,而β测试是在最终用户场所执行。

    4)系统测试

    系统测试是将已经确认的软件、计算机硬件、外设和网络等其他因素结合在一起,进行信息系统的各种集成测试和确认测试,其目的是通过与系统的需求相比较,发现所开发的系统与用户需求不符或矛盾的地方。系统测试是根据系统方案说明书来设计测试用例的,常见的系统测试主要有以下内容。

    (1)恢复测试。监测系统的容错能力。检测方法是采用各种方法让系统出现故障,检验系统是否按照要求能从故障中恢复过来,并在约定的时间内开始事务处理,而且不对系统造成任何伤害。如果系统的恢复是自动的(由系统自动完成),需要验证重新初始化、检查点和数据恢复等是否正确。如果恢复需要人工干预,就要对恢复的平均时间进行评估并判断它是否在允许的范围内。

    (2)安全性测试。检测系统的安全机制、保密措施是否完善,主要是为了检验系统的防范能力。测试的方法是测试人员模拟非法入侵者,采用各种方法冲破防线。系统安全性设计准则是使非法入侵者所花费的代价比进入系统后所得到的好处要大,此时非法入侵已无利可图。

    (3)压力测试。也称为强度测试,是对系统在异常情况下的承受能力的测试,是检查系统在极限状态下运行时,性能下降的幅度是否在允许的范围内。因此,压力测试要求系统在非正常数量、频率或容量的情况下运行。压力测试主要是为了发现在有效的输入数据中可能引起不稳定或不正确的数据组合。例如,运行使系统处理超过设计能力的最大允许值的测试例子;使系统传输超过设计最大能力的数据,包括内存的写入和读出等。

    (4)性能测试。检查系统是否满足系统设计方案说明书对性能的要求。性能测试覆盖了软件测试的各阶段,而不是等到系统的各部分都集成之后,才确定系统的真正性能。通常与强度测试结合起来进行,并同时对软件、硬件进行测试。软件方面主要从响应时间、处理速度、吞吐量和处理精度等方面来检测。

    (5)可靠性、可用性和可维护性测试。通常使用以下两个指标来进行衡量:平均失效间隔时间(Mean Time Between Failures, MTBF)是否超过了规定的时限,因故障而停机时间(Mean Time To Repairs, MTTR)在一年中不应超过多少时间。

    (6)安装测试。在安装软件系统时,会有多种选择。安装测试就是为了检测在安装过程中是否有误、是否容易操作等。主要监测系统的每一个部分是否齐全,硬件的配置是否合理,安装中需要产生的文件和数据库是否已产生,其内容是否正确等。

    2.测试方法

    测试是可以事先计划并可以系统地进行的一系列活动。因此,应该为软件过程定义软件测试模板,即将特定的测试方法和测试用例设计放在一系列的测试步骤中去。

    软件测试方法分为静态测试和动态测试。

    (1)静态测试。静态测试是指被测试程序不在机器上运行,而是采用人工检测和计算机辅助静态分析的手段对程序进行检测。

    ① 人工检测。人工检测是不依靠计算机而是靠人工审查程序或评审软件,包括代码检查、静态结构分析和代码质量度量等。

    ② 计算机辅助静态分析。利用静态分析工具对被测试程序进行特性分析,从程序中提取一些信息,以便检查程序逻辑的各种缺陷和可疑的程序构造。

    (2)动态测试。动态测试是指通过运行程序发现错误。对软件产品进行动态测试时可以采用黑盒测试法和白盒测试法。

    测试用例的设计如下。

    测试用例由测试输入数据和与之对应的预期输出结构组成。在设计测试用例时,应当包括合理的输入条件和不合理的输入条件。

    1)用黑盒法设计测试用例

    黑盒测试也称为功能测试,在完全不考虑软件的内部结构和特性的情况下,测试软件的外部特性。进行黑盒测试主要是为了发现以下几类错误。

    (1)是否有错误的功能或遗漏的功能?

    (2)界面是否有误?输入是否正确接收?输出是否正确?

    (3)是否有数据结构或外部数据库访问错误?

    (4)性能是否能够接受?

    (5)是否有初始化或终止性错误?

    常用的黑盒测试技术有等价类划分、边值分析、错误猜测和因果图等。

    (1)等价类划分。等价类划分法将程序的输入域划分为若干等价类,然后从每个等价类中选取一个代表性数据作为测试用例。每一类的代表性数据在测试中的作用等价于这一类中的其他值。这样就可以用少量代表性的测试用例取得较好的测试效果。等价类划分有两种不同的情况:有效等价类和无效等价类。在设计测试用例时,要同时考虑这两种等价类。

    定义等价类的原则如下。

    ① 在输入条件规定了取值范围或值的个数的情况下,可以定义一个有效等价类和两个无效等价类。

    ② 在输入条件规定了输入值的集合或规定了“必须如何”的条件的情况下,可以定义一个有效等价类和一个无效等价类。

    ③ 在输入条件是一个布尔量的情况下,可以定义一个有效等价类和一个无效等价类。

    ④ 在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可以定义n个有效等价类和一个无效等价类。

    ⑤ 在规定了输入数据必须遵守的规则的情况下,可定义一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。

    ⑥ 在确知已划分的等价类中,各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步地划分为更小的等价类。

    定义好等价类之后,建立等价类表,并为每个等价类编号。在设计一个新的测试用例时,使其尽可能多地覆盖尚未覆盖的有效等价类,不断重复,最后使得所有有效等价类均被测试用例所覆盖。然后设计一个新的测试用例,使其只覆盖一个无效等价类。

    (2)边界值划分。输入的边界比中间更加容易发生错误,因此用边界值分析来补充等价类划分的测试用例设计技术。边界值划分选择等价类边界的测试用例,既注重于输入条件边界,又适用于输出域测试用例。

    对边界值设计测试用例应遵循的原则如下。

    ① 如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值,以及刚刚超越这个范围边界的值作为测试输入数据。

    ② 如果输入条件规定了值的个数,则用最大个数、最小个数、比最小个数少1、比最大个数多1的数据作为测试数据。

    ③ 根据规格说明的每个输出条件,使用上述两条原则。

    ④ 如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例。

    ⑤ 如果程序中使用了一个内部数据结构,则应当选择这个内部数据结构边界上的值作为测试用例。

    ⑥ 分析规格说明,找出其他可能的边界条件。

    (3)错误推测。错误推测是基于经验和直觉推测程序中所有可能存在的各种错误,从而有针对性地设计测试用例的方法。其基本思想是列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据它们选择测试用例。

    (4)因果图。因果图法是从自然语言描述的程序规格说明中找出因(输入条件)和果(输出或程序状态的改变),通过因果图转换为判定表。

    利用因果图导出测试用例需要经过以下几个步骤。

    ① 分析程序规格说明的描述中,哪些是原因,哪些是结果。原因常常是输入条件或是输入条件的等价类,而结果是输出条件。

    ② 分析程序规格说明的描述中语义的内容,并将其表示成连接各个原因与各个结果的“因果图”。

    ③ 标明约束条件。由于语法或环境的限制,有些原因和结果的组合情况是不可能出现的。为表明这些特定的情况,在因果图上使用若干个标准的符号标明约束条件。

    ④ 把因果图转换成判定表。

    ⑤ 为判定表中每一列表示的情况设计测试用例。

    这样生成的测试用例(局部,组合关系下的)包括了所有输入数据的取“真”和取“假”的情况,构成的测试用例数据达到最少,且测试用例数据随输入数据数目的增加而增加。

    2)用白盒法设计测试用例

    白盒测试也称为结构测试,根据程序的内部结构和逻辑来设计测试用例,对程序的路径和过程进行测试,检查是否满足设计的需要。

    白盒测试常用的技术是逻辑覆盖、循环覆盖和基本路径测试。

    (1)逻辑覆盖。逻辑覆盖考察用测试数据运行被测程序时对程序逻辑的覆盖程度。主要的逻辑覆盖标准有语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖6种。

    ① 语句覆盖。语句覆盖是指选择足够的测试数据,使被测试程序中每条语句至少执行一次。语句覆盖对程序执行逻辑的覆盖很低,因此一般认为它是很弱的逻辑覆盖。

    ② 判定覆盖。判定覆盖是指设计足够的测试用例,使得被测程序中每个判定表达式至少获得一次“真”值和“假”值,或者说是程序中的每一个取“真”分支和取“假”分支至少都通过一次,因此判定覆盖也称为分支覆盖。判定覆盖要比语句覆盖更强一些。

    ③ 条件覆盖。条件覆盖是指构造一组测试用例,使得每一判定语句中每个逻辑条件的各种可能的值至少满足一次。

    ④ 判定/条件覆盖。判定/条件覆盖是指设计足够的测试用例,使得判定中每个条件的所有可能取值(真/假)至少出现一次,并使每个判定本身的判定结果(真/假)也至少出现一次。

    ⑤ 条件组合覆盖。条件组合覆盖是指设计足够的测试用例,使得每个判定中条件的各种可能值的组合都至少出现一次。满足条件组合覆盖的测试用例是一定满足判定覆盖、条件覆盖和判定/条件覆盖的。

    ⑥ 路径覆盖。路径覆盖是指覆盖被测试程序中所有可能的路径。

    (2)循环覆盖。执行足够的测试用例,使得循环中的每个条件都得到验证。

    (3)基本路径测试。基本路径测试法是在程序控制流图的基础上,通过分析控制流图的环路复杂性,导出基本可执行路径集合,从而设计测试用例。设计出的测试用例要保证在测试中程序的每一条独立路径都执行过,即程序中的每条可执行语句至少执行一次。此外,所有条件语句的真值状态和假值状态都测试过。路径测试的起点是程序控制流图。程序控制流图中的节点代表包含一个或多个无分支的语句序列,边代表控制流。

    白盒测试的原则如下。

    (1)程序模块中的所有独立路径至少执行一次。

    (2)在所有的逻辑判断中,取“真”和取“假”的两种情况至少都能执行一次。

    (3)每个循环都应在边界条件和一般条件下各执行一次。

    (4)测试程序内部数据结构的有效性等。

    4.4.5 调试

    调试发生在测试之后,其任务是根据测试时所发现的错误,找出原因和具体的位置,进行改正。调试工作主要由程序开发人员来进行,谁开发的程序就由谁来进行调试。

    目前常用的调试方法有如下几种。

    (1)试探法。调试人员分析错误的症状,猜测问题的所在位置,利用在程序中设置输出语句,分析寄存器、存储器的内容等手段来获得错误的线索,一步步地试探和分析出错误所在。这种方法效率很低,适合于结构比较简单的程序。

    (2)回溯法。调试人员从发现错误症状的位置开始,人工沿着程序的控制流程往回跟踪代码,直到找出错误根源为止。这种方法适合于小型程序,对于大规模程序,由于其需要回溯的路径太多而变得不可操作。

    (3)对分查找法。这种方法主要用来缩小错误的范围,如果已经知道程序中的变量在若干位置的正确取值,可以在这些位置上给这些变量以正确值,观察程序运行输出结果,如果没有发现问题,则说明从赋予变量一个正确值开始到输出结果之间的程序没有错误,问题可能在除此之外的程序中。否则错误就在所考察的这部分程序中,对含有错误的程序段再使用这种方法,直到把故障范围缩小到比较容易诊断为止。

    (4)归纳法。归纳法就是从测试所暴露的问题出发,收集所有正确或不正确的数据,分析它们之间的关系,提出假想的错误原因,用这些数据来证明或反驳,从而查出错误所在。

    (5)演绎法。根据测试结果,列出所有可能的错误原因。分析已有的数据,排除不可能和彼此矛盾的原因。对其余的原因,选择可能性最大的,利用已有的数据完善该假设,使假设更具体。用假设来解释所有的原始测试结果,如果能解释这一切,则假设得以证实,也就找出错误;否则,要么是假设不完备或不成立,要么有多个错误同时存在,需要重新分析,提出新的假设,直到发现错误为止。

    4.4.6 系统文档

    信息系统的文档,是系统建设过程的“痕迹”,是系统维护人员的指南,是开发人员与用户交流的工具。规范的文档意味着系统是按照工程化开发的,意味着信息系统的质量有了形式上的保障。文档的欠缺、文档的随意性和文档的不规范,极有可能导致原来的开发人员流动以后,系统不可维护、不可升级,变成了一个没有扩展性、没有生命力的系统。

    信息系统的文档,不但包括应用软件开发过程中产生的文档,还包括硬件采购和网络设计中形成的文档;不但包括上述有一定格式要求的规范文档,也包括系统建设过程中的各种来往文件、会议纪要、会计单据等资料形成的不规范文档,后者是建设各方谈判甚至索赔的重要依据;不但包括系统实施记录,也包括程序资料和培训教程等。

    文档在系统开发人员、项目管理人员、系统维护人员、系统评价人员以及用户之间的多种作用总结如下。

    (1)用户与系统分析人员在系统规划和系统分析阶段通过文档进行沟通。这里的文档主要包括可行性研究报告、总体规划报告、系统开发合同和系统方案说明书等。有了文档,用户就能依次对系统分析员是否正确理解了系统的需求进行评价,如不正确,可以在已有文档的基础上进行修正。

    (2)系统开发人员与项目管理人员通过文档在项目期内进行沟通。这里的文档主要有系统开发计划(包括工作任务分解表、PERT图、甘特图和预算分配表等)、系统开发月报以及系统开发总结报告等项目管理文件。有了这些文档,不同阶段之间的开发人员就可以进行工作的顺利衔接,同时还能降低因为人员流动带来的风险,因为接替人员可以根据文档理解前面人员的设计思路或开发思路。

    (3)系统测试人员与系统开发人员通过文档进行沟通。系统测试人员可以根据系统方案说明书、系统开发合同、系统设计说明书和测试计划等文档对系统开发人员所开发的系统进行测试。系统测试人员再将评估结果撰写成系统测试报告。

    (4)系统开发人员与用户在系统运行期间进行沟通。用户通过系统开发人员撰写的文档运行系统。这里的文档主要是用户手册和操作指南。

    (5)系统开发人员与系统维护人员通过文档进行沟通。这里的文档主要有系统设计说明书和系统开发总结报告。有的开发总结报告写得很详细,分为研制报告、技术报告和技术手册三个文档,其中的技术手册记录了系统开发过程中的各种主要技术细节。这样,即使系统维护人员不是原来的开发人员,也可以在这些文档的基础上进行系统的维护与升级。

    (6)用户与维修人员在运行维护期间进行沟通。用户在使用信息系统过程中,将运行过程中的问题进行记载,形成系统运行报告和维护修改建议。系统维护人员根据维护修改建议以及系统开发人员留下的技术手册等文档,对系统进行维护和升级。

    4.4.7 系统转换

    在进行新旧系统转换以前,首先要进行新系统的试运行。在系统测试、调试中,使用的是系统测试数据,有些实际运行中可能出现的问题,很难通过这些数据被发现。所以,一个系统开发后,让它实际运行一段时间,是对系统最好的检验和测试方法。

    系统试运行阶段的主要工作如下。

    (1)对系统进行初始化、输入各种原始数据记录。

    (2)记录系统运行的数据和状况。

    (3)核对新系统输出和旧系统(人工或计算机系统)输出的结果。

    (4)对实际系统的输入方式进行考察(是否方便、效率如何、安全可靠性、误操作保护等)。

    (5)对系统实际运行、响应速度(包括运算速度、传递速度、查询速度和输出速度等)进行实际测试。

    新系统试运行成功之后,就可以在新系统和旧系统之间互相转换。新旧系统之间的转换方式有直接转换、并行转换和分段转换。

    (1)直接转换。直接转换就是在确定新系统运行无误时,立刻启用新系统,终止旧系统运行。这种方式对人员、设备费用很节省。这种方式一般适用于一些处理过程不太复杂,数据不很重要的场合。

    (2)并行转换。这种转换方式是新旧系统并行工作一段时间,经过一段时间的考验以后,新系统正式替代旧系统。对于较复杂的大型系统,它提供了一个与旧系统运行结果进行比较的机会,可以对新旧两个系统的时间要求、出错次数和工作效率给以公正的评价。当然,由于与旧系统并行工作,消除了尚未认识新系统之前的紧张和不安。在银行、财务和一些企业的核心系统中,这是一种经常使用的转换方式。它的主要特点是安全、可靠,但费用和工作量都很大,因为在相当长时间内系统要两套班子并行工作。

    (3)分段转换。分段转换又称逐步转换、向导转换、试点过渡法等。这种转换方式实际上是以上两种转换方式的结合。在新系统全部正式运行前,一部分一部分地代替旧系统。那些在转换过程中还没有正式运行的部分,可以在一个模拟环境中继续试运行。这种方式既保证了可靠性,又不至于费用太大。但是,这种分段转换要求子系统之间有一定的独立性,对系统的设计和实现都有一定的要求,否则就无法实现这种分段转换的设想。

    在实际工作中,转换方法较为灵活。一个信息系统从使用到成熟再到提高,是一个比较长的过程。只有遵循数据处理的阶段性,信息系统才能健康发展。现以一个连锁企业开始实施新系统为例。

    (1)初始阶段。企业首先为应用系统做基本资料的准备,进行总部、“配送”核心系统的实施。

    (2)推广阶段。总部、“配送”系统稳定后,先从1~2家门店试点开始,以门店核心模块为主,完成门店与总部的信息交换、物流过程。然后再逐步推广门店系统,直至完成所有门店的联网工作。

    (3)控制阶段。所有门店联网完成后,进行准确、及时的基本数据采集和调整工作。

    (4)集成阶段。考虑自动补货、自动配货、财务接口等高级模块应用的工作。

    (5)管理阶段。进入数据的全面启用和介入管理决策。最后,系统步入成熟阶段。

    实际上,每个企业在不同阶段的发展过程中,对具体问题的解决方法也是不同的,随时都会进行以上阶段的周期重复,随着每次重复时起点的不断升高,整个企业的数据应用水平也就随之逐步提高了。

    4.5 系统运行和维护知识

    4.5.1 系统维护概述

    软件维护是软件生命周期中的最后一个阶段,处于系统投入生产性运行以后的时期中,因此不属于系统开发过程。软件维护是在软件已经交付使用之后,为了改正错误或满足新的需求而修改软件的过程,即软件在交付使用后对软件所做的一切改动。

    1.系统可维护性概念

    系统的可维护性可以定性地定义为:维护人员理解、改正、改动和改进这个软件的难易程度。提高可维护性是开发软件系统所有步骤的关键目的,系统是否能被很好地维护,可用系统的可维护性这一指标来衡量。

    1)系统的可维护性的评价指标

    (1)可理解性。指别人能理解系统的结构、界面、功能和内部过程的难易程度。模块化、详细设计文档、结构化设计和良好的高级程序设计语言等,都有助于提高可理解性。

    (2)可测试性。诊断和测试的容易程度取决于易理解的程度。好的文档资料有利于诊断和测试,同时,程序的结构、高性能的测试工具以及周密计划的测试工序也是至关重要的。为此,开发人员在系统设计和编程阶段就应尽力把程序设计成易诊断和测试的。此外,在系统维护时,应该充分利用在系统测试阶段保存下来的测试用例。

    (3)可修改性。诊断和测试的容易程度与系统设计所制定的设计原则有直接关系。模块的耦合、内聚、作用范围与控制范围的关系等,都对可修改性有影响。

    2)维护与软件文档

    文档是软件可维护性的决定因素。由于长期使用的大型软件系统在使用过程中必然会经受多次修改,所以文档显得非常重要。

    软件系统的文档可以分为用户文档和系统文档两类。用户文档主要描述系统功能和使用方法,并不关心这些功能是怎样实现的;系统文档描述系统设计、实现和测试等各方面的内容。

    可维护性是所有软件都应具有的基本特点,必须在开发阶段保证软件具有可维护的特点。在软件工程的每一个阶段都应考虑并提高软件的可维护性,在每个阶段结束前的技术审查和管理复查中,应该着重对可维护性进行复审。

    在系统分析阶段的复审过程中,应该对将来要改进的部分和可能会修改的部分加以注解并指明,并且指出软件的可移植性问题以及可能影响软件维护的系统界面;在系统设计阶段的复审期间,应该从容易修改、模块化和功能独立的目的出发,评价软件的结构和过程;在系统实施阶段的复审期间,代码复审应该强调编码风格和内部说明文档这两个影响可维护性的因素。在完成了每项维护工作之后,都应该对软件维护本身进行认真的复审。

    3)软件文档的修改

    维护应该针对整个软件配置,不应该只修改源程序代码。如果对源程序代码的修改没有反映在设计文档或用户手册中,可能会产生严重的后果。每当对数据、软件结构、模块过程或任何其他有关的软件特点作了改动时,必须立即修改相应的技术文档。不能准确反映软件当前状态的设计文档可能比完全没有文档更坏。在以后的维护工作中很可能因文档不完全符合实际而不能正确理解软件,从而在维护中引入过多的错误。

    2.系统维护的内容及类型

    系统维护主要包括硬件设备的维护、应用软件的维护和数据的维护。

    1)硬件维护

    硬件的维护应由专职的硬件维护人员来负责,主要有两种类型的维护活动:一种是定期的设备保养性维护,保养周期可以是一周或一个月不等,维护的主要内容是进行例行的设备检查与保养,易耗品的更换与安装等;另一种是突发性的故障维护,即当设备出现突发性故障时,由专职的维修人员或请厂方的技术人员来排除故障,这种维修活动所花时间不能过长,以免影响系统的正常运行。

    2)软件维护

    软件维护主要是指根据需求变化或硬件环境的变化对应用程序进行部分或全部的修改。修改时应充分利用源程序,修改后要填写程序修改登记表,并在程序变更通知书上写明新旧程序的不同之处。

    软件维护的内容一般有以下几个方面。

    ① 正确性维护。是指改正在系统开发阶段已发生而系统测试阶段尚未发现的错误。这方面的维护工作量要占整个维护工作量的17%~21%。所发现的错误有的不太重要,不影响系统的正常运行,其维护工作可随时进行;而有的错误非常重要,甚至影响整个系统的正常运行,其维护工作必须制定计划,进行修改,并且要进行复查和控制。

    ② 适应性维护。是指使应用软件适应信息技术变化和管理需求变化而进行的修改。这方面的维护工作量占整个维护工作量的18%~25%。由于目前计算机硬件价格的不断下降,各类系统软件层出不穷,人们常常为改善系统硬件环境和运行环境而产生系统更新换代的需求;企业的外部市场环境和管理需求的不断变化也使得各级管理人员不断提出新的信息需求。这些因素都将导致适应性维护工作的产生。进行这方面的维护工作也要像系统开发一样,有计划、有步骤地进行。

    ③ 完善性维护。这是为扩充功能和改善性能而进行的修改,主要是指对已有的软件系统增加一些在系统分析和设计阶段中没有规定的功能与性能特征。这些功能对完善系统功能是非常必要的。另外,还包括对处理效率和编写程序的改进,这方面的维护占整个维护工作的50%~60%,比重较大,也是关系到系统开发质量的重要方面。这方面的维护除了要有计划、有步骤地完成外,还要注意将相关的文档资料加入到前面相应的文档中去。

    ④ 预防性维护。为了改进应用软件的可靠性和可维护性,为了适应未来的软硬件环境的变化,应主动增加预防性的新的功能,以使应用系统适应各类变化而不被淘汰。例如将专用报表功能改成通用报表生成功能,以适应将来报表格式的变化。这方面的维护工作量占整个维护工作量的4%左右。

    3)数据维护

    数据维护工作主要是由数据库管理员来负责,主要负责数据库的安全性和完整性以及进行并发性控制。数据库管理员还要负责维护数据库中的数据,当数据库中的数据类型、长度等发生变化时,或者需要添加某个数据项、数据库时,要负责修改相关的数据库、数据字典,并通知有关人员。另外,数据库管理员还要负责定期出版数据字典文件及一些其他数据管理文件,以保留系统运行和修改的轨迹。当系统出现硬件故障并得到排除后,要负责数据库的恢复工作。

    数据维护中还有一项很重要的内容,那就是代码维护。不过代码维护发生的频率相对较小。代码的维护应由代码管理小组进行。变更代码应经过详细讨论,确定之后要用书面形式贯彻。代码维护的困难往往不在于代码本身的变更,而在于新代码的贯彻。为此,除了成立专门的代码管理小组外,各业务部门要指定专人进行代码管理,通过他们贯彻使用新代码。这样做的目的是要明确管理职责,有助于防止和更正错误。

    3.系统维护的管理和步骤

    要强调的是,系统的修改往往会“牵一发而动全身”。程序、文件、代码的局部修改都可能影响系统的其他部分。因此,系统的维护工作应有计划有步骤地统筹安排,按照维护任务的工作范围、严重程度等诸多因素确定优先顺序,制定出合理的维护计划,然后通过一定的批准手续实施对系统的修改和维护。

    通常对系统的维护应执行以下步骤。

    (1)提出维护或修改要求。操作人员或业务领导用书面形式向系统维护工作的主管人员提出对某项工作的修改要求。这种修改要求一般不能直接向程序员提出。

    (2)领导审查并做出答复,如同意修改则列入维护计划。系统主管人员进行一定的调查后,根据系统的情况和工作人员的情况,考虑这种修改是否必要、是否可行,做出是否修改、何时修改的答复。如果需要修改,则根据优先程度的不同列入系统维护计划。计划的内容应包括维护工作的范围、所需资源、确认的需求、维护费用、维护进度安排以及验收标准等。

    (3)领导分配任务,维护人员执行修改。系统主管人员按照计划向有关的维护人员下达任务,说明修改的内容、要求和期限。维护人员在仔细了解原系统的设计和开发思路的情况下对系统进行修改。

    (4)验收维护成果并登记修改信息。系统主管人员组织技术人员对修改部分进行测试和验收。验收通过后,将修改的部分嵌入系统,取代旧的部分。维护人员登记所做的修改,更新相关的文档,并将新系统作为新的版本通报用户和操作人员,指明新的功能和修改的地方。

    在进行系统维护过程中,还要注意维护的副作用。维护的副作用包括两个方面:一是修改程序代码有时会发生灾难性的错误,造成原来运行比较正常的系统变得不能正常运行。为了避免这类错误,要在修改工作完成后进行测试,直至确认和复查无错为止。二是修改数据库中数据的副作用,当一些数据库中的数据发生变化时可能导致某些应用软件不再适应这些已经变化了的数据而产生错误。为了避免这类错误,一是要有严格的数据描述文件,即数据字典系统;二是要严格记录这些修改并进行修改后的测试工作。

    总之,系统维护工作是信息系统运行阶段的重要工作内容,必须予以充分的重视。维护工作做得越好,信息系统的作用才能够得以充分发挥,信息系统的寿命也就越长。

    4.5.2 系统评价

    1.系统评价概述

    信息系统的评价分为广义和狭义两种。广义的信息系统评价是指从系统开发的一开始到结束的每一阶段都需要进行评价。狭义的信息系统评价则是指在系统建成并投入运行之后所进行的全面、综合的评价。

    按评价的时间与信息系统所处的阶段的关系,又可从总体上把广义的信息系统评价分成立项评价、中期评价和结项评价。

    (1)立项评价。指信息系统方案在系统开发前的预评价,即系统规划阶段中的可行性研究。评价的目的是决定是否立项进行开发,评价的内容是分析当前开发新系统的条件是否具备,明确新系统目标实现的重要性和可能性,主要包括技术上的可行性、经济上的可行性、管理上的可行性和开发环境的可行性等方面。由于事前评价所用的参数大都是不确定的,所以评价的结论具有一定的风险性。

    (2)中期评价。项目中期评价包含两种含义,一是指项目方案在实施过程中,因外部环境出现重大变化,例如市场需求变化、竞争性技术或更完美的替代系统的出现,或者发现原先设计有重大失误等,需要对项目的方案进行重新评估,以决定是继续执行还是终止该方案;另一种含义也可称为阶段评估,是指在信息系统开发正常情况下,对系统设计、系统分析、系统实施阶段的阶段性成果进行评估。由于一般都将阶段性成果的提交视为信息系统建设的里程碑,所以,阶段评估又可叫里程碑式评价。

    (3)结项评价。信息系统的建设是一个项目,是项目就需要有终结时间。结项评价是指项目准备结束时对系统的评价,一般是指在信息系统投入正式运行以后,为了了解系统是否达到预期的目的和要求而对系统运行的实际效果进行的综合评价。所以,结项评价又是狭义的信息系统评价。信息系统项目的鉴定是结项评价的一种正规的形式。结项评价的主要内容包括系统性能评价、系统的经济效益评价以及企业管理效率提高、管理水平改善、管理人员劳动强度减轻等间接效果。通过结项评价,用户可以了解系统的质量和效果,检查系统是否符合预期的目的和要求;开发人员可以总结开发工作的经验、教训,这对今后的工作十分有益。

    在对信息系统进行评价考核时,应该注意以下几个问题。

    (1)信息系统通过基本资料录入、进货、订货、盘点和零售等各个环节采集进来,其中任意一个环节的数据录入出现问题,都将导致最终报表的不准确,而报表不准确就意味着企业决策者无法根据报表决定企业的运作,更谈不上数据分析和决策支持了。这也是目前大部分使用了信息系统的企业普遍存在的问题。究竟是什么原因导致了数据采集的不准确呢?一些企业错误地将数据准确性作为考核信息部的一个指标,其实数据不准确更多源于管理上存在的问题,正因为数据源头非常多,所造成的数据不一致的问题不是信息部都能解决的,最终数据采集的成败将由最高管理层对数据采集各环节的管理力度所决定。而数据采集的成败又将最终决定整个信息系统应用的成败。

    (2)信息系统并不是万能系统。系统应用的过程中,有些问题是信息系统擅长解决的,如大量的、重复的、规范性的事务处理;而有些问题是信息系统不擅长解决的,如特殊的、偶然的、不规范的经营管理内容。让信息系统做不擅长的工作,势必在应用的过程中,投入的管理成本远远大于它所产生的效益。对这种灵活、多变的情况,不妨采用人工处理或通过制度的限制,尽量避免不规范的行为频繁发生,从而真正实现企业简单复制、快速扩张、规模效益的目的。

    2.系统评价的指标

    从以下几方面综合考虑,建立起一套指标体系理论框架。

    (1)从信息系统的组成部分出发,信息系统是一个由人机共同组成的系统,所以可以按照运行效果和用户需求(人)、系统质量和技术条件(机)这两条线索构造指标。

    (2)从信息系统的评价对象出发,对于开发方来说,他们所关心的是系统质量和技术水平;对于用户方而言,关心的是用户需求和运行质量;系统外部环境则主要通过社会效益指标来反映。

    (3)从经济学角度出发,分别按系统成本、系统效益和财务指标三条线索建立指标。