软件工程

目录

参考资料

参考书

图书名称: Software Engineering: Theory and Practice
封面图片: 软件工程(第4版)
出版印刷时间: 2009
出版社: Pearson 出版
图书作者: [美] Shari Lawrence Pfleeger [加]Joanne M. Atlee 著
译者 杨卫东
ISBN: 9780136061694

友链

软件工程 | luckyray (luckyray-fan.github.io)

09_软件工程_山软智库知识见解_V1.1(1) (kdocs.cn)

软件工程- CSDN搜索

Chapter 1 软件工程概述

软件危机(software crisis)

软件危机:定义、起因、历史、机遇-腾讯云开发者社区-腾讯云 (tencent.com)

软件危机的定义:落后的软件生产方式无法满足迅速增长的计算机软件需求,从而导致软件开发与维护过程中出现一系列严重问题的现象。

1968年,北大西洋公约组织(NATO)在联邦德国的国际学术会议创造软件危机(Software crisis)一词。而1960年代中期开始爆发众所周知的软件危机,为了解决问题,在1968、1969年连续召开两次著名的NATO会议,并同时提出软件工程的概念。

1972年,艾兹赫尔·戴克斯特拉于计算机协会图灵奖的演讲:

软件危机的主要原因,把它很不客气地说:在没有机器的时候,编程根本不是问题;当我们有了计算机,编程开始变成问题;而现在我们有巨大的计算机,编程就成为了一个同样巨大的问题。 艾兹赫尔·戴克斯特拉,《Communications of the ACM》

软件危机使人们认识到中大型软件系统与小型软件有着本质性差异: 大型软件系统开发周期长、费用昂贵、软件质量难以保证、生产率低,它们的复杂性已远超出人脑能直接控制的程度 ,大型软件系统不能沿袭工作室的开发方式,就像制造小木船的方法不能生产航空母舰一样。 它的存在已经有数十年的历史了,一直到了1980年代的面向对象技术才解决了一部分在软件危机上的窘境。

软件危机的表现

  • Projects running over-budget (超出预算)
  • Projects running over-time(超时间)
  • Software was very inefficient(软件效率低)
  • Software was of low quality(软件质量低)
  • Software often did not meet requirements(软件不符合需求)
  • Projects were unmanageable and code difficult to maintain(软件无法管理,代码难以维护)
  • Software was never delivered(软件无法交付)

软件危机的原因(2023.12.04更新,修正错误)

出现的原因:一方面与软件本身的特点有关,另一方面也和软件开发与维护的方法不正确有关。

(1)软件缺乏“可见性”,管理和控制软件开发过程相当困难。
(2)软件规模庞大,而且程序复杂性将随着程序规模的增加而呈指数上升。
(3)开发时期引入错误,导致软件维护通常意味着改正或修改原来的设计,客观上使得软件较难维护。
(4)软件专业人员对软件开发和维护中或多或少地采用了错误的方法和技术。

软件工程概念的提出

为了解决问题,在1968、1969年连续召开两次著名的NATO会议[The 1968/69 NATO Software Engineering Reports],并同时提出软件工程的概念。

科学方法解决问题:
研究如何以系统性的、规范化的、可定量的过程化方法去开发和维护软件,以及如何把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来

I 、What is software?!!

软件(software) = 程序(program) + 文档(document)

The notion of software

程序+文档(张效祥,计算机科学技术百科全书)
程序是计算任务的处理对象和处理规则的描述
文档是为了便于了解程序所需的阐明性资料
Computer programs and associated documentation (Ian Sommerville)
Software products may be developed for a particular customer or may be developed for a general market

II 、What is software engineering?!!

Software engineering

所谓软件工程,是指运用计算机科学、数学管理科学等相关原理,以工程化的思想和方法,来解决软件问题的工程。

定义:两个关键词

理解问题的本质(nature),并给出解决方案(solution)

也就是说,用系统科学的方法解决问题(problem-solution)。

目标:设计和开发高质量的软件。(付出较低开发成本;达到要求的功能;取得较好的性能;开发的软件易于移植;只需较低的维护费用;能按时完成开发任务,及时交付使用)

方法:面向对象模式,结构化模式,基于过程的模式等。

软件工程

软件工程包含什么
1、Method(技术,产生结果的形式化过程) 某一个环节里获取环节结果的方法
2、Tool(工具,用更好的方式完成某件事情的设备或自动化系统) 在某一个环节中可以更好的完成环节的工具,帮助提高生产效率或提高产品质量
3、Procedure(过程,什么情况下用什么工具做什么,以保证生产产品) 技术与工具结合完成一个个过程。
4、Paradigm(范式,产品搭建的方法论或者哲学思想) 过程与过程之间的关系,在方法方面定义一个产品搭建的模式。

III 、What is good software?!!

描述"BUG"的术语

错误(error):设计人员误解需求。(错误可能会导致故障)
故障(fault):开发人员写入到软件制品(程序或文档中)的错误信息。 创建出与需求分析人员和用户的实际意图不相符的设计(一个错误可能产生多个故障,静态存在)。
失效(failure):系统违背了它应有的行为。软件行为偏离预期(在系统交付前或交付后被发现,动态存在)。
A fault: occurs when a human makes a mistake, called an error, in performing some software activities (误解需求>与意图不符>其他故障)
A failure: is a departure from the system’s required behavior(交付前/交付后/测试/维护)

联系:人为原因导致程序错误;该错误编译到系统中导致系统故障;用户使用该系统时,因故障导致失效。故障是系统内部视图,从开发者的角度看待问题;失效是系统外部视图,从用户角度看到的问题。而且并不是所有的故障会导致失效,只要不执行故障代码,或者不进入某个特定状态,那么故障就不会使代码失效。

bug

零缺陷软件

由于市场压力促使软件开发人员快速交付产品,零故障无法实现。

关于 bug

改正(fixing)有时比重写(rewriting)整个系统要困难。
错误修正的越晚,付出的代价越大。
复审(review)十分重要,是正式团队的行为规范;自己检查能只能找出开发阶段故障的 1/5,同行评审能够揭示其余 4/5 的故障。

软件质量(quality of software)

  • The quality of the product 软件产品的质量
  • The quality of the process 过程的质量(CMM和ISO9000)
  • The quality of the product in the context of the business environment 商业环境下的质量

从三个方面考虑软件的质量:产品的质量、生产该产品的过程的质量以及在产品将使用的商业环境背景下的质量。

3.1 产品(product)的质量

用户:从失效的数目和类型等外部特性进行评价,如果软件具有足够的功能,并且易于学习和使用;或者虽然难以学习和使用,但是由于功能值得这些付出,用户就断定软件是高质量的。
开发者:从故障的数目和类型等内部特征来作为产品质量的依据。

3.2 过程(process)的质量

有很多过程都会影响到最终的产品质量,只要有活动出了差错,产品的质量就会受到影响;开发和维护过程的质量与产品的质量是同等重要的。
几个量化模型:CMM、ISO 9000、SPICE(了解)

3.3 商业(business)环境背景下的质量

(1) 技术价值与商业价值的联系与区别:
技术价值:技术指标(速度,正确的运行时间,维护成本等)。
商业价值:机构对软件是否与其战略利益相吻合的一种价值评估。误区:技术质量不会自动转化为商业价值。
(2) 目标
将技术价值和商业价值统一起来,改进过程所带来的商业价值。

IV 、Who does software engineering?!! 软件工程涉及的人员

客户(customer):为将要开发的软件系统支付费用的公司、组织或个人。

开发者(developer):为客户构建软件系统的公司、组织或个人。

用户(user):实际使用系统的人。

有时,他们可能是同一个人或同一组人。

Notes: 随着软件工程的发展,三者之间的界限越来越模糊了。客户介入研发,不断变更需求。 软件外包,开发人员也可以作为客户。

  1. sometimes the customer is not a user; 用户和客户有时是分离的;
  2. sometimes the customer, users, and developer belong to a same organization; 甚至有时三者都是同一实体下的;
  3. subcontractors(承包商) may included 有时可能包含第四方承包商。

参与者

V 、A system approach 系统方法

What is a system?

Hardware, software, interaction with people
装配在一起的硬件和软件,必须与用户、其他软件任务、其他部分的硬件、现有数据库、甚至其他计算机系统进行交互

软件系统的系统要素(组成)(对象(实体)+ 活动 + 关系 + 系统边界)

(1) 活动和对象

  • 活动(activity):活动是发生在系统中的某些事情,通常描述为由某个触发器引发的事件,活动通过改变某一特性把一个事物转变成另一个事物。
  • 对象(object)或实体(entity):活动中涉及的元素称为对象或实体(如记录数据的对象)。
  • 活动是发生在系统中的某些事情,实体是活动中涉及的要素

(2) 关系和系统边界

  • 关系(relationship):对实体和活动间数据项及动作相互关系的描述。
  • 系统边界(system boundary):用于描述系统中包含什么,不包含什么。

VI 、An engineering approach

构建一个系统 (buliding a system)

The construction process of a house
 确定和分析需求(房子的外观、户型、洗手间数量等)
 文档化房子的总体设计(documentation and abstraction)
 文档化房子的详细规格说明(documentation and detailed specification)
 设计房子的组成部分(design,设计图纸等)
 构建房子的每个部分(施工)
 测试房子的每部分(下水是否正常、照明是否正常、窗子是否正常)
 集成房子的各个部分,在搬进来之前做最后的修改(住户去检查、修改)
 由住户持续维护房子(维护)

What we learned from building a house

Remain flexible and allow changes in the original specifications at various points during construction
(保持灵活、允许更改)材料无法买到、看到雏形时新想法、最初的设计不可行
The house is built within the context of social, economic, and governmental structure(受社会经济影响、符合政府体系/政策要求)
Leave room for decisions based on experience, to deal with unexpected or nonstandard situations(为决策留有余地)建造部件的自然变形导致墙和地面不是正方形

现代软件工程包含的阶段:

*现代软件工程大致包含的几个阶段及各个阶段文档。*

1、需求分析

完成需求规格说明书(SRS Software Requirement Specification)。

2、系统设计

完成系统结构图(SAD software architecture diagrams and reports)。

3、程序设计

完成模块功能与数据描述文档。

4、软件开发

完成开发记录文档。

5、单元测试

按照程序设计中的要求进行测试,完成单元测试文档。

6、集成测试

按照SAD测试,完成集成测试文档。

7、系统测试

