《软件工程(第4版?修订版)》—第1章1.8节软件工程发生了多大的变化

1.8 软件工程发生了多大的变化
软件工程(第4版•修订版)
我们已经对构建软件和建造房子进行了比较。每年全国会建造几百栋房子,觉得满意的客户会搬进去。每年开发人员构造数百个软件产品,但是,更常见的是客户对结果不满意。为什么会存在这种差别呢?如果可以如此容易地列举出系统的开发步骤,那么为什么软件工程师生产高质量的软件却是这样艰难呢?

让我们回过头来再考虑建造房子的例子。在建造房子的过程中,Howell夫妇不断地检查计划。他们还有很多时候会改变自己的想法。同样地,软件开发允许客户在每一个步骤评审计划并且对设计进行改变。毕竟,如果开发人员生产出一个非凡的产品却不能满足客户的要求,那么最终的系统将只会浪费所有人的时间和精力。

由于这样的原因,以灵活的方式运用软件工程工具和技术是至关重要的。过去,作为开发人员,我们假定客户从一开始就知道他们想要什么,但这种稳定性通常不符合实际情况。随着一个项目展开,开始没有预料到的约束就会出现。例如,在选定一个项目要使用的硬件和软件之后,我们可能发现由于客户需求的变化,使得很难使用特定的数据库管理系统生成承诺给客户的菜单;或者发现与系统交互的另外一个系统已经改变了它的过程或数据的格式;我们甚至可能发现硬件或软件并没像厂商的文档所承诺的那样工作。因此,我们必须记住每一个项目都是与众不同的,必须使所选择的工具和技术能够反映对这个项目的约束。

我们还必须承认,大多数系统并不是单独存在的。它们与其他的系统交互,或接受信息或提供信息。开发这样的系统会很复杂,原因很简单,相互通信的系统之间需要大量的协调行为。对于那些并行开发的系统来讲,这种复杂性更是如此。在过去,开发人员很难确保系统间接口的文档的精确性和完整性。在后面的章节中,我们将讨论控制接口问题的相关事项。

1.8.1 变化的本质
有很多问题会影响到软件开发项目的成功,上述那些问题也在其中。无论采用什么样的方法,我们都必须既要展望未来,也要回顾过去。也就是说,我们必须回顾以前的开发项目,看一看关于软件质量保证的有效性以及关于技术和工具的有效性,我们到底学到了什么。另外,还要预测在将来很有可能改变我们实践的软件开发的方式以及软件产品的使用方式。Wasserman指出,自从20世纪70年代以来,软件开发一直发生着巨大的变化(Wasserman 1995)。例如,早期的应用软件是运行在单处理器上的,通常是大型机。输入是线性的,往往是一副卡片或一个输入磁带,而输出是字母数字。系统用两种基本方式来设计:转换(transformation),它将输入转换为输出;事务(transaction),由输入决定哪个功能将被执行。如今,基于软件的系统已经大不相同,并且更为复杂。它们通常运行在多个系统上,有时配置在具有分布式功能的客户/服务器体系结构中。软件不仅执行用户需要的主要功能,而且还要执行网络控制、安全性、用户界面表示和处理,以及数据或对象管理。传统的“瀑布”开发方法假定开发活动是线性前进的,即只有在一个活动完成以后才会进行下一个活动(将在第2章中学习)。这种方法不再灵活也不再适合于当今的系统了。

在Stevens的演讲中,Wasserman通过已经改变软件工程实践的7个关键因素,总结了这些变化(Wasserman 1996),如图1-12中所示。

(1) 商用产品投入市场时间的紧迫性。
(2) 计算技术在经济上的转变:更低的硬件成本,更高的开发、维护成本。

(3) 功能强大的桌面计算的可用性。

(4) 广泛的局域网和广域网。

(5) 面向对象技术的采用及其有效性。

(6) 使用窗口、图标、菜单和指示器的图形用户界面。

(7) 软件开发瀑布模型的不可预测性。

