1.5 软件工程方法学
1.5.1 软件工程方法学的定义
软件工程方法为软件开发提供了“如何做”的技术,软件工具为软件工程方法提供了自动的或半自动的软件支撑环境;过程是为了获得高质量的软件所需要完成的一系列任务框架,它规定了完成各项任务的工作步骤。
通常把在软件开发过程中使用的一整套技术方法的集合称为方法学(Methodology)。软件工程方法学包含三个要素:方法、工具和过程。
其中:①方法是完成软件开发各项任务的技术方法,回答“怎样做”的问题。②工具是为运用方法而提供的自动的或半自动的软件工程支撑环境,软件开发工具是用于辅助软件生命周期过程的基于计算机的工具,通常可以设计并实现工具来支持特定的软件工程方法,减少手工方式管理的负担,让软件工程更加系统化,工具的种类包括支持单个任务的工具及囊括整个开发过程的工具。③过程是为了获得高质量的软件所需要完成的一系列任务的框架,它规定了完成各项任务的工作步骤。
1.5.2 软件工程方法学的类型
软件工程方法是软件工程学科的核心内容,从20世纪60年代末以来,出现了许多软件工程方法,其中最具影响的是结构化设计方法、面向对象方法和形式化方法。
(1)结构化设计方法
结构化设计方法(Structured Design,SD)是一种传统的软件开发方法,它是由结构化分析、结构化设计和结构化程序设计三部分有机组合而成的。它的基本思想:把一个复杂问题的求解过程分阶段进行,而且这种分解是自顶向下,逐层分解,使得每个阶段处理的问题都控制在人们容易理解和处理的范围内。结构化方法将软件开发全过程依次划分为若干个阶段,采用结构化技术来完成每个阶段的任务。特点:①强调自顶向下顺序地完成软件开发的各阶段任务;②结构化方法要么面向行为,要么面向数据,缺乏使两者有机结合的机制。
结构化分析方法是以自顶向下、逐步求精为基点,以一系列经过实践的考验被认为是正确的原理和技术为支撑,以数据流图、数据字典、结构化语言、判定表、判定树等图形表达为主要手段,强调开发方法的结构合理性和系统的结构合理性的软件分析方法。
结构化设计方法是以自顶向下、逐步求精、模块化为基点,以模块化、抽象、逐层分解求精、信息隐蔽化局部化和保持模块独立为准则的设计软件的数据架构和模块架构的方法学。
结构化方法按软件生命周期划分,有结构化分析(SA)、结构化设计(SD)和结构化实现(SP)。其中要强调的结构化方法学是一个思想准则的体系,虽然有明确的阶段和步骤,但是也集成了很多原则性的东西。所以,学会结构化方法,仅从理论知识上去了解是不够的,还要从实践中慢慢理解各准则,并将其变成自己的方法学。
结构化分析的步骤如下:
①分析当前的情况,做出反映当前物理模型的数据流图。
②推导出等价的逻辑模型的数据流图。
③设计新的逻辑系统,生成数据字典和基元描述。
④建立人机接口,提出可供选择的目标系统物理模型的数据流图。
⑤确定各种方案的成本和风险等级,据此对各种方案进行分析。
⑥选择一种方案。
⑦建立完整的需求规约。
结构化设计方法给出一组帮助设计人员在模块层次上区分设计质量的原理与技术。它通常与结构化分析方法衔接起来使用,以数据流图为基础得到软件的模块结构。结构化设计方法尤其适用于变换型结构和事务型结构的目标系统。在设计过程中,它从整个程序的结构出发,利用模块结构图表述程序模块之间的关系。结构化设计的步骤如下:
①评审和细化数据流图。
②确定数据流图的类型。
③把数据流图映射到软件模块结构,设计出模块结构的上层。
④基于数据流图逐步分解高层模块,设计中下层模块。
⑤对模块结构进行优化,得到更为合理的软件结构。
⑥描述模块接口。
(2)面向对象方法
面向对象方法(Object-Oriented Method)是一种把面向对象的思想应用于软件开发过程中,指导开发活动的系统方法,简称OO(Object-Oriented)方法,是建立在“对象”概念基础上的方法学。对象是由数据和容许的操作组成的封装体,与客观实体有直接对应关系,一个对象类定义了具有相似性质的一组对象。而继承性是对具有层次关系的类的属性和操作进行共享的一种方式。所谓面向对象就是基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解、刻画客观世界和设计、构建相应的软件系统。
OO方法起源于面向对象的编程语言(简称OOPL)。20世纪50年代后期,在用FORTRAN语言编写大型程序时,常出现变量名在程序不同部分发生冲突的问题。鉴于此,ALGOL语言的设计者在ALGOL60中采用了以“Begin…End”为标识的程序块,使块内变量名是局部的,以避免它们与程序中块外的同名变量相冲突。这是编程语言中首次提供封装(保护)的尝试。此后程序块结构广泛用于高级语言如Pascal、Ada、C之中。
20世纪60年代中后期,Simula语言在ALGOL基础上研制开发,它将ALGOL的块结构概念向前发展一步,提出了对象的概念,并使用了类,也支持类继承。20世纪70年代,Smalltalk语言诞生,它取Simula的类为核心概念,它的很多内容借鉴于Lisp语言。由Xerox公司经过对Smautalk72/76持续不断地研究和改进之后,于1980年推出并商品化,它在系统设计中强调对象概念的统一,引入对象、对象类、方法、实例等概念和术语,采用动态联编和单继承机制。
从20世纪80年代起,人们基于以往已提出的有关信息隐蔽和抽象数据类型等概念,以及由Modula2、Ada和Smalltalk等语言所奠定的基础,再加上客观需求的推动,进行了大量的理论研究和实践探索,不同类型的面向对象语言(如Object-c、Eiffel、C++、Java、Object-Pascal等)逐步发展和建立起来。
面向对象源出于Simula,真正的OOP由Smalltalk奠基。Smalltalk现在被认为是最纯的OOPL。正是通过Smalltalk80的研制与推广应用,使人们注意到OO方法所具有的模块化、信息封装与隐蔽、抽象性、继承性、多样性等独特之处,这些优异特性为研制大型软件、提高软件可靠性、可重用性、可扩充性和可维护性提供了有效的手段和途径。
20世纪80年代以来,将面向对象的基本概念和运行机制运用到其他领域,获得了一系列相应领域的面向对象的技术。面向对象方法已被广泛应用于程序设计语言、形式定义、设计方法学、操作系统、分布式系统、人工智能、实时系统、数据库、人机接口、计算机体系结构以及并发工程、综合集成工程等,在许多领域的应用都得到了很大的发展。1986年在美国举行了首届“面向对象编程、系统、语言和应用(OOPSLA'86)”国际会议,使面向对象受到世人瞩目,其后每年都举行一次,这进一步标志OO方法的研究已普及到全世界。
面向对象方法学:OO方法遵循一般的认知方法学的基本概念(即“有关演绎—从一般到特殊和归纳—从特殊到一般”的完整理论和方法体系)而建立面向对象方法等基础。
面向对象方法学要点之一:认为客观世界是由各种“对象”所组成的,任何事物都是对象,每一个对象都有自己的运动规律和内部状态,每一个对象都属于某个对象“类”,都是该对象类的一个元素。复杂的对象可以是由相对比较简单的各种对象以某种方式而构成。不同对象的组合及相互作用就构成了要研究、分析和构造的客观系统。
面向对象方法学要点之二:是通过类比,发现对象间的相似性,即对象间的共同属性,这就是构成对象类的依据。
面向对象方法学要点之三:认为对已分成类的各个对象,可以通过定义一组“方法”来说明该对象的功能,即允许作用于该对象上的各种操作。对象间的相互联系是通过传递“消息”来完成的,消息就是通知对象去完成一个允许作用于该对象的操作,至于该对象将如何完成这个操作的细节,则是封装在相应的对象类的定义中的,细节对于外界是隐蔽的。
面向对象方法的具体步骤如下:
①分析确定在问题空间和解空间出现的全部对象及其属性。
②确定应施加于每个对象的操作,即对象固有的处理能力。
③分析对象间的联系,确定对象彼此间传递的消息。
④设计对象的消息模式,消息模式和处理能力共同构成对象的外部特性。
⑤分析各个对象的外部特性,将具有相同外部特性的对象归为一类,从而确定所需要的类。
⑥确定类间的继承关系,将各对象的公共性质放在较上层的类中描述,通过继承来共享对公共性质的描述。
⑦设计每个类关于对象外部特性的描述。
⑧设计每个类的内部实现(数据结构和方法)。
⑨创建所需的对象(类的实例),实现对象间应有的联系(发消息)。
面向对象方法是将数据和对数据的操作紧密地结合起来的方法。软件开发过程是多次反复迭代的演化过程。面向对象方法在概念和表示方法上的一致性,保证了各项开发活动之间的平滑过渡。对于大型、复杂及交互性比较强的系统,使用面向对象方法更有优势。
(3)形式化方法
形式化方法是一种基于形式化数学变换的软件开发方法,它可将系统的规格说明转换为可执行的程序。
在计算机科学和软件工程领域,形式化方法是基于数学的特种技术,适合于软件和硬件系统的描述、开发和验证。将形式化方法用于软件和硬件设计,是期望能够像其他工程学科一样,使用适当的数学分析以提高设计的可靠性和鲁棒性。但是,由于采用形式化方法的成本高,意味着它们通常只用于开发注重安全性的高度整合的系统。
形式化方法在古代就运用了,在现代逻辑中又有了进一步的发展和完善。这种方法特别在数学、计算机科学、人工智能等领域得到广泛运用。它能精确地揭示各种逻辑规律,制定相应的逻辑规则,使各种理论体系更加严密。同时也能正确地训练思维、提高思维的抽象能力。
软件形式化方法最早可追溯到20世纪50年代后期对于程序设计语言编译技术的研究,即J.Backus提出BNF描述Algol60语言的语法,出现了各种语法分析程序自动生成器以及语法制导的编译方法,使得编译系统的开发从“手工艺制作方式”发展成具有牢固理论基础的系统方法。形式化方法的研究高潮始于20世纪60年代后期,针对当时所谓的“软件危机”,人们提出种种解决方法,归纳起来有两类:一是采用工程方法来组织、管理软件的开发过程;二是深入探讨程序和程序开发过程的规律,建立严密的理论,以其用来指导软件开发实践。前者导致“软件工程”的出现和发展,后者则推动了形式化方法的深入研究。经过30多年的研究和应用,今人们在形式化方法这一领域取得了大量、重要的成果,从早期最简单的形式化方法——一阶谓词演算方法到现在的应用于不同领域、不同阶段的基于逻辑、状态机、网络、进程代数、代数等众多形式化方法。形式化方法的发展趋势逐渐融入软件开发过程的各个阶段,从需求分析、功能描述(规约)、(体系结构/算法)设计、编程、测试直至维护。