按照SRS进行测试,完成系统测试文档。

8、系统交付

提交系统说明文档。 用户手册、操作者手册 user manual and operator manual

9、维护

提交维护记录文档。

软件系统开发

VII 、Members of the development team

需求分析人员、设计人员、程序员、测试人员、培训人员、维护人员、资料管理人员、配置管理人员。

  • Requirement analysts 需求分析人员
  • Designers 设计人员,软件架构师。
    从需求分析中抽取出具体实现,设计出满足用户需求的架构。是经验与实际规则相结合的一部分,为最困难的一部分。
  • Programmers 程序开发者。
  • Testers 测试人员。
    开发出一些测试工具再去测试软件。
  • Trainers
    训练用户如何使用系统
  • Maintenance team 维护人员
    待命防止系统崩溃
  • Librarians 文档管理人员。
    使开发更加规范,说明当时是怎么想的。
  • Configuration management team 配置管理人员。
    不变的固化为程序,可变的抽象为配置项。

软件工程各阶段各自的工作:(了解)
需求设计(分析员、客户):将客户想要的分解为离散需求。
系统设计(分析员、设计员):生成系统层描述(系统要做什么)。
程序设计(设计员、程序员):实现指定需求的代码。
程序实现(程序员):编代码。
单元测试(程序员、测试员):发现各种错误。
集成测试(测试团队):检查系统功能。
系统测试(测试员、客户、培训员):根据《SRS》检查要求。
系统交付(培训员):培训用户。
系统维修(维修团队):寻找故障,根据客户需求变化,对系统作出修改。
资料管理(资料管理员):维持一个软件的不同版本之间各种文档的对应关系,包括需求规格说明、设计描述、程序文档、培训手册、测试数据进度等。
配置管理(配置管理员):维护需求、设计、实现和测试之间的对应关系。
软件架构师:属于高级程序员,侧重开发过程和模式的选择和论证(在国内和分析员差不多,其工作重点与分析员有所不同,但就开发来说,其工作似乎更重要些,而分析员的工作更偏重于市场与用户需求)。

VIII. 软件工程发生了多大的变化

使现代软件工程实践发生变化的七个关键因素(by Wasserman)

1.Time to market 软件交付市场的紧迫性
2.计算成本的下降
3.桌面计算机性能的提高
4.网络技术的发展
5.面向对象技术的发展
6.用户图形界面系统的普及
7.瀑布模型存在的问题

软件开发瀑布模型的不可预测性
说明(了解):瀑布模型沿袭了传统系统工程的大规模批发制造的理念,假定生产活动为线性,这与现代软件的生产方式相矛盾。不再是有足够的灵活性和适应性来满足并行开发或并行运行这样的商业软件需求,因此不可预测。
结论(了解):对一个系统进行划分,以便并行地开发其子系统,需要一个与瀑布模型有很大不同的开发模型。

软件工程的 Wasserman 规范

Abstractions (抽象)

  • A description of the problem at some level of generalization.基于某种概念层次上对问题的描述
  • 隐藏细节

Analysis and design methods and notations (分析、设计方法和符号描述系统)

  • A way to describe the problem and its solution at some level of abstraction.使用标准表示来对程序进行描述。利于交流,利于建模并检查其完整性和一致性,利于对需求和设计部件进行重用。

User interface prototyping (用户界面原型化)

  • prototyping:building a small version of a system.建立系统的小型版, 通常具有有限的关键功能,以利于用户评价和选择,证明设计或方法的可行性。

Software architecture (软件架构)

  • A way to describe the structure of a system in terms of separately specified components and their interrelationships.定义一组体系结构单元及其相互关系集来描述软件系统。

Software process (软件过程)

  • A process: a series of steps involving activities,constrains, and resources that produce an intended output of some kind 一组有序的任务称为过程,它涉及活动、约束和资源使用,用于产生某种想要的输出
    To form a common understanding 形成对软件开发中的活动、资源和约束的共同理解
    To find inconsistencies, redundancies,omissions 有助于开发团队发现过程及其组成部分中存在的不一致、冗余和遗漏。修改后,过程会变得更加有效
    To find and evaluate appropriate activities for reaching process goals 发现并评价达到过程目标的合适的活动,根据模型评估候选活动是否合适
    To tailor a general process for a particularsituation in which it will be used 根据具体情况对每一个过程进行修改

Reuse (软件复用)

  • A way to reuse software components from a library of components.重复采用以前开发的软件系统中具有共性的部件, 用到新的开发项目中去(不仅仅是源代码的重用)

Measurement (软件测度)

  • A way to assess the quality of software and to assess the effectiveness of the software process.通用的评价方法和体系,有助于使过程和产品的特定特性更加可见,包括量化描述系统、量化审核系统。

Tools and integrated environments (工具和集成环境)

  • A way to support the software process and to provide automated support for some activities.通过框架比较软件工程环境提供的服务,以决定其好坏。工具:由于厂商很少针对整个开发生命周期,因此对于工具的比较集中于小的活动集,例如测试或设计。

picadilty 广告投放的规则

Chapter 2 Modeling the Process and Life Cirle (建模过程和生命周期)

I. The meaning of process !!

定义:

过程(process):软件开发过程中产生某种期望结果的一系列有序任务,涉及活动、约束和资源。

重要性:

1、通用性:软件过程可以让一系列开发活动保持一致性和结构性,因而具有了通用性。

2、指导性:软件过程使我们可以分析、检查、理解、控制和改善软件开发活动。

3、可以把获得的经验传递给其他人。

软件过程模型(software process models)

  • 形成对软件开发中的活动、资源和约束的共同理解
  • 有助于开发团队发现过程中部分中存在的不一致、

软件开发过程

software

Requirement analysis and definition (需求分析和定义)
确定系统必须完成的工作、提出完整、准确、清晰、具体的要求(最重要的部分)

  • Problem definition(问题定义)
  • Feasibility research(可行性研究)
  • Requirement analysis(需求分析)
  • Software requirement specification (SRS)软件需求规格说明书  — logical architecture(系统逻辑结构),learn about boundary, entities, activities (what we will do) and objects (what we will use)(学习边界、实体、活动和对象)
  • Review(复审)by all anticipants (所有参与者的复审)

System design (系统设计)
提出总体设计 确定系统的具体实现方案
Program design (程序设计)
提出详细设计 确定系统中每一部分程序的具体实现
Writing the programs (编写程序)
构建每一个部分
Unit testing (单元测试)
对系统的每一部分进行分别测试
Integration testing (集成测试)
将单元组成到一起,测试模块之间的集成和调用关系
System testing (系统测试)
测试整个系统,包括功能、安全性等
System delivery (系统交付)
将产品部署到用户处
Maintenance (维护)
系统运行,维护。(发生时间最长的)

每个阶段本身就可以描述为一组活动的过程,每个活动包括约束、输出和资源 。例如需求分析,以用户表述的功能和特征作为输入,输出为需求,约束就是产生需求说明文档的预算和进度,需求的种类和表示方法。每个过程都可以用不同的方式加以描述,例如文本、图表等。

软件生命周期(software life cycle)

When a process involves building a software,the process may be referred to as software lifecycle.

涉及产品构建的过程称为生命周期,软件生命周期就描述了软件产品从概念到实现、交付、使用和维护的整个过程。不是面面俱到的,只是告诉你是按什么方向走,具体落地实现可以修改。

II. Software process models!!

软件开发模型
软件过程
软件过程模型

软件开发过程是脑海里的一种思想,在物理层面的落地就是软件过程模型。
模型反映了开发的目标。
早期就可以进行评估并明确约束。
都是将需求作为输入,将产品作为输出。

软件生存周期模型(software development models)

又称软件开发模型,是软件生命周期的一个框架,规定了软件开发、运作和维护等所需的过程、活动和任务。

Waterfall Model

描述:
从一个阶段瀑布般的转换到另一个阶段。
一个开发阶段必须在另一个阶段开始前完成。
是比较悠久的模型。
每个过程活动都有与其相关的里程碑(中间产出)和可交付产品,以便判断距离最后完成还有多远。(借助该思想设计的瀑布模型)
可以说是软件开发过程中的第一个基础模型。

瀑布模型的工作原理如下:

  • 从小到大收集用户需求;正确记录所有要求,以了解用户的产品要求。
  • 在用户要求之后,将列出系统要求以与系统配合使用。
  • 软件开发团队根据需要设计了产品。
  • 开发团队在绘制详细设计后开始产品的实际实现,其中包括系统、硬件、软件等。
  • 实施后,测试团队对整个产品进行全面测试。

优点:
以项目的阶段评审和文档控制为手段有效地对整个开发过程进行指导,从而保证了软件产品及时交付,并达到预期的质量要求。

适用于需求非常明确的产品。

瀑布模型存在的问题:

  • A variation of the waterfall model
  • Uses unit testing to verify procedural design
  • Uses integration testing to verify architectural (system) design 没有迭代
  • Uses acceptance testing to validate the requirements 需求不完善
  • If problems are found during verification and validation, the left side of the V can be re-executed before testing on the right side is re-enacted
    获得完善的需求规约是非常困难的;
    难以适应快速变化需求;
    系统太大时,难以一次做完;
    反馈信息慢;
    极可能引起开发后期的大量返工,如返工到需求、设计等早期活动;

2.2.3 瀑布模型的优化——原型化的瀑布模型
我们注意到瀑布模型将过程抽象为线性发展的,这种抽象给它带来了简单、明确和直观的优点,但同时也招致了许多问题。可是实际的开发中每个步骤并不是理想中的线性发展的的状态,比如在设计阶段了解到客户更新了需求,或者在设计阶段的疏漏直到测试时才被发现,以上的情况都需要返回之前的步骤进行修正才能解决。我们需要对瀑布模型进行优化,引入原型化以有助于控制活动之间的往返。

V Model

V模型是瀑布模型的一种变体,它使用单元测试来验证过程设计,使用集成测试来验证体系结构(系统)设计,使用验收测试来验证需求。如果在验证和验证过程中发现问题,则可以在重新执行右侧测试之前重新执行V的左侧。

描述:
明确的标注了测试过程中存在不同测试类型,明确的表示了开发阶段与测试各阶段的对应关系。
单元测试是否满足详细设计的要求。
集成测试验证之前已测试过的部分是否可以很好的结合在一起 。
系统测试检测系统功能,安全性等。
验收测试是由客户进行的,确定软件的实现是否满足用户需求。