例如,市场压力意味着企业必须抢在竞争对手之前准备好新的产品和服务,否则,企业本身的生存将会受到威胁。因此,如果传统的评审和测试技术需要大量的时间投入,但是却没有减少相应的故障或失效率,那么这些技术就不能再使用。类似地,以前花在提高速度或减少空间方面的代码优化的时间不再是明智的投资,因为增加磁盘和内存条可能是更便宜的解决方案。

另外,桌面计算把开发的权利交到用户的手中,用户现在使用他们的系统开发电子表格和数据库应用、小程序甚至是专门的用户界面模拟程序。这种开发责任的转移意味着软件工程师更有可能构建比以前更为复杂的系统。类似地,大多数用户和开发人员可以利用巨大的网络资源,使得用户更容易在没有特殊应用的情况下找到信息。例如,现在在万维网上搜索是快速、容易和有效的。用户不再需要为找到自己所需的内容而编写数据库应用。

开发人员现在发现他们的工作价值也增加了。面向对象的技术、网络和复用库,使开发人员可以直接、快速地将大量可复用模块用于新的应用中。并且,常常用专门的工具开发图形用户界面,有助于使复杂的应用友好地面对用户。由于在分析问题方面我们已经变得精于此道,因此,现在能够对一个系统进行划分,以便并行地开发其子系统,这就需要一个与“瀑布”模型有很大不同的开发过程。将在第2章中看到,我们有很多选择,包括使我们建立原型的过程(用于同客户和用户一起验证需求是否正确,并评价设计的可行性)和活动间正确迭代的过程。这些步骤有助于确保在将需求和设计变成代码之前,使它们尽可能没有故障。

1.8.2 软件工程的Wasserman规范
Wasserman指出,7个技术变化中的任何一个都对软件开发过程有着重大的影响(Wasserman 1996)。它们合在一起,改变了我们的工作方式。在DeMarco的介绍中,描述了这种根本的转变:我们首先解决了容易的问题——这意味着尚未解决的一组问题比以前更加困难了。Wasserman通过提出软件工程中存在的8个基本概念来应对这一挑战。这些概念构成了有效的软件工程规范的基础。在这里给出它们的简要介绍,在后面的章节中,将回过头来探讨它们在什么地方适用于我们所做的事情,以及如何应用于我们所做的事情。

1.抽象
有时,在一个问题的“自然状态”(即如同客户和用户表达的那样)考虑这个问题是一件令人畏惧的事情。在问题的“自然状态”下,我们不可能发现以有效的或者甚至只是可行的方法处理问题的显而易见的方式。抽象(abstraction)是在某种概括层次上对问题的描述,使得我们能够集中于问题的关键方面而不会陷入细节。这个概念与转换(transformation)不同,转换是把问题转移到另外一个我们理解得更好的环境中。转换通常用于将一个问题从现实世界转移到数学世界中,这样我们能够利用数字的知识来解决问题。

通常,我们使用抽象标识对象的类,以便能够把多个项组合在一起。这样,我们处理的事情可以更少,而且可以集中考虑每个类中各个项之间的共性。我们可以讨论一个类中各个项的性质或属性,检查属性以及类之间的关系。例如,假定我们要为一条大的、复杂河流构建一个环境监测系统。监控设备可能包括监测空气质量、水质、温度、流速以及其他环境特性的传感器。但是,为了达到目的,我们可能决定定义一个称为“传感器”的类。类中的每个项具有固定的属性,不论它监测哪个特性:高度、重量、电力需求、维护进度等。我们在了解问题环境的过程中,或在设计解决方案的过程中,处理的是类,而不是它的元素。因此,类的使用有助于简化问题陈述并使我们集中于问题的本质要素或特性。

抽象也可以按层次的方式进行组织。例如,传感器是一种类型的电子设备,而我们可能有两种类型的传感器:水传感器和空气传感器。

因此,可以构成图1-13所示的简单层次结构。通过隐藏其中一些细节,我们可以集中精力考虑必须处理的对象的本质特性,并且得到简单、优雅的解决方案。我们将在第5章、第6章和第7章中更详细地讨论抽象和信息隐藏。

