软件开发过程(process)
是一个将用户需求转化为软件系统所需要的活动的集合。
软件生命周期(SDLC,Software Devlopment Life Cycle)
软件从孕育、诞生、成长、成熟、衰亡等阶段称为软件生命周期。
早期系统开发的生命周期以结构化的方法具体分成了六个阶段:问题的定义及规划、需求分析、软件设计、程序编码、软件测试、运行维护。
而随着面向对象方法和统一软件开发过程(RUP)方法论的提出,出现统一过程的生命周期,在统一过程中以迭代的方式重复一些列组成系统生命周期的循环,每次循环都可以向用户提供一个产品版本作为终结。每次迭代都包括四个阶段:初始、细化、构造和交付。
软件开发模型(Software Development Model)
软件开发模型是软件开发全过程、软件开发活动以及他们之间关系的结构框架。它是一种策略,这种策略是由软件工程师在具体的实践工程活动当中设计并提炼出来,能够覆盖软件生命周期的基本阶段,确定设计的方法、过程及工具。
软件开发模型也称软件生命周期模型(Life Cycle Model),典型的软件开发模型有:瀑布模型、快速原型模型、迭代模型、螺旋模型等。
瀑布模型(Waterfall Model)
瀑布模型的软件开发过程与软件生命周期是一致的并且它是由文档驱动,两相邻阶段之间存在因果关系。
缺点:
1. 瀑布模型假定用户的需求是不变的,因此缺乏灵活性。瀑布模型本质上是一种线性顺序模型,各阶段之间存在着严格的顺序性和依赖性,特别是强调预先定义需求的重要性,在着手进行具体的开发工作之前,必须通过需求分析预先定义并“冻结”软件需求,然后再一步一步的实现这些需求。
2. 以文档驱动,导致产生大量的文档资料。
3. 由于以文档为主体的特点,很多的问题可能在最后才会暴露出来,风险被压后,后果可能是巨大的。如某个需求在前期分析时认为是可行的,而接纳到开发计划里,但直到详细设计,甚至具体实现时才发现无法实现……。或者是直到测试阶段才知道需求理解有偏差,核心业务要推倒重写。
快速原型模型(Rapid Prototype)
快速原型模型又称原型模型,它是增量模型的另一种形式;快速原型模型的第一步是建造一个快速原型,实现客户或未来的用户与系统的交互。
快速原型在功能上等价于产品的一个子集。根据客户的需要在很短的时间内解决用户最迫切的需要,此时只是部分功能的实现,快速原型模型最重要的目的是确定用户真正的需求并支持需求的动态变化。一般不会单独使用,而和其他模型一起使用。
迭代模型
迭代模型指在进行较大规模的项目任务时,将开发分为若干次迭代,每次迭代都要从项目的管理及计划、分析、设计、实现到运作整个过程。又称做迭代和增量式开发或迭代和进化式开发。
注意点!!
- 一次迭代时间在2到6周之间,小步骤、快速反馈和调整是迭代的主要思想。仅一周的迭代时间不足以获取有意义的产出和反馈。若大于6周则复杂性会变得不可控制,反馈将延迟。时间太长会破坏迭代的核心动机并增加项目风险。
- 一个关键思想是时间定量。在项目开始之初就要确定下来迭代时间,之后的工作都必须依照时间表来集成、测试和稳定局部系统。如果难以满足期限要求,建议从本次迭代中移去一些任务或需求,但不能推迟完成日期。
- 迭代开发中绝不能被“瀑布思维”侵蚀,不要在编程前做完整而详细的分析。整个开发过程是不断迭代和进化的,所以实现前的所有需求和设计都是不完整的,它们会在一次次迭代中基于反馈而完善。
- 整个项目不会有完整的计划,而是制定估计结束日期和阶段计划(Rup中的里程碑),但不会对这些阶段计划详细定义细粒度的步骤。只能预先对一次迭代制定详细计划(迭代计划)。
- 每次迭代都具有各自的需求分析、设计、实现和测试活动,实质上,它类似小型的瀑布式项目。每一次的迭代都会产生一个经过测试、集成并可执行的局部系统,它是最终产品的一个子集。
需求变更是软件开发永恒的主题,而迭代开发可以包容变更。经过多次迭代的系统持续地扩展和精化,并以循环反馈和调整为核心驱动力,最终称为适当的系统。
- 来自早期开发中的反馈,有助于程序设计人员理解规格说明,有助于精化需求。
- 来自测试中的反馈,有助于开发者精化设计或模型。
- 来自团队处理早期特性过程中的反馈,有助于精化时间表和估计。
- 来自客户和市场的反馈,有助于重新定义下一次迭代实现特性的优先级。
- 在早期缓解高风险(技术、需求、目标、可用性等等)。
- 由于用户的需求并不能在一开始就作出完全的界定,它们通常是在后续阶段中不断细化的。因此,迭代过程这种模式使适应需求的变化会更容易些。
- 早期反馈、用户参与和调整,会产生更接近涉众真是需求的精化系统。
- 加快了整个开发工作的进度。因为开发人员清楚问题的焦点所在,他们的工作会更有效率。
- 减少项目失败的可能性,提高生产率,降低缺陷率。如果开发人员重复某个迭代,那么损失只是这一个开发有误的迭代的花费。
- 早期可见的进展。降低了产品无法按照既定进度进入市场的风险。通过在开发早期就确定风险,可以尽早来解决而不至于在开发后期匆匆忙忙。
- 复杂性降低;团队不会被“分解瘫痪”或长期且复杂的步骤所淹没。
- 一次迭代中的经验可以被系统地改进开发过程本身,应如此反复进行下去。
总结:
风险之所以称为风险是由于它的不可预估性,而对于软件开发,最主要的一个风险就是需求变更或者需求理解错误。最有效的应对办法就是尽早验证,并控制风险的影响规模。迭代开发可以尽早地得到一个可运行的系统。客户绝大部分情况下是在看到并使用了系统之后,才会提出需求变更,认为有不合适的地方。
在早期的迭代中包含对客户来说最核心、最复杂、或最不稳定的那一部分需求。可以保障核心业务尽早和尽可能多地经历验证和测试,保证交付时核心业务称为最稳定的模块。
通过迭代方式,开发工作可尽早开始,则由于开发周期的加长,可以投入更少的开发人员。同时分析设计和开发越早参与项目,则技能越纯熟,后期所面临的问题越少。可以降低技术风险和人力资源风险。
螺旋模型(Spiral Model)
螺旋模型是瀑布模型和快速原型模型的有机结合,它是由风险驱动的,它强调了其他模型所忽略的风险分析。
统一过程(Unified Process,Up)
统一过程:是一种现代的软件开发过程模型。它是基于构件(Component-based)的,即所构造的软件系统是由软件构件通过明确定义的接口相互链接所建造起来的。并且它使用统一建模语言(Unified Modeling Language,UML)来制定系统的所有蓝图。
UP三大基本公理(特征)
用例和风险驱动
UP 一般由UML方法和工具支持。用例是捕获需求的方法,因此,也可以说UP是用例(需求)驱动的。
UP的另一个驱动就是风险,因为如果你不主动预测和防范风险,风险就会主动攻击你。UP需要对软件开发中的风险进行分析、预测并关注软件的构造。
以体系结构为核心
UP方法实际上就是开发和演进一个健壮的系统体系结构,体系结构描述了系统的整体框架:如何把系统划分成组件以及这些组件如何进行交互和部署在硬件上。组件使重用成为可能,系统可以由组件组成。基于独立的、可替换的、模块化组件的体系结构有助于管理复杂性,提高重用率。RUP描述了如何设计一个有弹性的、能适应变化的、易于理解的、有助于重用的软件体系结构。
迭代及增量
Up迭代表示我们把项目分成小的子项目(迭代),它提供系统的功能块或者增量,最终产生完整的功能系统。每一次迭代都经历一次完整的软件生命周期,每一次迭代都有需求、分析、设计、实施,并以一个可执行版本结束。
执行迭代计划的关键是准确获知每个迭代要完成的目标,如果采用UML建模,则用例就是最好的迭代点。可以为用例排出优先级,在每个迭代中实现一部分用例。
____________________________
总结
在软件工程实际运用中,只采用单一一种模型显然不能适应项目负责的需求变化,采用各种模型组合开发的形式在实际运用中较为广泛。
____________________________
RUP(Rational Unified Process 统一软件开发过程)
RUP 是 Rational 公司开发和维护的过程产品。它完全兼容UP,但比UP更加完整、详细。它提供了在开发组织中分派任务和责任的纪律化方法。它的目标是在可预见的日程和预算前提下,确保满足最终用户需求的高质量产品。
里程碑
RUP中的软件生命周期在时间上被分解为四个顺序的阶段,分别是:初始阶段(Inception)、细化阶段(Elaboration)、构造阶段(Construction)和交付阶段(Transition)。每个阶段结束于一个主要的里程碑(Major Milestones);每个阶段本质上是两个里程碑之间的时间跨度。在每个阶段的结尾执行一次评估以确定这个阶段的目标是否已经满足。如果评估结果令人满意的话,可以允许项目进入下一个阶段。
初始阶段
主要目标
- 明确软件系统的范围和边界条件,括从功能角度的前景分析、产品验收标准和哪些做与哪些不做的相关决定
- 明确区分系统的关键用例(Use-case) 和主要的功能场景
- 展现或者演示至少一种符合主要场景要求的候选软件体系结构
- 对整个项目做最初的项目成本和日程估计(更详细的估计将在随后的细化阶段中做出)
- 估计出潜在的风险(主要指各种不确定因素造成的潜在风险)
- 准备好项目的支持环境
产出
- 核心项目需求、关键特色和主要约束的总体蓝图
- 原始用例模型(完成10%~20%)
- 原始项目术语表(可能部分表达为业务模型)
- 原始商业案例,包括业务的上下文、验收规范(年度映射、市场认可等等),成本预计
- 原始的风险评估
- 一个或多个原型
里程碑
生命周期目标里程碑,评价项目基本的生存能力。
评审标准
- 风险承担者就范围定义成本日程估计达成共识
- 以客观的主要用例证实对需求的理解
- 成本/日程、优先级、风险和开发过程的可信度
- 被开发体系结构原型的深度和广度
- 实际开支与计划开支的比较
- 如果无法通过这些里程碑,则项目可能被取消或仔细地重新考虑。
细化阶段
主要目标
- 确保软件结构、需求、计划足够稳定;确保项目风险已经降低到能够预计完成整个项目的成本和日程的程度。
- 针对项目的软件结构上的主要风险已经解决或处理完成。
- 通过完成软件结构上的主要场景建立软件体系结构的基线。
- 建立一个包含高质量组件的可演化的产品原型。
- 说明基线化的软件体系结构可以保障系统需求可以控制在合理的成本和时间范围内。
- 建立好产品的支持环境。
产出
- 用例模型(完成至少80%)-- 所有用例均被识别,大多数用例描述被开发
- 补充捕获非功能性要求和非关联于特定用例要求的需求
- 软件体系结构描述_可执行的软件原型
- 经修订过的风险清单和商业案例
- 总体项目的开发计划,包括纹理较粗糙的项目计划,显示迭代过程和对应的审核标准
- 指明被使用过程的更新过的开发用例
- 用户手册的初始版本(可选)
里程碑
生命周期结构里程碑,为系统的结构建立了管理基准并使项目小组能够在构建阶段中进行衡量。检验详细的系统目标和范围、结构的选择以及主要风险的解决方案。
评审标准
- 产品的蓝图是否稳定?
- 体系结构是否稳定?
- 可执行的演示版是否显示风险要素已被处理和可靠的解决
- 构建阶段的计划是否足够详细和精确?是否被可靠的审核基础支持?
- 如果当前计划在现有的体系结构环境中被执行而开发出完整系统,是否所有的风险承担人同意该蓝图是可实现的?
- 实际的费用开支与计划开支是否可以接受?
- 如果无法通过这些里程碑,则项目可能被取消或仔细地重新考虑。
构造阶段
主要目标
- 通过优化资源和避免不必要的返工达到开发成本的最小化
- 根据实际需要达到适当的质量目标
- 据实际需要形成各个版本(Alpha,Beta,and other test release)
- 对所有必须的功能完成分析、设计、开发和测试工作
- 采用循环渐进的方式开发出一个可以提交给最终用户的完整产品
- 确定软件站点用户都为产品的最终部署做好了相关准备
- 达成一定程度上的并行开发机制
产出
- 特定平台上的集成产品
- 用户手册
- 当前版本的描述
里程碑
初始功能里程碑,决定了产品是否可以在测试环境中进行部署。此刻,要确定软件、环境、用户是否可以开始系统的运作。此时的产品版本也常被称为“beta”版。
评审标准
- 产品是否足够稳定和成熟得发布给用户?
- 是否所有的风险承担人准备好向用户移交?
- 实际费用与计划费用的比较是否仍可被接受?
- 如果无法通过这些里程碑,则移交不得不被延迟。
交付阶段
主要目标
- 进行 Beta 测试以期达到最终用户的需要
- 进行 Beta 测试和旧系统的并轨
- 转换功能数据库
- 对最终用户和产品支持人员的培训
- 提交给市场和产品销售部门
- 和具体部署相关的工程活动
- 协调 Bug 修订/改进性能和可用性(Usability)等工作
- 基于完整的 Vision 和产品验收标准对最终部署做出评估
- 达到用户要求的满意度
- 达成各风险承担人对产品部署基线已经完成的共识
- 达成各风险承担人对产品部署符合 Vision 中标准的共识
- 该阶段依照产品的类型,可能从非常简单到极端复杂的范围内变化。例如,现有的桌面产品的新版本可能非常简单,而替代国际机场的流量系统会非常复杂。
里程碑
产品发布里程碑。此时,决定是否目标已达到或开始另一个周期。在许多情况下,里程碑会与下一个周期的初始阶段相重叠。
评审标准
- 用户是否满意?
- 实际费用与计划费用的比较是否仍可被接受?
工作流
RUP中有9个核心工作流,分为6个核心过程工作流(Core Process Workflows)和3个核心支持工作流(Core Supporting Workflows)。尽管6个核心过程工作流可能使人想起传统瀑布模型中的几个阶段,但应注意迭代过程中的阶段是完全不同的,这些工作流在整个生命周期中一次又一次被访问。9个核心工作流在项目中轮流被使用,在每一次迭代中以不同的重点和强度重复。
商业建模(Business Modeling)
商业建模工作流描述了如何为新的目标组织开发一个构想,并基于这个构想在商业用例模型和商业对象模型中定义组织的过程,角色和责任。
需求(Requirements)
需求工作流的目标是描述系统应该做什么,并使开发人员和用户就这一描述达成共识。为了达到该目标,要对需要的功能和约束进行提取、组织、文档化;最重要的是理解系统所解决问题的定义和范围。蓝图被创建,需求被提取。代表用户和其他可能与开发系统交互的其它系统的 Actor 被指明。Use case 被识别,表示系统的行为。因为use case 根据 actor 的要求开发,系统与用户之间的联系更紧密。系统展示了用于再生系统的用例模型。
分析和设计(Analysis & Design)
分析和设计工作流将需求转化成未来系统的设计,为系统开发一个健壮的结构并调整设计使其与实现环境相匹配,优化其性能。分析设计的结果是一个设计模型和一个可选的分析模型。设计模型是源代码的抽象,由设计类和一些描述组成。设计类被组织成具有良好接口的设计包(Package)和设计子系统(Subsystem),而描述则体现了类的对象如何协同工作实现用例的功能。 设计活动以体系结构设计为中心,体系结构由若干结构视图来表达,结构视图是整个设计的抽象和简化,该视图中省略了一些细节,使重要的特点体现得更加清晰。体系结构不仅仅是良好设计模型的承载媒介,而且在系统的开发中能提高被创建模型的质量。
实现(Implementation)
实现工作流的目的包括以层次化的子系统形式定义代码的组织结构;以组件的形式(源文件、二进制文件、可执行文件)实现类和对象;将开发出的组件作为单元进行测试以及集成由单个开发者(或小组)所产生的结果,使其成为可执行的系统。
测试(Test)
测试工作流要验证对象间的交互作用,验证软件中所有组件的正确集成,检验所有的需求已被正确的实现, 识别并确 认缺陷在软件部署之前被提出并处理。RUP提出了迭代的方法,意味着在整个项目中进行测试,从而尽可能早地发现缺陷,从根本上降低了修改缺陷的成本。测试类似于三维模型,分别从可靠性、功能性和系统性能来进行。
部署(Deployment)
部署工作流的目的是成功的生成版本并将软件分发给最终用户。部署工作流描述了那些与确保软件产品对最终用户具有可用性相关的活动,包括:软件打包、生成软件本身以外的产品、安装软件、为用户提供帮助。在有些情况下,还可能包括计划和进行beta测试版、移植现有的软件和数据以及正式验收。
配置和变更管理 (Configuration & Change Management)
配置和变更管理工作流描绘了如何在多个成员组成的项目中控制大量的产物。配置和变更管理工作流提供了准则来管理演化系统中的多个变体,跟踪软件创建过程中的版本。工作流描述了如何管理并行开发、分布式开发、如何自动化创建工程。同时也阐述了对产品修改原因、时间、人员保持审计记录。
项目管理(Project Management)
软件项目管理平衡各种可能产生冲突的目标,管理风险,克服各种约束并成功交付使用户满意的产品。其目标包括:为项目的管理提供框架,为计划、人员配备、执行和监控项目提供实用的准则,为管理风险提供框架等。
环境(Environment)
环境工作流的目的是向软件开发组织提供软件开发环境,包括过程和工具。环境工作流集中于配置项目过程中所需要的活动,同样也支持开发项目规范的活动,提供了逐步的指导手册并介绍了如何在组织中实现过程。
敏捷开发(Agile Development)
敏捷开发通常应用时间定量的迭代和进化式开发、使用自适应计划、提倡增量交付并包含其他提倡敏捷性(快速和灵活的响应变更)的价值和实践。
敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。
敏捷开发只写有必要的文档,或尽量少写文档,注重人与人之间,面对面的交流,所以它强调以人为核心。
敏捷开发不是一门技术,它是一种方法论,也就是一种软件开发的流程,它会指导我们用规定的环节去一步一步完成项目的开发;而这种开发方式的主要驱动核心是人;它采用的是迭代式开发。在敏捷开发中,软件项目的构建被切分成多个子项目,各个子项目的成功都经过测试,具备集成和可运行的特征。
敏捷就是“快”,快才可以适应目前社会的快节奏;要快就要发挥个人的个性思维多一些,个性思维的增多,虽然通过结队编程、代码共有、团队替补等方式减少个人对软件的影响力,但也会造成软件开发继承性的下降,因此敏捷开发是一个新的思路,但不是软件开发的终极选择。对于长时间、人数众多的大型软件应用的开发,文档的管理与衔接作用还是不可替代的。
敏捷UP
统一过程(UP)并没有被赋予重量级或非敏捷的含义,Up可以采纳和应用可适应性和轻量级的精神,从而产生敏捷Up。
Craig Larman : 《敏捷迭代开发:管理者指南》,《UML和模式应用》。
- 使用UP活动和制品的简集。除非能增加价值,否则避免创建这些制品。应该致力于早期编程而非构建文档。
- 以敏捷建模实践应用UML。敏捷建模:强调UML作为草图的方式(非正式、不完整的图,通常是在白板上手绘的草图,借助可视化语言的功能,用于探讨问题和解决方案空间的复杂部分),而且通常费时较短,对时间投入具有高回报。
如何进行迭代开发的分析与设计
一、需求工作会议:假设在最终交付前将有20次迭代。在第一次迭代之前,先进行高阶需求分析。
1)通过高阶需求分析,例如仅仅确定用例和特性的名称,以及关键的非功能性需求。这个分析不可能是完美的。
2)从高阶列表中选择10%列表项(需要具备以下特征:1.具有重要的架构意义。2具有高业务价值。3具有高风险。)。
3)对选中的这些个用例的功能和非功能性需求进行详细的分析。
完成这一个过程后,对10%进行了深入分析,90%进行了高阶分析。
——————
二、第一次迭代:因为选中的这些用例中包含大量工作,所以并不是第一次迭代就要把选中的用例都构造出来。
1)在选中的这些用例中,选择的子集目标。
2)在团队的帮助下,将其分解为一系列更为详细的迭代任务。
3)在特定的时间内(如3周的时间定量迭代)进行设计、构造和测试,完成第一次迭代。
- 建模
- 开发
- 测试
- 在结束前一周,检查是否能够完成初始的迭代目标,如果不能,则缩小迭代范围,将次要目标置回任务列表。
- 在最后一周的周二,冻结代码,必须检入(使用版本控制和配置管理工具)、集成和测试所有的代码,以建立迭代的基线。
- 周三上午,上外部涉众演示此局部系统,展示早期可视进展,同时要求反馈。
4)在第一迭代即将结束时(如最后一周的周三和周四),召开第二次需求工作会,对上一次会议的所有材料进行复查和精化。然后选择具有重要架构意义和高价值业务价值的另外10%到15%的用例,用1到两天对其进行详细分析。
这项工作完成后,会详细记录大概25%的用例和非功能需求,当然是不完美的。
5)周五上午,举行下一迭代计划会议。
6)以相同的步骤进行第二次迭代。
7)反复进行4次迭代和五次需求工作会,
这样在第4次迭代结束时,可能已经详细记录了约80%~90%的需求,但只实现了系统的10%。
这些大量、详细的需求集是基于反馈和进化的,因此其质量远高于纯粹依靠推测而得到的瀑布式规格说明。
8)我们大概推进了整个项目过程的20%,这是细化阶段的结束。此时可以估计这些精化的、高质量的需求所需工作量和时间了。因为具有依据现实得出的调查、反馈结论并进行了早期编程和测试,因此估计能够做什么和需要多长时间的结果会更可靠。
9)此后,一般不需要再召开需求工作会,需求依据基本稳定了。接下来是一系列为期3周的迭代,在最后一个周五召开的迭代计划会上选择适宜的下一步工作,每次迭代都要反复询问:“就我们现在所知,下一个三周应该完成的、最关键的技术和业务特性是什么?”