优点: 使得隐藏在瀑布模型中的迭代和重做活动更加明确

缺点: 仅把测试作为编码的最后一个阶段,未在需求阶段就进行测试

原型化模型(prototyping model)

原型化模型是一种软件开发模型,它将软件开发过程分为四个阶段:需求收集、原型设计、原型开发和原型评估。在原型设计阶段,软件工程师和客户一起确定软件的基本要求。在原型开发阶段,软件工程师根据客户的要求开发原型。在原型评估阶段,客户评估原型并提出更改建议。

优点:
减少开发中的风险和不确定性 。
避免太晚开始迭代 。

缺点:
快速建立起来的系统结构加上连续的修改可能会导致产品质量低下。

原型化模型

Operational specification(可操作规格模型)

略 专业领域使用较多

阶段化开发:增量和迭代 (Phased development: increments and iteration)

 Incremental development: starts with small functionalsubsystem and adds functionality with each new release 小的子系统->不断增加功能
 Iterative development: starts with full system, then changes functionality of each subsystem with each new release 全系统->不断完善功能

优点:
从需求到系统交付的时间短 快速抢占市场 早些获得反馈,可以对产品进行修改。
缺点:
不断进行新老版本时,会有一些不稳定性。

螺旋模型(spiral model)

描述:
以需求和初始化开发计划(预算、约束、人员安排方案、设计和开发环境)为起点。
在产生操作概念(要做哪些事情,有什么资源等)文档之前,插入评估风险以及可选原型的步骤,以评估需求是否完整和一致。
第一轮迭代产生操作概念,第二轮是需求,后面依次是设计和测试。
每轮都进行风险分析,评估不同选择,通过原型验证可行性,并决定如何消除或降低风险。
一圈代表一次迭代 。

优点:
灵活性,可以在项目的各个阶段进行变更。
减少了过多测试或测试不足所带来的风险。
缺点:
对风险评估经验和专门知识的要求较高,在风险较大的项目开发中,如果未能够及时标注风险,势必造成重大损失 会增加开发成本,延迟提交时间。

敏捷模型(agile model)

四个原则 价值-敏捷宣言:
(1)个体和交互胜过过程和工具;
(2)可以工作的软件胜过面面俱到的文档;
(3)客户合作胜过合同谈判;
(4)响应变化胜过遵循计划。
四种方法:
(1)橄榄球法(Scrum)
(2)极限编程(XP)
(3)水晶法(Crystal)
(4)自适应软件开发(ASD)

四个特性 价值观:
沟通、反馈、简化、勇气

极限编程

极限编程是敏捷过程的一种具体形式,指把好的开发实践运用到极致,多应用于软件需求模糊的场合。提供敏捷方法最一般原则的指导方针。
强调敏捷方法的4个特性:交流、简单性、勇气以及反馈

特点:
测试成为开发的核心;
纪律性与灵活性巧妙结合.

XP关键做法:
计划博弈(Planning Game)
小型发布(Small Releases)
系统隐喻(System Metaphor)
简化设计(Simple Design)
集体拥有代码(Collective Code Ownership)
结对编程(Pair Programming)
测试驱动(Test-driven)
重构(Refactoring)
持续集成(Continuous integration)
每周40小时工作制(40-hour Weeks)
现场客户(On-site Customer)
代码规范(Coding Standards)

III. 过程建模的技术与工具

静态模型(static model)描述过程,表明了从输入到输出的转换过程。动态模型(dynamic model)能够动态展现过程,这样用户能够看到中间产品和最终产品是如何随着时间的推移进行转换的。

静态建模:Lai表示法

这是在一种范型的基础上建立的,在这种范型中:人扮演角色,资源执行活动,从而产生制品。这个过程模型表明了角色、活动和制品之间的相互关系。而状态表说明在给定的时间内,每个制品完成情况的信息。
过程包含以下7种类型的要素。

(1) 活动:过程中将要发生的事情。该要素可以与下面几项相关联:该活动前后发生的事情、所需的资源、使活动开始的触发器、支配活动的规则、如何描述算法以及得到的经验教训,以及如何将该活动与项目团队联系起来。

(2) 序列:活动的顺序。序列可用触发器进行描述,也可以用程序结构、转换、排序或满足的条件来描述。

(3) 过程模型:是关于系统兴趣的观点。因此,部分过程可以用单独的模型表示,或者用以预测过程行为,或者用以检查某些特性。

(4) 资源:必要的项、工具或人员。资源可以包括设备、时间、办公空间、人员、技术,等等。过程模型确定每个活动对于每一个资源所需的数量。

(5) 控制:施加于过程执行的外部影响。控制可以是手工的或自动的、人工的或机械的。

(6) 策略:指导原则。它是影响过程执行的高层的过程约束,可能包含一个规定的开发过程、必须使用的工具或强制性的管理模式。

(7) 组织:过程代理的层次化结构,使物理的分组与逻辑分组及相关角色相对应。从物理分组到逻辑分组的映射必须足够灵活以便反映物理环境的变化。

动态建模:系统动力学

过程模型的一个良好特性就是演示过程的能力,这样,随着活动的发生,我们就可以观察资源和产品发生了什么情况。换言之,我们想要描述这个过程的模型,并且在软件向我们展示资源流是如何通过活动成为输出的时候可以进行观察。这种动态过程的视图使我们能够模拟过程,并在实际消耗资源之前能够进行修改。

使用系统动力学方法的第一步是将实证性证据、研究报告和直觉这三者结合在一起来标识这些关系。下一步是量化这些关系,量化可以包含直接的关系。

Chapter 3 Planning and Managing The Project (计划和管理项目)

I. Tracking progress 项目跟踪

项目进度(Project Schedule)
项目进度是对特定项目的软件开发周期的刻画。包括对项目阶段、步骤、活动的分解,对各个离散活动的交互关系的描述,以及对各个活动完成时间及整个项目完成时间的初步估算。

活动
是项目的一部分,在一段时间内发生

里程碑
是活动的完成,就是每一个特定的时刻,向开发人员和客户指明项目已经进展到了可测量的级别

按照活动和里程碑的概念,可以把开发分为阶段,阶段包含步骤,步骤包含活动。
每个活动都是一个可测量事件,这样我们可以确定活动完成的客观标准。
任何一个活动的终止都可以是一个里程碑。

Work breakdown and activity graphs 工作分解和活动图

工作分解图(work breakdown structure)是一种层次化的任务清单,它将项目分解为若干个可管理的活动和任务。
可以用四个参数对每个活动进行定义:

  • Precursor 前驱:活动开始之前必须完成的一些事件
  • Duration 持续时间:完成活动所需的时间长度
  • Due date 截止日期:活动必须完成的日期
  • Endpoint 终点:表示活动已经结束,通常是一个里程碑或可交付产品。

Activity graph 活动图
可以画活动图来描述依赖关系,图中的结点是项目里程碑,连接结点的线表示包含的活动。
能否有效使用活动图,取决于对任务并行本质的理解。如果工作不能并行,那么就是一条直线,但活动图必须真实的描述并行性,因为人力有限,看似并行确被制约。
用虚线连接表示是一种没有伴随活动的关系。

估算完成时间

关键路径法(CPM - Critical Path Method) **重要考点

计算关键路径
详解关键路径法

  • Real time (actual time) 真实时间:完成活动所需要的时间
  • Available time 可用时间:完成活动可用的时间量
  • Critical path 关键路径:最长路径中每一个结点的时差都为零,所以决定了项目是否可以按期完成,被称为关键路径。

时差 Slack time for an activity
Slack time = available time - real time = latest start time - earlist start time
时差 = 可用时间 - 真实时间 = 最晚开始时间 - 最早开始时间

求关键路径:先求每个结点的最早开始时间,求出整个项目的最长花费时间。再用最长花费时间倒退,从最后一个结点开始,求每个结点的最晚开始时间。用最晚开始时间减去最短开始时间得到时间差,时间差为0的在关键路径上。

关键路径是项目中时间最长的活动顺序,决定着可能的项目最短工期。
计算关键路径的长度时,需要将路径上的所有活动的持续时间、提前量(负的)和滞后量(正的)加总在一起。
最长路径的总浮动时间最少,通常为零;进度网络图可能有多条关键路径。
长度仅次于关键路径的路径称为次关键路径,次关键路径也可能有多条。
借助进度计划软件来规划时,为了达成相关方的限制要求,可以自行定义用于确定关键路径的参数。
活动图

附有持续时间的活动图

II. Project personnel(项目人员)

Staff roles and characteristics 人员角色和特性

做同类工作的两个人至少可能在下面的某一方面不同:
完成工作的能力;对工作的需兴趣;开发类似应用的经验;使用类似工具或语言的经验;使用类似技术的经验;培训;与他人交流的能力;与他人共同承担责任的能力;管理技能。

Work styles 工作风格

Extroverts(外向型): tell their thoughts
Introverts(内向型): ask for suggestions
Intuitives(感性的): base decisions on feelings
Rationals(理性的): base decisions on facts,options
工作风格
1.决定交流方式
2.更加灵活,优先级别
Work styles determine communication styles
Understanding workstyles

  • help to be flexible
  • give information based on other's priorities

Project organization 项目组织

取决于:

  • 团队成员的背景和工作风格
  • 团队成员的数目
  • 客户和开发人员的管理风格

两种组织结构:
主程序员负责制小组(Chief programmer team):一个人负则系统的设计和开发,其它的小组成员向该主程序员汇报,主程序员对每一个决定有最终决策权。

忘我方法(Egoless approach): 每个成员平等的承担责任,而且过程与个人是分开的;批评是针对产品和结果的,不针对个人的。

III. Effort estimation(估算工作量)

专家判断 expert judgement

(x+4y+z)/6
一个悲观的预测(x),一个乐观的预测(y),一个最有可能的预测(z)

算法方法 Algorithmic methods

用方程的方式,工作量是因变量,其它因素是自变量,通常认为项目规模是影响最大的因素
E=( a + bSc ) m(X)
S是规模,abc是常量,X是影响成本因素的向量,m是因素的调整因子;可以看出主要是规模,其它是调整。
(反馈控制,对系统进行优化)

Walston and Felix model: E = 5.25 S 0.91
Bailey and Basili model: E = 5.5 + 0.73 S^1.16