2.分析和设计方法以及表示法
当设计一个作为课程作业的程序时,通常需要自己完成工作。产生的文档是一个正式描述,它告诉你自己为什么选择这个特定的方法、变量名的含义是什么以及实现的算法。但是,当与团队一起工作的时候,必须与开发过程中的其他参与者进行交流。大多数工程师,无论他们是做什么样的工程,都会使用标准的表示法来帮助他们进行交流以及文档化相关决策。例如,建筑师画了一张图或蓝图,任何其他的工程师都能够理解他画的图。更为重要的是,公共的表示法使得建筑承包商能够理解建筑师的意图和想法。正如将在第4章、第5章、第6章和第7章中看到的,软件工程中没有类似的标准,由此产生的误解是当今软件工程中的一个关键问题。
分析和设计方法不止是提供了交流媒介,还使我们能够建立模型并检查模型的完整性和一致性。再者,我们可以更容易地从以前的项目中复用需求和设计组件,从而相对容易地提高生产率和质量。

但是,在我们能够决定一组标准的方法和工具之前,仍然有许多悬而未决的问题需要解决。正如我们将在后面的章节中看到的那样,不同的工具和技术处理的是问题的不同方面,我们需要标识建模原语,以便用一种技术就能获取问题的所有重要的方面。或者我们需要开发一种供所有方法使用的表示技术,当然可能需要某种形式的剪裁。

3.用户界面原型化
原型化(prototyping)意味着构建一个系统的小版本,通常只有有限的功能,它可用于:

帮助用户或客户标识系统的关键需求;
证明设计或方法的可行性。
通常,原型化过程是迭代的:首先构建原型,然后对原型进行评估(利用用户和客户的反馈),考虑如何改进产品或设计,之后再构建另外一个原型。当我们和客户认为手头问题的解决方案令人满意时,迭代过程就终止了。

原型化通常用来设计一个良好的用户界面(user interface),即系统与用户交互的部分。但是,在其他场合也可以使用原型,甚至是在嵌入式系统(embedded system)(即其中的软件功能不是明确地对用户可见的系统)中。原型能够向用户展示系统将会有什么样的功能,而不管它们是用硬件还是用软件实现的。因为从某种意义上讲,用户界面是应用领域和软件开发团队之间的桥梁,所以,原型化可以把使用其他需求分析方法不能明确的问题和假设表面化。我们将在第4章和第5章讨论用户界面原型化的作用。

4.软件体系结构
系统的整个体系结构不仅对实现和测试的方便性很重要,而且对维护和修改系统的速度和有效性也很重要。体系结构的质量可能成就一个系统,也可能损害一个系统。事实上,Shaw和Garlan将体系结构独自作为规范,它影响整个开发过程(Shaw and Garlan 1996)。一个系统的体系结构应该体现我们将在第5章和第7章学习的良好设计的原则。

系统的体系结构根据一组体系结构单元以及单元之间的相互关系来描述系统。单元越独立,体系结构越模块化,就越容易分别设计和开发不同的部分。Wasserman指出,至少有5种方法可以将系统划分为单元(Wasserman 1996)。

(1) 模块化分解:基于指派到模块的功能。

(2) 面向数据的分解:基于外部数据结构。

(3) 面向事件的分解:基于系统必须处理的事件。

(4) 由外到内的设计:基于系统的用户输入。

(5) 面向对象的设计:基于标识的对象的类以及它们之间的相互关系。

这些方法并不是相互排斥的。例如,可以用面向事件的分解设计用户界面,同时,使用面向对象或面向数据的方法来设计数据库。我们将在后面的章节中进一步详细分析这些技术。这些方法之所以重要,是因为它们体现了我们的设计经验,并通过复用已经做过的和所学到的,充分利用过去的项目。

5.软件过程
自从20世纪80年代后期以来,很多软件工程师已经在密切留意开发软件的过程以及由此产生的产品。活动中的组织和规范对软件的质量和软件开发的速度的积极作用已经得到承认。然而,Wasserman指出:

不同应用类型和组织文化之间的巨大差异使得不可能对过程本身进行预先规定。因此,软件过程不可能以抽象和模块化的方式作为软件工程的基础。(Wasserman 1996)

相反,他提出,不同的软件类型需要不同的过程。尤其是,Wasserman指出企业范围的应用程序需要大量的控制,而单个的或部门级的应用程序可以利用快速应用程序开发,如图1-14所示。

利用目前的工具,很多中小规模的系统可以由一两个开发人员来完成,其中每个开发人员必须担任多个角色。这样的工具可能包含文本编辑器、编程环境、测试支持工具,还可能包含一个获取关于产品和过程的关键数据元素的小型数据库。因为项目的风险相对较低,所以需要很少的管理支持或评审。
但是,大型、复杂的系统需要更多的结构、检查和平衡。这些系统通常涉及很多客户和用户,并且开发会持续很长时间。再者,因为某些关键子系统可能由他人提供或用硬件实现,开发人员并不总是能够控制整个过程。这种类型的高风险系统需要分析和设计工具、项目管理、配置管理、更复杂的测试工具以及对系统更严格的评审和因果分析。第2章将详细讨论若干可选的过程,以了解不同的过程是如何处理不同的目标的。然后,在第12章和第13章中,我们评估一些过程的有效性,并探讨对它们进行改进的方法。

6.复用
在软件开发和维护中,通常通过复用以前开发项目中的项来利用应用程序之间的共性。例如,在不同的开发项目中,我们使用同样的操作系统和数据库管理系统,而不是每次都构建一个新的。类似地,当我们构建一个与以前做过的项目类似但有所不同的系统时,可以复用需求集、部分设计以及测试脚本或数据。Barnes和Bollinger指出,复用并不是一个新的思想,他们还给出了很多有趣的例子,说明复用的不仅仅是代码(Barnes and Bollinger 1991)。

Prieto-Diaz介绍了这样一种理念:可复用构件是一种商业资产(Prieto-Diaz 1991)。公司和组织机构对那些可复用的项进行投资,而当这些项再次用于后面的项目中的时候,就可以获得巨大的收益。但是,制定一个长期、有效的可复用计划可能很困难,因为存在如下这些障碍。

有时候,构建一个小的构件比在可复用构件库中搜索这样一个构件要更快。
要使一个构件足够通用、可以在将来被其他开发人员很容易地复用,则可能需要花费格外多的时间。
由于难以对做过的质量保证和测试的程度进行文档化,可能会导致一个潜在的复用人员认为构件的质量是令人满意的。
如果某个复用的构件失效或需要进行更新,不清楚谁应该对此负责。
理解和复用一个由他人编写的构件,其代价可能是高昂的,也可能很耗时。
在通用性和专业性之间通常存在冲突。
我们将在第12章中更详细地讨论复用,并研究几个成功复用的例子。

7.测度
改进是软件工程研究的驱动力:通过改进过程、资源和方法,我们可以生产和维护更好的产品。但是,我们有时只能概况地表示改进目标,原因是没有量化地描述我们做了什么以及我们的目标是什么。正因为如此,软件测度已经成为好的软件工程实践的一个关键方面。通过量化我们做了什么以及我们的目标是什么,就可以用通用数学语言来描述我们的行动和结果,从而能够评估我们的进展。另外,量化的方法允许我们比较不同项目的进展。例如,当John Young担任惠普公司的CEO时,他设置了“10X”的目标,即无论对于何种应用的类型和领域,对于惠普的每一个项目,在质量和生产率方面都要有10倍的提高(Grady and Caswell 1987)。

在较低的抽象层次上,测度有助于使我们的过程和产品的特定特性更加可见。将我们对现实的、经验世界的理解转换为形式化的、数学世界中的要素和相互关系,通常是有益的,这样,我们可以操纵它们,从而得到进一步的理解。正如图1-15所示的那样,可以使用数学和统计的方法来解决问题、寻找趋势或刻画一种情形(例如使用平均值和标准差)。而这个新的信息可以接着被映射回现实世界,作为我们试图解决的现实问题的解决方案的一部分。在本书中,我们将看到测度如何应用于支持分析和决策的例子。