基于代码行的工作量估算
基于代码行(SLOC)的工作量估算,是从开发者的技术角度出发来度量软件。代码行数是软件开发者最早进行规模测量的主要方法。进行工作量估算时,先采用WBS法、类比法等统计出软件项目的代码行数,然后将代码行数转换为人天数。其中,将代码行(SLOC)转换成人天数主要有2种方法。
(1)生产率方法:要求有开发商每人天开发的代码行数,估算出代码行数后,直接利用代码行数÷SLOC/人天,即得工作量人天数。
(2)参数模型法:利用模型,将代码行数转换成人天数。

常见的模型有:
Putnam模型
Putnam1978 年提出的一种动态多变量模型。估算工作量的公式是:K = L3/(Ck3*td^4)

其中:L 代表源代码行数(以行计),K代表整个开发过程所花费的工作量(以人年计),td 表示开发持续时间(以年计),Ck表示技术状态常数,它反映“妨碍开发进展的限制”,取值因开发环境而异。
COCOMOⅡ模型
COCOMOⅡ模型指出,软件开发工作量与软件规模呈指数关系,并且工作量受16个成本驱动因子的影响。COCOMO Ⅱ的计算步骤如下:
1)估算软件规模Size,这里以千代码行(KSLOC)计。
2)评估比例因子SF,求指数E。
3)求成本驱动因子值EMi。求标称进度工作量PM:

IBM模型
 IBM模型是1977年IBM公司的Walston和Felix提出的。其中估算工作量的公式如下:E=5.2×L^0.91 ,L是源代码行数(以千行计),E是工作量(以人月计)

机器学习方法 machine-learning methods

ML-based估算

分析过去项目数据,并用他们生产方程式以预测未来项目 这个过程可以采用机器学习的方法进行
采用过去项目的数据进行训练。为网络提供相关数据,识别数据的模式,使用正向和反向传播算法进行学习。

专家估算法的大致含义?算式估算法的大致含义?

专家估算法:

使用专家的知识和经验,对软件项目的工作量进行评估,是一种经验性的猜测。

一般使用三种方法:

1、类推法:

做出三种估计,乐观的、悲观的、最可能的估计,加权平均。

2、Delphi法:

几组专家预测,取平均值。

3、Wolverton法:

通过计算老问题(O),新问题(N)和容易的(E),适中的(M),困难的(H)这2x3的组合,形成矩阵进行估计。

算式估算法:

E = ( a + bSc ) m (X)

E为工作量,a,b,c都为常数,S是估算的系统规模,X 是一个从X1到Xn的n维度成本因素向量,m是基于该因素的调整因子。

IV. Risk management activities(风险管理)

什么是风险

风险是指在项目开发过程中,可能会发生的一些不期望发生的事件,这些事件可能会对项目的进度、成本、质量、资源等产生影响,甚至会导致项目失败。Risk is an unwanted event that has negative consequences.

概念:软件生产过程中不希望看到的,有负面结果的事件
方面:风险损失,风险概率(相乘为风险暴露(Risk Exposure),即数学期望)

与事件有关的损失
事件发生的可能性
能够改变结果的程度

风险量化

Quantify the effect of risks(量化风险的影响)
Risk exposure = (risk probability) x (risk impact)

Cost of reducing risk(降低风险的成本)
Risk leverage = (risk exposure before reduction – (risk exposure after reduction) / (cost of risk reduction)

风险类型
  • 一般风险
  • 特定项目风险

Personnel shortfalls
Unrealistic schedules and budgets
Developing the wrong functions
Developing the wrong user interfaces
Gold-plating
Continuing stream of requirements changes
Shortfalls in externally-performed tasks
Shortfalls in externally-furnished components
Real-time performance shortfalls
Straining computer science capabilities

Steps in risk management 风险管理

如何管理:评估+控制

评价项目的风险,以便了解在开发或维护的过程中可能发生什么。

风险评估:风险识别(checklist),风险分析,风险优先级分配

再进行风险控制,控制的理念认为,我们不可能去除所有风险,而是可以通过采取行动以一种可接受的方式处理有害的结果,从而将风险降到最低。

风险控制:风险降低,风险管理计划,风险化解

降低风险的策略:

1、避免风险:改变功能和性能需求,使风险没机会发生。

2、转移风险:通过把风险分配到其他系统中,或者购买保险以便在风险成为事实时弥补经济上的损失。

3、假设风险:用项目资源,接受并控制风险。比如在开发时主动有意识地进行测试。

项目计划

目标
进度
标准
资源
质量保证

过程模型和项目管理

Enrollment Management Model: Digital Alpha AXP
注册管理模型:

  • 宏大的目标
  • 完全信任
  • 反复交流意见
  • 认可每一次进步,随着规划不断学习

F-16 Project
责任模型:
集成产品开发

Boehm指出的所有开发过程共有的三个里程碑:

1.Life cycle objectives

  •  Objectives: Why is the system being developed?
  •  Milestones and schedules: What will be done by when?
  •  Responsibilities: Who is responsible for a function?
  •  Approach: How will the job be done, technically and managerially?
  •  Resources: How much of each resource is needed?
  •  Feasibility: Can this be done, and is there a good business reason for doing it?
  1. Life-cycle architecture: define the system and software
    architectures and address architectural choices and risks
  2. Initial operational capability: readiness of software,
    deployment site, user training

Chapter 4 Capturing the Requirements(需求获取)

软件工程概论(四) 获取需求_软件工程获取需求的方法_Mirevas的博客-CSDN博客

I. 需求过程

定义

A requirement is an expression of desired behaviour.(需求是对期望行为的表达)

过程
需求引发->需求分析-> 规格说明-> 验证 ->需求规格说明书SRS

1、需求就是对期望的行为的表达。需求处理的是对象或者实体(输出),他们可能处于的状态(输出形式),以及用于改变状态或对象特性的功能(产生输出或修改形式)。

2、标记关键实体,限定实体,定义实体间的关系。

3、特定于实现的描述不是需求,除非是客户说的。需求就是确定客户的问题和需要,而不是解决方案。首先,抽象为现实世界中现象之间的交互,就能抓住客户需求的核心内容,易用客户熟悉的方式陈述。

4、是否敏捷,需求分析起很大作用。需求复杂时,就重点分析;需求不定,就敏捷开发。极限编程里需求是测试用例,但用例不等于客户真正的需求。

需求规格说明书

II. 需求引发

需求引发是过程中极为关键的一部分,我们必须用各种技术来确定用户和客户到第要什么。

谁是风险承担者 (Stakeholders)?
 Clients: pay for the software to be developed
 Customers: buy the software after it is developed
 Users: use the system
 Domain experts: familiar with the problem that the software
must automate
 Market Researchers: conduct surveys to determine future
trends and potential customers
 Lawyers or auditors: familiar with government, safety, or
legal requirements
 Software engineers or other technology experts

委托人:有最终话语权,为开发支付费用的人
客户:在软件开发之后购买软件的人。
用户:最终使用系统的人,了解实际需求以及特殊需求
领域专家:软件内容所涉及领域的专家
市场研究人员:进行调查,确定将来趋势以及潜在客户需要的那些人
律师或审计人员:对政府、安全性以及法律需求熟悉的那些人
软件工程师或其它技术人员:技术评估

需求引发的手段:

与风险承担者进行会谈
评审可用文档
观察当前系统(如果存在),收集关于用户如何执行任务的客观信息。
做用户的学徒,在用户执行任务时,更详细的学习。
使用特定领域策略
就如何改进将要构建的产品,与当前潜在用户一起讨论

III. 需求类型 Types of Requirements

功能需求 Functional requirement:

根据要求的活动(如对输入的反应、活动发生时每一个实体之前的状态和之后的状态)来描述需要的行为。
功能需求定义问题解决方案空间的边界。解决方案空间是使得软件满足需求的设计方式的集合。最初,该集合可能会很大,但是,实践中就一个软件产品而言,仅仅是计算正确的输出是不够的,还有其它类型的需求,将可接受的产品和不可接受的产品区分开来。

非功能性需求 Quality requirement or non-functional requirement:

质量需求或非功能需求,描述一些软件解决方案必须拥有的质量特性,如快速的响应时间、易使用性、高可靠性或低维护代价。

设计约束 Design constraint:

设计约束是已经作出的设计决策或限制问题解决方案集的设计决策,如平台或构件接口的选择。

过程约束 Process constraint:

过程约束是对用于构建系统的技术和资源的限制。例如,客户可能坚持使用敏捷方法,以便在继续增加新特征时能够使用早期版本。

IV. Characteristics of Requirements

Correct 正确性
Consistent 一致性
Unambigious 无二义性
Complete 完备性
Feasible 可行性
Relevant 相关性
Testable 可测试性
Traceable 可跟踪性

V. 建模表示 Modeling Notations

软件工程原理的一个显著特性是,它具有用于开发安全的、成功的产品的可重复过程。

第二个显著特征是,存在用于建模、文档化和交流决策的标准表示法。

UML (Unified Modeling Language)

UML通俗解释:UML类图总结

统一建模语言是用于文档化软件规格说明和设计的一组方法。

由于UML最初是用于开发面向对象系统的,应而UML根据对象和方法表示系统。对象类似于实体,按照具有继承层次的类进行组织。每一个对象提供方法,在对象的变量上执行动作。在对象执行的过程中,他们发送消息来调用其它对象的方法、确认动作、传送数据。

Eight graphical modeling notations, and the OCL constrain language, including
Use-case diagram (a high-level DFD)
Class diagram (an ER diagram)
Sequence diagram (an event trace)
Collaboration diagram (an event trace)
Statechart diagram (a state-machine model)
OCL properties (logic)

4.5.1 Entity-relationship diagrams (实体-联系图——UML类图)

Definition

是一种表示概念模型的图形表示法范型,主要描述对象、实体,以及实体之间的关系。是大多数面向对象需求和设计表示法的基础。

Three elements

实体 (An entity): 表示为矩形,代表具有共同性质和行为的现实世界对象构成的集合(有时称为类)
联系 (A relationship): 表示为两个实体之间的边,边的中间有一个菱形,说明联系的类型。
属性 (An attribute): 是实体上的注释,描述实体相关的数据或性质。

在所有UML规格说明中,类图是旗舰模型。
类图虽然被普遍认为是设计表示法,但用于表示概念也是可以的。
概念模型中的类,可以是一个程序类,也可以不是,因为本质上是为了表示现实世界中的实体。
一般来说实体包括,参与者(如主顾、操作员、人员),要存储、分析、转换或显示的复杂数据,瞬时时间的记录等(业务事物、电话交谈)等

  • 每一个方框代表一个类
  • class-scope attribute(类范围属性)
  • class-scope operation(类范围操作)

4.5.3 Event traces(事件踪迹——时序图)

Definition

事件踪迹是关于现实世界实体之间交换的事件序列的图形描述。每一条竖线表示不同实体的时间线,其名字出现在线的顶部。每一条水平线表示两个实体之间的一个事件或交互,通常理解为一个实体到另一个实体的消息传递。时间按从顶向下进展。
每一个图描述一个踪迹,表示的只是若干可能行为中的一个。

Properties/application

事件追踪广泛用于开发人员和客户中,因为除了计时问题,事件追踪的语义相对精确且易于理解。其简单性多数是因为它将需求描述分为场景,将每一个场景分别考虑(建模、阅读、理解)为不同的踪迹。
由于这些特性,事件踪迹对于文档化系统的行为并不是非常有效。
事件踪迹最好用在项目的开始,以对关键需求达成共识,并帮助开发人员识别正在建模的问题中的重要实体。

UML sequence diagrams

消息时序图是扩充的事件踪迹表示法。具有创建和撤销实体、指定动作和计时器,以及组合事件踪迹的能力。

4.5.5 State machines(状态机——状态图、Pertinent)

Definition

状态机表示法用于在单个模型中表示一组事件踪迹。状态机是一种图形描述,描述了系统与其环境之间的所有对话。

Two elements

每一个节点称为状态,表示存在于事件发生之间的一个稳定的条件集合。
每一个边称为转移,表示由于一个事件的发生而产生的行为或条件的变化。

每一个转移都标记有触发事件,还可能有输出事件,前面用符号‘/’表示,输出事件是转移发生时产生的。

一条通过状态机的路径,起始于状态机的初始状态,沿着状态到状态的转移,表示了环境中的一条可观察事件的踪迹。如果状态机是确定的(即对每一个状态和事件都有唯一的响应),那么,通过该状态机的一条路径表示将要发生的事件踪迹,给出触发路径转移的输入事件序列。

Properties/application

在表示动态行为方面,以及在描述在响应已经发生的历史事件时行为将如何变化方面,状态机都是很有用的。
特别适合的建模模型是:
随着系统的执行过程,对于同样的输入,系统响应是如何变化的。
对每一个状态,从那个状态发出的转移集指明可能触发一个响应的事件集及对事件集的相应响应。

UML statechart diagrams

UML状态机图同活动图一样,是动态视图的一种。

UML状态机图描述的是某个对象的状态和感兴趣的事件,以及对象响应该事件的行为。它描述的是“某个对象”,因此,一个状态机图中只能表示一个对象,而不是多个对象。状态图显示了该对象的生命周期,也即,对象经历的事件,对象的转换和对象在这些事件之间的状态。

4.5.8 Data-flow diagrams(DFD)(数据流图——用例图)

Definition

数据流图建模:功能以及从一个功能到另一个功能的数据流。

Four elements

椭圆表示一个加工或功能,它转换数据。
箭头表示数据流,其中,进入椭圆的箭头表示其功能的输入,从椭圆输出的箭头表示其功能的输出。
持久性数据保存在数据存储中,它是一个正式的库或信息库,表示为两个平行线。
数据源或者数据接收器表示为矩形,称为参与者,提供输入数据或接受输出结果的实体。

4.5.10 Functions and relations (函数和关系——判定表)

Definition

一些形式化范型将需求或软件行为建模为一组数学函数或关系,当组合在一起时,将系统输入映射到系统输出。一些函数说明系统的执行状态,而其它一些函数说明输出。当一个输入值映射到多个输出值时,就使用关系,不使用函数。

每一个输入都有输出 -> 完备性

Decision table

判定表是函数规格说明的表格表示,将事件和条件映射到适当的反应或动作上。该规格说明是非形式化的,因为输入(事件和条件)和输出(动作)可以用自然语言表示,也可以用数学表达式表示,或者同时使用两者。

优点:
容易检查,看看是否满足条件,是否完备,是否有冲突,以及明确条件与动作的关联之处。

4.5.13 Logic (逻辑 ——OCL)

Defintion

逻辑(logic)由一种表述性质的语言加上一组推理规则组成。

一阶逻辑:

包含类型变量、常量、函数、关系、谓词(>,<)等等。

num_coins >= num_entries

时态逻辑

4.5.16 代数规格说明

VI. 需求和规格说明语言

UML

用例图、类图、序列图、合作图、状态图

SDL

用于精确说明通过无线的消息队列通信的实时、并发、分布处理的行为。

VII. Prototyping requirements(原型化)

大部分人发现,详细地评论一个现有的产品比详细想象一个新的产品要容易得多。同样,能够引发细节的一种方式是构建被提议系统的原型,并请求潜在用户反馈。他们希望看到哪些方面被改进,哪些特征不那么有用,遗漏了哪些功能。构建原型还有助于确定客户的问题是否有一个可行的解决方案,或者帮助我们探讨优化质量需求的可选方案。

Rapid prototyping

Throwaway prototyping

抛弃型原型是为了对问题或者提议的解决方案有更多了解而开发的软件,永远不会作为交付软件的一部分。
允许我们去编写“快速但不考虑质量的软件”,但是能够迅速抓住我们面临的问题的核心。

Evolutionary prototyping

演化型原型不仅帮助我们回答问题,而且还要演变为最终产品。这类软件在开发必须展现最终产品的质量需求(如响应速度、模块化),并且这些质量的要求不能改进。

Prototyping vs. modeling
探索关于需求的问题有两种方式,建模或者原型化。哪一种方法更好,取决于我们的问题是什么。

用原型更容易回答关于用户界面的问题。原型实现了一些提议的特征,将更有效的帮助用户对这些特征的进行优先级划分,并可能识别出一些不必要的特征。

关于事件将要发生的顺序这样的约束问题,或者关于活动同步这样的问题,使用模型能够更快速的得到答案。

最终都要给出需求文档,二者之间哪种更好,取决于哪种能更好地帮助后续的软件开发。

VIII. 需求文档

需求定义

范围、背景、环境、核心功能、假设

需求规格说明(开发者角度)

IEEE标准
  • 文档介绍
  • 总体描述
  • 具体需求
  • 附录

IX. 确认和验证

确认

正确地构建系统

验证

构建了正确的系统

X. 度量需求

度量通常集中在三个领域:产品、过程和资源

对每一个需求评分:(1-5分)

  • 1分表示开发人员完全理解该需求
  • 5分表示完全不理解需求,不能根据它开发出设计。

其他指标:......

Chapter 5 (设计体系结构)

I. The Design Process

Defintion
设计是一种创造性的过程,它考虑如何实现所有的客户需求。设计所产生的计划也称为设计。

早期的设计决策专注于系统的体系结构(system’s architecture),用以解释如何将系统分解为单元以及这些单元又如何相互关联,还描述这些单元的所有外部可见特征。
后期的设计决策专注于如何实现单个单元。

软件体系结构

*IEEE610. 12—1990:体系结构是以构件、构件之间的关系、构件与环境之间的关系为内容的某一系统的基本组织以及指导上述内容设计与演化的原理,即软件体系结构={构件,连接件,环境,原理}

*Bass的定义:系统的一个或多个结构,包括软件构件、构件的外部可视属性和构件之间的关系

*国内普遍认可的看法:可以将体系结构定义为构件、连接件和约束。软件体系结构指可预制和可重构的软件框架结构。
体系结构(Architecture)=构件(Components)+连接件(Connectors)+约束(Constraints)

设计是一种创造性的过程

设计是一种具有智力挑战性的任务 Design is an intellectually challenging task
要搞清楚软件系统可能遇到的所有情况,包括系统必须能够适应的异常情况。

Nonfunctional design goals (e.g., ease of use, ease to maintain) 非目标功能
 不仅限制了可接受的解决方案的集合,而且可能实际上相互冲突
 使软件系统可靠和可复用的技术,代价高昂

External factors (e.g., standard data formats, government regulations) 外部任务
 软件必须符合已有硬件接口的规格说明,与遗留软件继续合作

系统还要具有要完成的非目标功能,例如易于维护、易于拓展、易于使用以及可移植性等。
外部任务可能使设计任务更加复杂,例如,软件可能必须符合已有的硬件的接口的规格说明,与遗留软件合作,或者符合标准数据格式或政府规章制度。

通过学习优秀的设计例子,我们可以改进我们的设计技巧

Most design work is routine design(常规设计), solve problem by reusing and adapting solutions from similar problems.
大部分设计工作是例程设计,针对一个问题,我们可以通过对其相似问题的解决方案进行复用和调整来予以解决。
有效利用现有解决方案的方法很多。

Cloning: Borrow design/code in its entirety, with minor adjustments
一个比较极端的方法是克隆,克隆已有的系统并进行定制,借鉴现有的整个设计,甚至包括它的代码,对它做少许的调整来解决特定问题,以满足新客户的要求

Reference models: Generic architecture(一般性的体系架构)
一个略为中庸的方法是基于一个参考模型来进行设计,它是一种用于特定的领域中标准的、一般性的体系结构。参考模型仅仅给我们提供建议,指导我们如何把系统分解为主要的构件以及这些构件之间是如何交互的。

Architectural styles(体系结构风格)
更一般性的解决方案称为体系结构风格。体系结构风格指导我们如何把问题分解为软件单元以及这些单元彼此应当如何交互。和参考模型不同的是,体系结构风格不是为特定领域进行的某种优化,而是关于如何完成一般性设计所给予的建议。

用于理解决策以及评估选择的体系结构的工具

Design patterns(设计模式):设计模式是一种针对单个软件模块或少量模块而给出的一般性解决方案,它提供相对较低层次的设计决策。
Design convention or idiom(设计公约): 设计公约是一系列设计决策和建议的集合,采用这些设计决策和建议,能够提高系统某方面的设计质量。
Innovative design(创新性设计):创新设计过程是被我们头脑中闪现的灵感所推进的,这种无规律的突发式进展正是创新设计过程的特征。
Design principles(设计原则): 设计原则描述的是一些良好设计的特征,而不是如何进行设计的说明性建议。

设计过程模型

1、建模:尝试可能的分解,根据需求描述的系统的关键特性等确定软件体系结构。

2、分析:分析初步的体系结构,主要关注系统级别的决策,如软件的质量、性能等。

3、文档化:确定各个不同的模型视图。

4、复审:检查文档是否满足了所有需求。

5、最终产出:软件体系结构文档,即SAD。用来和开发团队中其他人员交流系统级别设计决策的有力工具。

II.Modeling Architectures

III. Decomposition and Views

功能/特征/数据/过程/事件/面向对象

High level - Low level自顶向下!
1、Modular decomposition/Functional decomposition

这种方法是把功能或需求分解为模块。设计人员首先从需求规格说明书中所列出的功能开始,这些功能是系统级别的,它会随着系统环境改变输入和输出。更低层次的设计将这些功能分解成子功能,随后被指派给更小的模块,该级别的设计也会描述模块(子功能)间互相调用的情形。

2、Data-oriented decomposition

这种方法关注的是如何将数据分解成模块。该方法中的高层设计描述了概念上的数据结构,而低层设计提供了它们的细节,包括数据如何在模块中分配,以及分配好的数据如何实现概念上的模型。

3、 Event-oriented decomposition

这种方法关注系统必须处理的事件,并将事件的责任分配给不同模块。高层设计将系统预期的输入事件编成目录,而低层设计将系统分解为状态,并描述事件是如何触发状态转移的。

4、Outside-in design

由外而内的设计,基于系统的用户输入,即系统如何处理每一个输入及产生什么样的输出。

5、Object-oriented design

这种方法将对象分配给模块。该方法中,高层设计定义了系统对象的类型,解释了对象之间是如何关联的。低层设计细化了对象的属性和操作。

模块化

Modules/ computers
只有当系统的每个活动都仅由对应的软件单元实现,并且每个软件单元的输入和输出都已经明确的被定义时,才可以称这个设计是模块化的。
一个定义明确的软件单元的接口必须能够准确无误的指定该单元的外部可见行为:每个指定的输入对于单元的功能来说都很重要,且一个指定的输出很可能就是这个单元动作的结果

体系结构视图:

 Decomposition view
 Dependencies view
 Generalization view
 Execution view
 Implementation view
 Deployment view
 Work-assignment view

IV. Architectural styles and strategies

软件体系结构风格是已建立的、大规模的系统结构模式。惯用范例 通用的组织结构

体系结构风格关注的是构件间各种不同的通信、同步或共享数据的方式。就这一点而言,体系结构风格将构件间限定的交互系统化,为实现这些交互提供了必要的机制。

本节主要介绍软件开发中常用的6种体系结构风格:

  • 管道和过滤器
  • 客户-服务器
  • 对等网络
  • 发布-订阅
  • 信息库
  • 分层

1、Pipes and filters 管道和过滤器

将数据输入到称作过滤器的数据转换构件中得到输出数据;管道是简单的将数据从一个过滤器传递到下一个过滤器的连接器,它不对数据做任何改变。
管道过滤器结构将数据流处理分为几个顺序的步骤来实现,一个步骤的输出是另一个步骤的输入,每个步骤由一个过滤器实现。每个过滤器是独立的,它不需要知道系统中其它过滤器的存在或功能。

A simple example

DOS的管道指令,用“|”(竖线)将命令隔开,“|”竖线前的命令的输出作为竖线后命令的输入。

优点:

允许将系统的输入和输出看作是各个过滤器行为的简单组合,独立的过滤器能够减少构件之间的耦合度。
各个过滤器相互独立,因此很容易子啊系统中添加新的过滤器或去除旧的过滤器。
当输入输出数据具有相同的格式时,可以很容易地将管道和过滤器风格的程序复用到其它系统中。

2、 C/S客户-服务器

在客户-服务器风格的体系结构中,设计被分为两种构件,客户和服务器。服务器提供服务,客户提供请求/应答协议(request/reply request)访问服务。
这些构件都是现时运行且分布在若干台机子上的,可能包括一台中心服务器和几台分布在若干机器上的提供相同或不同服务的服务器。
在该体系中客户和服务器间的关系是不对称的,客户知道他们向哪台服务器请求服务,而服务器不知道他们正在为哪个客户提供服务,甚至不知道正在为多少个客户提供服务。
客户通过发送一个请求来作为通信的开始,比如发送一个消息或者发起一次远程调用,然后,服务器作出响应执行该请求,并且把结果回复给客户。
正常来说,服务器都是简单的对客户请求被动作出反应的构件,但是在某些情况下,服务器也会代表客户发起一系列动作,比如客户向服务器发送了一个可执行函数,称作回调,随后在特定情况下服务器调用这些回调函数。

3、P2P(Peer to Peer对等网络)

在对等网络体系结构中,每一个构件都只执行它自己的进程,并且对于其它同级构件,每个构件本身即是客户端又是服务器。每一个构件都有一个接口,该接口不仅指定了该构件所提供的服务,而且指定了它向其它同级构件所请求的服务。端与端之间通过彼此发送请求的方式来实现通信。
P2P适用于文件是静态的时候、文件内容和性质并不是非常关键的时候,或共享速度和可靠性不是很重要的时候。对于文件内容经常变化、共享速度和文件质量有着重要影响,或者如果一个端必须信任另一个端,更适合中央服务器的体系结构。

示例:文件共享网络

4、Publish-subscribe 发布-订阅

在发布-订阅的体系结构中,构件之间通过对事件的广播和反应实现交互。如果一个构件对某个事件感兴趣则可订阅该事件,一旦该事件发生了,另一个构件则进行发布来通知订阅者。发布-订阅所隐含的基础结构将负则注册订阅事件以及向合适的构件传达发布的内容。
隐含调用(implicit invocation)就是一种常见的发布-订阅体系结构,订阅者将自己的某个过程与感兴趣的事件建立关联(称注册该过程)。在这种情况下,当事件发生时,发布-订阅的基础结构就调用该事件的所有注册过程。
和客户-服务器以及P2P的构件相比,发布-订阅构件对于其它构件的存在一无所知,相反,发布者只是简单的宣布事件,然后等待反应;订阅者只是简单的对事件通知作出反应,而不管事件时如何发布的。在这种体系结构中,隐含的基础结构通常表现为连接所有发布-订阅构件的事件总线。

5、Repositories 信息库

信息库风格的体系结构由两类构件组成,中心数据存储以及与其相关联的访问构件。共享数据存放于数据存储中,而顺序存储器是一个计算单元,它负则存储、检索以及更新信息。
在黑板类型的信息库系统中,访问数据的构件却是被动的,他们的执行是对当前数据存储器的内容作出反应。典序情况下,黑板包含了当前系统的执行状态,该状态可以触发各独立的数据存储器执行过程,我们将这种数据存储器称为知识源。
这种体系结构一个很重要的特性就是对于系统关键数据的中心式管理。在数据存储中,可以将一些职责本地化,比如,存储固定数据、管理当前的数据访问情况、保障安全和隐私,以及保护数据。也要考虑一个重要的设计决策。是否要将数据映射到多个数据存储中。虽然分布或复制数据可能会提高系统的性能,但是往往也要付出代价,如系统复杂度增加、数据存储器固定化以及安全性降低。

6、Layering 分层

分层系统将系统的软件单元按层次化组织,每一层为它的上层提供服务,同时又作为下层的客户。
在一个纯粹分层系统中,各层中的软件单元只能访问同层中的其它单元和相邻低层的接口所提供的服务。但是为了提高性能,在一些情况下这些条件也可能会宽松,可以允许一个给定层访问所有低层的服务,这称为层次桥接。

示例:ISO/OSI 网络模型

V. Achieving Quality Attributes (QA质量保证)

1、Modifiability 可修改性

可修改性是大部分体系风格的基础

Two classifications of affected software units:
 Directly affected
 Indirectly affected
Directly affected units’ responsibilities change to accommodate a system modification
Indirectly affected units’ responsibilities do not change, but implementations must be revised

提高内聚度、通用性

降低耦合

2、Performance 性能

策略:

增加计算资源

提高资源利用率

有效地管理资源分配

降低对资源的需求

3、安全性

提高免疫力

高弹性

4、reliable 可靠性

主动故障检测

被动

异常处理

5、鲁棒性/健壮性

互相怀疑策略

6、usability 可用性

支持用户自定义命令

7、商业目标

VII. 体系结构的评估和改进

1、度量设计质量

2、故障树分析

3、安全性分析

4、权衡分析

5、成本效益分析

6、原型化

VIII. 文档化软件体系结构

SAD:

系统概述、视图、软件单元、分析数据和结果、设计合理性、定义、术语、编写词

IX. 体系结构设计评审

确认和验证

Chapter 6 Designing the Modules

I. Design Methodology

We will learn how to design the details of each software unit 在掌握了需求、设计了体系结构、对结构/功能进行分解之后,我们需要对每个软件单元进行具体设计

方法:自顶向下、自底向上、由外到内

Refactoring 重构:周期性地重审和修改设计决策

II. Design Principles

面向对象设计的六个基本原则 six dominant principles:
 Modularity 模块化
 Interfaces 接口
 Information hiding 信息隐藏
 Incremental development 增量式开发
 Abstraction 抽象
 Generality 通用性

1、Modularity 模块化

模块化,也称关注点分离,是一种把系统中各不相关的部分进行分离的原则,以便于各部分能够独立研究。
关注点可以是功能、数据、特征、任务、性质或想要定义或详细理解的需求以及设计的任何部分。
如果该原则应用得当。每个模块都有自己唯一的目的,并且相对独立于其它模块。每个模块的理解和开发将会更简单。模块独立也使得故障的定位和系统的修改更加简单。

易理解和开发 易定位缺陷 易更改/维护

To determine how well a design separates concerns, we use two concepts that measure module independence (模块独立程度): coupling
and cohesion 耦合度和内聚度
高内聚与低耦合是每个软件开发者追求的目标

Coupling 耦合 (缺案例说明)

1、content coupling 内容耦合
耦合度最高,一个模块实际上修改了另一个模块

2、 common coupling 公共耦合
通过对设计进行组织,使其从公共数据存储区来访问数据,但是依赖关系依然存在,因为对公共数据的改变意味着要通过反向追踪所有访问过该数据的模块来评估该改变的影响。

3、 control coupling 控制耦合
当某个模块通过传递参数或返回代码来控制另一个模块的活动时,就称这两个模块是控制耦合。
优点:每个模块只完成一个功能或进程,模块间传递的控制信息减到最少,接口也简化成固定的、可识别的参数和返回值集合。

4、stamp coupling 标记耦合
如果使用一个复杂的数据结构来从一个模块到另一个模块传递信息,并且传递的是该数据结构本身,那么两个模块之间就是标记耦合。(数据格式和组织方式必须匹配)

5、data coupling 数据耦合
如果传送的只是数据值,不是结构数据,那么模块之间就是通过数据耦合。

6、非直接耦合
最理想的耦合

Cohesion 内聚

内聚度指的是模块的内部元素,如数据、功能、内部模块等的“粘合”程度

1、coincidental 巧合内聚
内聚度最低的是巧合内聚,只是由于方便或偶然的原因,不相关的功能、进程或数据处于同一个模块中。

2、 logical 逻辑内聚
当一个模块中的各个部分只通过代码的逻辑结构相关联时,称这个模块具有逻辑内聚。
根据接收的不同参数执行不同的操作。尽管这些不同的操作体现了一定的内聚他们之间会共享一些程序状态和代码结构,但这种代码结构的内聚相对于数据、功能或目标的内聚是比较弱的。引入新操作时,就比较难以理解和维护。

例子:计算还款计划表的接口。LendApply 是借款申请;CalculateParam 是计算所需金额参数;CalcuateM
ethod 是计息方式——如等额本金、等额本息、先息后本。这个接口一直运行得很好,直到有一天业务要求
停用等额本金方式,统一采用等额本息方式计算还款计划表。这时候我们只有两种选择:1)让所有的调用方
排查一遍自己调用这个接口时传入的参数,保证入参 calculateMethod 只传入了等额本息方式;2)在接口内
部做一个转换:调用方传入了等额本金方式,那么按等额本息方式处理。显然,第一种方式会把原本很小的
一个需求变化扩散到整个系统群中。第二种方式则容易让调用方产生误解——明明指定了等额本金方式,为
什么计算结果是等额本息的?这就好比点了一份虾滑上菜却给上了一份黄瓜一样。这就是逻辑内聚的问题:
它把接口内部的逻辑处理暴露到了接口之外。这样,当暴露出去的这部分逻辑发生变更时,原本无辜的调用
方就要受到牵连了