8.工具和集成环境
多年以来,厂商一直推荐使用CASE(计算机辅助软件工程)工具,其中的标准化的集成开发环境将增强软件开发。但是,我们已经看到,不同的开发人员是如何使用不同的过程、方法和资源的。因此,一个统一的方法说起来容易,做起来就难了。
另一方面,研究人员已经提出了几个框架,使我们能对已有的环境和打算构建的环境进行比较和对照。这些框架还允许我们检验每个软件工程环境提供的服务,决定哪一个环境最适合于给定的问题或应用程序的开发。

对工具进行比较主要的难点之一是厂商很少针对整个开发生命周期。相反,他们集中于小的活动集,例如设计或测试等,并且由用户把选择的工具集成到一个完整的开发环境中。Wasserman指出了在任何工具集成中必须处理的下列5个问题(Wasserman 1990)。

(1) 平台集成:工具在异构型网络中的互操作能力。

(2) 表示集成:用户界面的共性。

(3) 过程集成:工具和开发过程之间的链接。

(4) 数据集成:工具共享数据的方式。

(5) 控制集成:一个工具通知和启动另一个工具中的动作的能力。

在本书后面的每一章中,我们将研究支持本章描述的活动和概念的工具。

你可以将这里描述的8个概念想象成把本书编织起来的8条线,它们把分离的活动连接起来,称为软件工程。随着我们对软件工程了解得越来越多,我们将重新讨论这些概念,以了解它们是如何把软件工程统一和提升为一个学科的。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

时间: 2024-10-23 04:37:38

《软件工程(第4版?修订版)》—第1章1.8节软件工程发生了多大的变化的相关文章

《软件工程(第4版?修订版)》—第1章1.2节软件工程取得了哪些进展

1.2 软件工程取得了哪些进展软件工程(第4版•修订版)编写软件既是一门艺术也是一门科学.作为一名计算机专业的学生,深入理解这句话是非常重要的.计算机科学家和软件工程研究人员研究的是计算机的机制,并建立起使它们具有更高生产率.更有效的理论.但同时,他们也设计计算机系统并编写程序,执行相关任务,这是一项融合艺术.天赋和技巧的实践性工作.在具体的系统上执行特定任务,可能会存在很多方法,但是,某一种方法可能更有效.更精确.更易于修改.更容易使用或更便于理解.任何黑客都能够编写代码完成工作,但是,要写出

《软件工程(第4版?修订版)》—第1章1.4节软件工程涉及的人员

1.4 软件工程涉及的人员软件工程(第4版•修订版)软件开发的一个关键部分是客户与开发人员之间的交流,如果交流失败,那么系统也将失败.必须在构建有助于解决问题的系统之前,理解客户想要什么以及他们需要什么.要做到这一点,我们把讨论的重点转向软件开发所涉及的人员. 从事软件开发工作的人员数目取决于项目的规模和难易程度,然而,不论涉及多少人,都可以区分他们在整个项目生命周期中的角色.因此,对于一个大型项目,一个人或一个小组可能被确定地指派为某一个角色:而在小型项目中,一个人或一个小组可以一次承担几个角

《Ruby程序员修炼之道》(第2版)—第1章1.1节进入Ruby的世界

第1章 进入Ruby的世界 Ruby程序员修炼之道(第2版) 本章主要内容 Ruby语法的生存工具箱① Ruby基础编程指引:程序编写.保存.运行和错误检查 Ruby安装指南 Ruby的扩展机制 Ruby中易用的命令行工具,包括交互式Ruby解释器(irb) 本书的内容是Ruby基础,而本章是基础中的基石.本章的目标是让读者在开始学习Ruby之前掌握足够的知识和技巧. 接下来读者将看到Ruby的基本语法和技术,以及Ruby的运行机制:如何写一个程序,怎样使用Ruby运行程序,以及如何把一个程序分

《Ruby程序员修炼之道》(第2版)—第1章1.4节易用的Ruby工具和应用程序