3、 temporal 时态内聚
设计被划分为几个用来表示不同执行状态的模块,初始化、读进输入、计算、打印输出和清除,这样的内聚是时态内聚。
在这种模块中数据和功能仅仅因为在一个任务中同时被使用而形成联系。这样的设计会造成代码重复,因为多个模块对关键数据结构的操作都比较类似。

4、 procedural 过程内聚
通常,必须按照某个确定的顺序执行一系列功能,如果模块中的功能组合在一起只是为了确保这个顺序,那么该模块就是过程内聚。
同时态内聚相比,有一个优点,其功能总是涉及相关的活动和相关的目标。
这样一种内聚只会出现在模块本身运用的上下文环境中,如果不知道模块的上下文环境,则很难理解为什么这么工作,也很难修改。

5、communicational 通信内聚
将某些功能关联起来,因为他们是操作或生成一个数据集的,围绕数据集构造的模块是通信内聚

6、functional 功能内聚
理想的情况是功能内聚,满足两个条件。在一个模块中包含了所有必需的元素,并且每一个处理元素对于执行单个功能来说都是必需的。某个功能内聚的模块不仅执行设计的功能,而且只执行该功能,不执行其它任何功能。

7、informational 信息内聚
在功能内聚的基础上,将其调整为数据抽象化和基于对象的设计,就是信息内聚。

2、Interfaces 接口

接口为系统其余部分定义了该软件单元提供的服务,以及如何获取这些服务。

接口是这样一种设计结构,它对开发人员封装和隐藏了软件单元的设计和实现细节。
软件接口单元的规格说明描述了软件单元外部可见的性质。接口规格说明的描述只涉及软件单元边界的实体,该单元的访问函数、参数、返回值和异常。一个接口的规格说明需要向其它系统开发人员传达正确应用该单元的所有信息,这些信息不应该局限于单元的访问函数和它的签名,还应包括以下几点:
1、目标:为每个访问函数的功能建立充分详细的文档,以帮助其它开发人员找出最符合他们需求的函数
2、前置条件:列出所有假设,以帮助开发人员了解在何种情况下该单元才能正常工作
3、协议:包括访问函数的调用顺序、两个构件交换消息的模式。比如,一个调用模块访问共享资源之前需要被授权允许。
4、后置条件:将可见的影响称为后置条件。为每个访问函数的后置条件编写文档,包括返回值、引发的异常以及公共变量的变化,这样,调用它的代码才能对函数的输出作出适当的反应。
5、质量属性:这里描述的质量属性(如性能、可靠性)是对开发人员和用户可见的。只有可见才能评价是否起作用。

3、Information hiding 信息隐藏

设计决策隐藏在设计中,但不提供接口。

信息隐藏的目标是使得软件系统更加易于维护。它以系统分解为特征。每个软件单元都封装了一个将来可以改变的独立的设计决策,然后我们根据外部可见的性质,在接口和接口规格说明的帮助下描述了各个软件单元。
信息隐藏的一个好处是使得软件具有低耦合度。每个单元的接口列出了该单元提供的访问函数和需要使用的其它访问函数的集合。这个特征使得软件易于理解、维护和定位。

4、Incremental development 增量式开发

首先,指定单元之间的使用关系它为各个软件单元和它依赖的单元之间建立关联。将系统的这种使用关系表述成使用图,图中节点代表软件单元,有向边从使用其它单元的软件单元出发,指向被使用的单元。使用图可以帮助我们逐步确定更大的系统子集,对此我们可以增量的进行实现和测试。
扇入(fan in)指代使用某个软件单元的软件单元数量,扇出(fan out)指代某个软件单元使用其它软件单元的数量。

设计一个系统的最终目标之一是创建一个有着高扇入、低扇出的软件单元。(依赖包越少越好,被使用次数越多越好)
使用夹层法消除循环。

5、Abstract

抽象是一种忽略一些细节来关注其它细节的模型或表示。目标不同,忽略的细节也不同。
对于一个特定的模型,一个好的抽象的关键是决定哪些细节是不相关的,进而可以被忽略。抽象的性质取决于开始时我们建立这个模型的初衷,我们想交互哪些信息,或者我们想展示哪个分析过程。

6、Generality

在开发软件单元时,使它尽可能的能够称为通用的软件,来加强它在将来某个系统中能够被使用的可能性。
我们通过增加软件单元使用的上下文环境的数量来开发更加通用的软件单元,下面是几条实现规则:
将特定的上下文环境信息参数化:通过把软件单元所操作的数据参数化,我们可以开发出更加通用的软件
去除前置条件:使得软件在那些我们之前假设不可能发生的条件下工作
简化后置条件:把一个复杂的软件单元分解成若干个具有不同后置条件的单元,再将他们集中起来解决原来需要解决的问题,或者当只需要其中一部分后置条件时单独使用。

III. OO Design

Law of Demeter 德米特原则

 又叫做最少知识原则,也就是说,一个对象应当对其他对象尽可能少的了解,不和陌生人说话。
 目的在于降低类之间的耦合。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。
 不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。
 需要注意的是,应用该法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系——这在一定程度上增加了系统的复杂度

Dependency inversion(依赖倒置)

 used to reverse the direction of a dependency link between two classes

V. 面向对象设计模式

设计模式

创建型模式

工厂模式

结构性模式

组合模式

装饰器模式

行为型模式

观察者模式

策略模式

模板模式

访问者模式

VI. 设计中其他方面的考虑

数据管理

异常处理

VII. 面向对象度量

Chapter 7 Writing the Programs

这一章节在整体软件工程中属于代码实现这一过程的方法论,即给程序员的指导手册。不同于学生时代的单打独斗,进入公司后程序员需要合作一起完成一个项目的编程工作,这就需要有一定的标准和规范来让程序员编写的代码易于理解以提高沟通效率,方便合作;需要一定的编程指导原则来实现设计人员的设计;需要形成内外部文档便于团队内的长久沟通;需要了解不同的编程过程来提高生产效率。我们看到,这就是程序实现人员的工作职责和项目负责人对他们的殷切期望:在团队合作的背景下,高效地实现设计文档的内容。

大多数软件是由团队开发,涉及各种工作以生成高质量的产品,需要大量的协作和协调。因此,让他人理解你的代码理解为什么这么编写代码如何配合他们的工作,这非常重要。

从课程的角度,由于软件工程这门课侧重于整体的工程流程,而这章大多关注于编程实现,在其他课程中有所涉及,所以这一章的考察点主要在于概念理解上。

为什么说编程工作是复杂甚至令人气馁(daunting)的任务?
(1) 设计人员可能没有处理平台和编程环境的所有特性,易于用图表示的结构和关系并不是总能直截了当的编写代码。
(2) 编写易于理解的代码
(3) 编写的代码要易于重用
(4) 需要比照着设计进行检查

I. 编写标准和过程

不同于学习阶段的独立开发,公司中开发项目需要多人协同合作,编程标准和步骤就是公司们要求公司的代码符合某种风格,格式和内容标准。这样代码和相关的文档对每一个读者就会非常清晰。

7.1.1 编程标准对自身的作用

(1) 帮助自己组织想法,避免错误。
(2) 一些过程包括编写代码文档的方法,使得它更清晰且易于遵循
(3) 有助于将设计转化成代码(维护设计构件和代码构件的一致性)。

7.1.2 编程标准对他人的作用

(1)易于维护(2)易于测试(3)易于重用

7.1.3 设计与编程实现相匹配

(1) 在程序设计构件和程序代码构件间建立起直接的对应关系是最关键的标准。
(2) 设计诸如低耦合,高内聚,定义明确等特性的接口

II. 编程的指导原则(Programming guidelines)

一般性的编程原则应当从哪三个方面考虑?
控制结构,算法,数据结构

7.2.1 控制结构

当设计转变成代码时,我们希望保留组件的控制结构,在隐含调用的面向对象设计中,控制是基于系统状态和变量而变化的。
代码重组,模块化代码,注意构件通用性,注释里体现代码耦合,提高代码内聚度

7.2.2 算法

设计时通常会指定一类算法,编程时遵循。
选择算法时要在执行时间,设计质量,标准和客户需求之间平衡考虑。
编写某种算法时所涉及的问题
(1)编写更快代码的代价。可能会是代码更加复杂,从而要花费更多的时间编写代码
(2)测试代码的时间代价。代码的复杂度要求有更多的测试用例或测试数据
(3)用户理解代码的时间代价。
(4)需要修改代码时,修改代码的时间代价。