1.4 易用的Ruby工具和应用程序 安装Ruby后,就可以得到一组重要的命令行工具,它们被安装在配置信息bindir所指定的文件夹中,通常是/usr/local/bin./usr/bin或者/opt同等的目录中.(可以使用require "rbconfig"去测试一下RbConfig::CONFIG["bindir"]返回的结果.)这些命令行工具具体是以下几个. ruby:解释器. irb:Ruby交互式解释器. - rdoc和ri:Ruby文档工具. rake:

《软件测试技术大全:测试基础 流行工具 项目实战(第3版)》—第1章1.6节模拟面试问答

1.6 模拟面试问答 本章介绍的是软件测试相关的背景,以及软件测试的发展情况等.身为软件测试员,应该或多或少地了解软件测试的发展动态,及其相关的历史事件等内容,这样无论是在与同行交流,向开发人员介绍和讲解测试,还是在应聘面试中,都会有更多的话题. 一般在应聘过程中,面试官可能会问到以下一些问题,读者可以根据自己的了解以及在本章中学到的内容做出相应的回答. (1)您觉得目前的软件测试行业的现状是怎样的? 参考答案:目前的软件测试行业在国内正在蓬勃地发展中,但是由于起步比较晚,虽然大部分公司都已经设

《Ruby程序员修炼之道》(第2版)—第1章1.3节Ruby扩展和编程库

1.3 Ruby扩展和编程库本节的要点并不是关于Ruby标准库的参考.曾在引言中解释过,本书的目标不是编写一本Ruby语言的参考文档,而是教会读者使用Ruby语言并掌握它,并最终拓宽视野. 相应地,本节的目标是讲述扩展的工作方式,即如何使用Ruby运行这些扩展.它们之间技术实现的不同,并最终能让用户自己编写扩展和库文件的扩展架构. 随Ruby发布的扩展通常全部作为标准库来引用.标准库包括为不同项目和任务所提供的扩展,如数据库管理.网络.数学领域.XML处理等.标准库精密的结构每次改变,哪怕只有一

《Ruby程序员修炼之道》(第2版)—第1章1.2节剖析Ruby的安装

1.2 剖析Ruby的安装在系统上安装Ruby意味着在许多磁盘目录中安装了Ruby语言的库和支持文件.大多数时候,Ruby都知道如何找到其所需要的这些目录而不用弹出提示.但是了解Ruby安装的知识对了解Ruby本身大有益处. 查看Ruby的源代码 除了Ruby安装目录体系之外,Ruby的源代码目录也安装好了.如果没有,可以到Ruby的主页中下载.源代码目录中包含了许多在最终安装中出现的Ruby文件和许多已编译为目标文件并安装好的C语言文件.另外,源代码目录包含了一些如ChangeLog和软件授权

《设计模式沉思录》—第1章1.1节对模式的十大误解

第1章 介绍设计模式沉思录在阅读本书之前,如果读者还没有听说过一本名叫<设计模式>(Design Patterns: Elements of Reusable Object-Oriented Software [GoF95])的书,那么现在正好可以去找一本来读.如果读者听说过该书,甚或自己还有一本但却从来没有实际研读过,那么现在也正好应该好好研读一下. 如果你仍然在继续往下阅读,那么我会假设你不是上述两种人.这意味着你对模式有大致的了解,特别是对23个设计模式有一定的了解.你至少需要具备这样的

《软件工程(第4版?修订版)》—第1章1.11节本章对单个开发人员的意义

1.11 本章对单个开发人员的意义软件工程(第4版•修订版)本章介绍了许多概念,它们对于优秀的软件工程研究和实践来说都很重要.单个的软件开发人员可以通过下面的方法使用这些概念. 当有一个问题需要解决时(无论解决方案是否涉及软件),可以通过把问题分解成不同的组成部分和各部分之间的关系来分析问题.然后,解决单个子问题并把它们合并成为统一的整体,从而产生一个解决方案.必须理解需求可能发生变化,即使在分析问题.形成解决方案时需求也会变化.因此,解决方案必须是良好文档化的并且具有灵活性的,还应该把假设和使