7.2.3 数据结构

编写程序时,应该安排数据的格式并进行存储,这样的数据管理和操作才能简明易懂。

7.2.4 通用编程策略

(1) 局部化输入和输出(单独设计 IO),更加易于维护。

指把一些关系密切的软件元素物理地放得彼此靠近。这种局部化有助于实现信息隐藏,因为不同模块之间的紧密联系被限制在局部范围内,避免了系统中不必要的耦合和依赖。例如,一个处理用户输入的模块可以与一个处理输出的模块放在同一个文件夹内,而与其他模块放在不同的文件夹内,这样就实现了局部化。

(2) 设计阶段包含伪代码,独立于特定的语言
(3) 改动时从需求改动,重新设计,重新编码,不要打补丁
(4) 重用

III. 文档化(Documentation)

7.3.1 内部文档

内部文档包含的信息是面向阅读程序源码的那些人的,因此它提供概要信息以识别程序,描述数据结构,算法和控制流。包含:
(1) 头注释块(header comment block,HCB)
将一组注释信息放在每个构件的开始部分,包含构件名,作者,配置在整个系统设计的哪个部分上,何时编写和修改的,为什么要有该构件,构件是如何使用数据结构,算法和控制的。
(2) 其他程序注释包含:
a. 可以对程序正在做什么提供逐行的解释。
b. 将代码分解成表示主要活动的段,每个活动再分解成更小的步骤。
c. 随着时间进行修改的记录。
(3) 有意义的变量名和语句标记
命名时尽量用有意义的变量名进行命名
(4) 排版格式以增强理解
注意缩进和间隔来反映基本的控制结构。

7.3.2 外部文档

外部文档的内容面向不看实际代码的人,如设计人员考虑修改或改进时;它在系统层面回答问题。

IV. 编程过程

7.4.1 编程作为求解过程

分为四步:理解问题,制定计划,执行计划,回顾

7.4.2 极限编程(Extreme Programming,XP)(第二章具体介绍)

极限编程是敏捷过程的一种具体形式,提供敏捷方法最一般原则的指导方针。

XP 的支持者强调敏捷方法的 4 个特性:交流、简单性、勇气以及反馈。

交流是指客户与开发人员之间持续地交换看法;

简单性激励开发人员选择最简单的设计或实现来处理客户的需要;

勇气体现在尽早地和经常交付功能的承诺;

在软件开发过程中的各种活动中,都包含反馈循环。例如,程序员一起工作,针对实现设计的最佳方式,相互提供反馈;客户和程序员一起工作时,以完成计划的任务。

极限编程的两类参与者:

客户:
(1)定义程序员将要实现的系统特征,使用故事的形式描述系统工作的方式
(2)描述测试计划,验证是否实现了所描述的故事
(3)为故事及其测试分配优先级程序员:

开发人员:将客户需求予以编程实现

7.4.3 派(结)对编程(Pair Programming)

结对编程属于主要的敏捷开发方法,开发方式是两个程序员共同开发程序,且角色分工明确:一个负责编写程序,另一个负责复审和测试,两个人定期交换角色。

优点:提高生产率和质量,但证据不充分,模棱两可

缺点:会抑制问题求解的基本步骤,扰乱对问题的关注

典型例题

  1. 简述编程应考虑的三方面原则
    (1)控制结构:当设计转变成代码时,我们希望保留组件的控制结构,在隐含调用的面向对象设计中,控制是基于系统状态和变量而变化的。
    (2)算法:在编写代码时,程序设计通常会制定一类算法,用于编写组件。
    (3)数据结构:编写程序时,应该安排数据的格式并进行存储,这样的数据管理和操作才能简明易懂。
  2. 名词解释:
    派对编程
    极限编程

Chapter 8 Testing the Programs 测试程序

章节概述
对于任何一个系统,测试的过程都是必不可少的。测试并不想我们想象的一样单纯,它也有自己的一套体系流程。本章介绍的就是有关测试的前半部分——单元测试和集成测试。将重新深入地认识故障和失效,了解测试的目的、流程和方法。如何从单元测试到将单元集成一个系统也是本章学习的内容。

I. Software Faults and Failures 故障和失效

8.1.1 故障

故障的定义:由错误(error)引起的系统内在问题。

故障出现的原因:

(1)软件本身,系统处理大量的状态,复杂的公式,活动,算法等;

(2)客户不清晰的需求;

(3)其他原因,如项目的规模,众多的参与者导致的复杂性。

8.1.2 失效

失效的定义:软件的动作与需求描述的不相符。

造成失效的原因:

(1)错误的规格说明,或者遗漏了一些需求;

(2)对于指定的硬件和软件,说明中存在一些无法完成的实现;

(3)错误的系统设计;

(4)错误的程序设计,错误的实现。

故障的识别(fault identification):是确定由哪一个或者哪些故障引起失效的过程。

故障改正(fault correction)或故障去除(fault removal):修改系统使得故障得以全部去除的过程。

8.1.3 故障的分类

分类的原因:知道正在处理的是什么类别的故障对于我们具体的测试,以及之后的故障改正都是有很大帮助的。

(1)算法故障(algorithmic fault):由于处理步骤中的某些错误,使得对于给定的输入,构件的算法或逻辑没有产生适当的输出。
(2)计算故障(computation fault)或精读故障(precision fault):一个公式的实现是错误的,或者计算结果没有达到要求的精度。
(3)文档故障(documentation fault):文档与程序实际做的事情不一致。
(4)压力故障(stress fault)或过载故障(overload fault):对队列长度、缓冲区大小、表的维度等的使用超出了规定的能力。
(5)能力故障(capacity fault)或边界故障(boundary fault):系统活动到达指定的极限时,系统性能会变得不可接受。
(6)计时故障(timing fault)或协调故障(coordination fault):几个同时执行或仔细定义顺序执行的进程之间协调不适当。
(7)吞吐量故障(throughput fault)或性能故障(performance fault):系统不能以需求规定的速度执行。
(8)恢复故障(recovery fault):当系统失效时,不能表现得像设计人员希望的或客户要求的那样。
(9)硬件和系统软件故障(hardware and system software fault):当提供的硬件或者系统软件实际上并没有按照文档中的操作条件或步骤运作时。
(10)标准和过程故障(standards and procesure fault):代码没有遵循组织机构的标准和过程。

8.1.4 正交缺陷分类

定义:被分类的任何一项故障都只属于一个类别,则分类方案是正交的。如果一个故障 属于不止一个类,则失去了度量的意义。

II. Testing Issues

8.2.1 测试的组织

1 测试的阶段:
(1)模块测试(module testing)、构件测试(component testing)或单元测试(unittesting):将每个程序构件与系统中的其他构件隔离,对其本身进行测试。
(2)集成测试(integration testing):验证系统构件是否能够按照系统和程序设计规格说明中描述的那样共同工作的过程。
(3)功能测试(function test):对系统进行评估,以确定集成的系统是否确实执行了需求规格说明中描述的功能,其结果是一个可运转的系统。
(4)性能测试(performance test):测试系统的软硬件性能是否符合需求规格说明文档。其结果是一个确认的系统。
(5)验收测试(acceptance test):确定系统是按照用户的期望运转的。
(6)安装测试(installation test):确保系统在实际环境中按照应有的方式运转。
(7)系统测试(system test):功能测试、性能测试、验收测试和安装测试统称为系统测试。

8.2.4 测试的方法

1.黑盒:将测试的对象看作是一个不了解其内容的闭盒,我们的测试就是向闭盒提供输入的数据,并记录产生的输出。测试的目标是确保针对每一种输入,观察到的输出与预期的输出相匹配。黑盒测试参考的文档是系统设计和程序设计阶段的文档。
优点:黑盒测试免于受强加给测试对象内部结构和逻辑的约束。更偏向于功能性的测试。
缺点:黑盒法以 SRS 为依据,有一定的盲目性和不确定性,不可能揭示所有的错误。没办法总是使用这种方式进行完备的测试。不容易找到具有代表性的测试用例证明所有情况下功能都正确。

2.白盒:将测试对象看作一个白盒,然后根据测试对象的结构用不同的方式进行测试。
优点:可以测试一个模块的细节。
缺点:该法以模块内部逻辑为依据,当内部逻辑过于复杂时,则不能给出好的或合适的测试用例。有时候,对于大量递归、循环和分支的构件,想要测试完所有的分支也是不现实的。

  1. 实际测试中,没有必要把黑盒测试和白盒测试严格的区分开来。具体的测试方法的选择受到很多因素的影响。

Chapter 9 Testing the System 系统测试

1. 系统测试的主要步骤及各自含义?

1、功能测试:根据SRS测试系统功能。

2、性能测试:根据SRS测试系统性能。

3、验收测试:根据客户的需求定义,由客户和用户一起测试。

4、安装测试:在用户环境下进行测试。

2. 什么是回归测试?

回归测试是用于新的版本或者改进版本的一种测试,以验证与旧版本相比,软件是否仍然以同样的方式执行同样的功能。

3.确认测试概念,确认测试分类?(基准测试、引导测试、并行测试)

确认测试:由用户检查软件系统是否满足了他们的需求的测试。

Pilot test: install on experimental basis
Alpha test: in-house test
Beta test: customer pilot
Parallel testing: new system operates in parallel with old system

1、基准测试:

由用户准备典型测试用例,在实际安装后的系统运作并由用户对系统执行情况进行评估。

2、引导测试:

在假设系统已经永久安装的前提下执行系统。它依赖系统的日常工作进行测试,相对基准测试不是非常的正式与结构化。

4. 什么是alpha测试?β测试?

α测试:内部测试。客户进行实际的测试前,先自己组织团队(或者委托其他团队)测试这个系统。

β测试:公测。客户实际进行的测试。

  1. α测试

就是把用户请到公司内部进行测试使用。

α测试是由一个用户在开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的测试;

目的:是评价软件产品的FLURPS(即功能、局域化、可使用性、可靠性、性能和支持)。

注意!α测试不能由程序员或测试员完成。

  1. β测试

用户在不同场所进行测试。

β测试是一种验收测试。β测试由软件的终用户们在一个或多个场所进行。

重点内容与习题

计算关键路径

IMG_20231011_075656

建模

UML类图
消息时序图

数据流图

状态机图

附件

posted @ 2023-12-30 10:18  星塵織夢  阅读(134)  评论(0)    收藏  举报