23春复习答疑摘要:
课件,作业,公式TCF,技术复杂度,因子计算,UUCP,UCW,权值 0.3.5。软件维护内容少点。特别复杂带经验导出算式的计算不做要求,像b的三分之一次方那种。参数表会提供。填空1×10,选择1×10,判断1×10,简答(30多分过程、比较、优缺点分析),综合题(计算,写公式拿步骤分)。
软件过程与项目管理期末复习总结
01 概述
软件(Software):一组对象或项目所形成的一个“配置”,由程序、 文档和数据等部分构成。
– 程序(program):可被计算机硬件理解并执行的一组指令,提供期望的功能 和性能
– 数据(data structure):程序能正常操纵信息的数据结构
– 文档(document):与程序开发、维护和使用有关的图文材料
软件的四大特征
复杂性(complexity) – 软件要解决的现实问题通常很复杂,数据、状态、逻辑关系的可能组合导 致了软件本身的复杂性 – 软件无法以“制造”的方式被生产,只能采用手工开发方式,这是一种人 为、抽象化的智能活动(智力密集型),与人的水平密切相关,人类思维的 不确定性导致了开发过程的复杂性
不可见性(invisibility) – 尚未完成的软件是看不见的,无法像产品一样充分呈现其结构,使得人们 在沟通上面临极大的困难,难以精确的刻画和度量
易变性(changeability) – 软件所应用的环境由人群、法规、硬件设备、应用领域等因素汇集而成, 而这些因素皆会频繁快速的变化
一致性(conformity) – 各子系统的接口必须协同一致,而随着时间和环境的演变,要维持这样的 一致性通常十分困难
“变化”是永恒的主题: – 软件必须不断的变化以适应新的计算环境或新技术的发展 – 软件必须通过不断的功能增强以实现新的业务需求 – 软件必须通过扩展以与其他软件系统进行互操作 – 软件必须被不断的重构以使其生命周期得以延续
软件的特性
• 不可视性与主观性 • 软件规模与复杂性 • 易变性与不确定性 • 精确性与模糊性
软件及其开发方式的发展
第一阶段(1950-1960年代): – 软件主要用于数值计算的需求; – 程序设计被认为是一种任人发挥创造才能的活 动,程序的质量完全依赖于程序员的个人才能; – 软件从“简单 复杂”的发展,导致“软件危 机”的出现
第二阶段(1970年代): – 软件开始向商务领域推广,出现了结构化编程、 数据库等技术; – 软件不仅是程序,还包括开发、使用、维护等 文档,“软件生命周期”的概念开始形成
第三阶段(1980年代): – 软件系统的规模、复杂度进一步扩大; – 开始关注对软件开发过程的管理及工程性的开 发; – 出现了CASE工具; – 开始关注软件的质量度量和管理; – 面向对象(OO)思想开始出现
第四阶段(1990年代): – Internet和Web分布式、异构环境下的软件; – 软件复用成为关注点; – 软件生命周期的每一个阶段都发展出详细的方 法论; – 分布式计算、网格技术
第五阶段(2000年代-至今): – 软件的服务化、系统互操作的需求 – 基于云计算平台的软件体系结构、模型驱动的 开发方法MDA、敏捷软件开发方法、软件集 成开发环境及工具 – 面向服务的体系架构SOA方法 – 基于互联网与云计算的软件开发方法 – 普适计算、移动计算
软件开发技术的发展过程
1950-1960年代: 软件 = 程序(Program) 面向过程的软件 = 算法(Algorithm) + 数据结构(Data Structure)
1970年代: 软件 = 程序(Program) + 文档(Document) 软件 = 程序(Program) + 文档(Document) + 数据(Data)
1980-1990年代: 面向对象的软件 = 对象(Object) + 消息(Message)
1990年代-至今: 面向构件的软件 = 构件(Component) + 框架(Framework) 面向服务的软件 = 服务(Service) + 消息(Message) + 总线(Bus)
软件本身在概念建构上具有先天的困难,即如何从抽象性问题发展出具体概念上的解决方案
软件危机(Software Crisis):计算机软件的开发和维护过程所遇到的一 系列严重问题
软件危机的表现: – 对软件开发成本和进度的估算很不准确,甚至严重拖期和超出预算 – 无法满足用户需求,导致用户很不满意 – 质量很不可靠,经常失效 – 难以更改、调试和增强 – 没有标准、完整的文档 – 软件成本严重上升 – 软件开发生产率跟不上计算机应用迅速发展的趋势
“软件工程”是…
范围: – 软件开发过程(分析、设计、实现、测试、运行、维护) – 软件开发中应遵循的原则和管理技术 – 软件开发中所采用的技术和工具
目标: – 满足用户需求 – 按时交付 – 控制成本 – 高质量
软件开发方法学
分类
– 结构化开发方法(Structured Analysis and Design Technique, SADT)
– 面向对象开发方法(Object Oriented Analysis and Design, OOAD)
– 基于UML的OOAD
工具:自动或半自动的软件支撑环境,辅助软件开发任务的完成,提 高开发效率和软件质量、降低开发成本
02 软件工程核心思想
映射与转换 任何软件系统开发的共同本质在于: – 从现实空间的需求到计算机空间的软件代码之间的映射与转换
软件工程本质:用严格的规范和管理手段来缩小偏差,通过牺牲“时间”来提高“质量”
概念映射:问题空间的概念与解空间的模型化概念之间的映射
业务逻辑映射:问题空间的处理逻辑与解空间处理逻辑之间的映射
为了实现以上两个映射,软件工程需要解决以下问题:
– 需要设置哪些抽象层次——单步映射?多步映射?几步?
– 每一抽象层次的概念、术语与表达方式——公式?图形?文字?
– 相邻的两个抽象层次之间如何进行映射——需要遵循哪些途径和原 则?
现实空间的需求 ➡ 需求规约:需求分析:在一个抽象层上建立需求模型的活动,产生需求规约 (Requirement Specification),作为开发人员和客户间合作的基础,并 作为以后开发阶段的输入。
需求规约 ➡ 设计规约:**软件设计:**定义实现需求规约所需的系统内部结构与行为,包括软件 体系结构、数据结构、详细的处理算法、用户界面等,即所谓设计规 约(Design Specification),给出实现软件需求的软件解决方案
设计规约 ➡代码:实现:由设计规约到代码的转换,以某种特定的编程语言,对设计规 约中的每一个软件功能进行编码
验证/确认:一种评估性活动,确定一个阶段的产品是否达到前阶段确 立的需求 (verification) , 或 者 确 认 开 发 的 软 件 与 需 求 是 否 一 致 (validation)
软件工程所关注的对象 产品:各个抽象层次的产出物 过程:在各个抽象层次之间进行映射与转换
软件工程具有“产品与过程二相性”的特点,必须把二者结合起来去考 虑,而不能忽略其中任何一方
软件工程所关注的目标 功能性需求(Functional Requirements):软件所实现的功能达到它的设计规范和满足用户需求的程度(完备性、正确性、健壮性、 可靠性); 非功能性需求(Non-Functional Requirements):系统能够完成所期望的 工作的性能与质量 (效率、可用性、可维护性、可移植性、清晰性等)
典型NFR举例:可用性(availability): 当系统不再提供其规格说明中所描述的服务时,就出现了系统故障, 即表示系统的可用性变差 ; 关注的方面: – 如何检测系统故障、故障发生的频度、出现故障时的表现、允许系 统有多长时间非正常运行、如何防止故障发生、发生故障后如何消 除故障、等等
错误检测(Fault Detection) – 命令-响应机制(ping-echo)、心跳(heartbeat)机制、异常机制 (exception)
错误恢复(Recovery) – 表决、主动冗余(热重启)、被动冗余(暖重启/双冗余/三冗余)、 备件(spare) – Shadow操作、状态再同步、 检查点/回滚
错误预防(Prevention) – 从服务中删除、事务、进程 监视器
典型NFR举例:可维护性/修改性(modifiability): 可以修改什么——功能、平台(HW/OS/MW)、外部环境、质量属性、 容量等 何时修改——编译期间、构建期间、配置期间、执行期间 谁来修改——开发人员、最终用户、实施人员、管理人员 修改的代价有多大? 修改的效率有多高?
目标:减少由某个修改所直接/间接影响的模块的数量 常用决策: – 高内聚/低耦合、固定部分与可变部分分离、抽象为通用模块、变 “编译”为“解释” – 信息隐藏、保持接口抽象化和 稳定化、适配器、低扇出 – 推迟绑定时间 —运行时注册、 配置文件、多态、运行时动态 替换
典型NFR举例:安全性(security): 安全性:系统在向合法用户提供服务的同时,阻止非授权使用的能力 – 未经授权试图访问服务或数据 – 试图修改数据或服务 – 试图使系统拒绝向合法用户提供服务 关注点:抵抗攻击、检测攻击、从攻击中恢复
抵抗攻击——对用户进行身份认证、对用户进行授权、维护数据的机 密性、限制暴露的信息、限制访问 检测攻击——模式发现、模式匹配 从攻击中恢复——将服务或数据回复到正确状态、维持审计追踪
不同目标之间的关系—折中(tradeoff): 不同类型的软件对质量目标的要求各有侧重: – 实时系统:侧重于可靠性、效率 – 生存周期较长的软件:侧重于可移植性、可维护性 多个目标同时达到最优是不现实的: – 目标之间相互冲突
视角不同,需求各有不同
软件工程=最佳实践
软件工程核心思想:分而治之(Divide and Conquer) 将复杂问题分解为若干可独立解决的简单子问题,并分别独立求解, 以降低复杂性 然后再将各子问题的解综合起来,形成最初复杂问题的解;复用(Reuse) 在一个新系统中,大部分的内容是成熟的,只有小部分内容是全新的 构造新的软件系统可以不必每次从零做起 复用已经成功使用的架构、框架、同类经验的团队 直接使用已有的软构件,即可组装成新的系统 复用已有的功能模块,既可以 提高开发效率,也可以改善新 开发过程中带来的质量问题;折中(Trade-off) 不同的需求之间往往存在矛盾与冲突,需要通过折中来作出的合理的 取舍,找到使双方均满意的点,核心问题:如何调和矛盾(需求之间、人与人之间、供需双方之间、…);演化(Evolution) 软件系统在其生命周期中面临各种变化 核心问题:在设计软件的初期,就要充分考虑到未来可能的变化,并 采用恰当的设计决策,使软件具有适应变化的能力 即:可修改性、可维护性、可扩展性。
03软件过程模型
软件开发生命周期(Software Development Life Cycle – SDLC): From 0 to 1
Multiple versions in the life of a software: From 1 to n
软件过程
软件过程定义以下内容: – 人员与分工 – 所执行的活动 – 活动的细节和步骤
软件过程通过以下方式组织和管理软件生命周期: – 定义软件生产过程中的活动 – 定义这些活动的顺序及其关系
软件过程的目的: – 标准化(可模仿)、可预见性(降低风险)、提高开发效率、获得高质 量产品 – 提升制定时间和预算计划的能力
黑盒测试只在软件接口处进行,黑盒顾名思义,我们把测试对象看作一个黑盒子,我们无法看清里面具体是什么,只能给定输入,通过观察输出来判断是否有效。
白盒测试则是可以看见程序内部,是对于一个模块一个模块进行较为精细的测试。
软件过程的实质:在软件开发生命周期内采取特定 的方式和策略进行过程管理控制
软件过程模型就是一种开发策略,这种 策略针对软件工程的各个阶段提供了一 套范形,使工程的进展达到预期的目的
软件过程模型分类 预测型(Predictive): 提前进行大量 的计划工作,然后一次性执行;执行 是一个连续的过程。 迭代 型(Iterative): 允许对未完成的工作进行反馈,从而改进和修改该工 作。 增量型(Incremental): 向客户提供 己完成的,可能立 即使用的可交付成 果。 敏捷型(Agile): 既有迭代,也有 增 量 ,便于完善工作 ,频繁交付 。
预测型过程模型(Predictive model) – 项目开发活动通常按照固定顺序执行,前一步活动结果是后一步活 动的“蓝图”,前一步对后一步结果的预期约束十分精准 – 需要提前进行大量的计划工作,然后一次性执行,执行过程是一个 连续的过程.( 瀑布模型 (Waterfall)、V模型(V Model)、W模型(W Model)形式化过程 (Formal model))
迭代过程模型 (Iterative model) – 允许对未完成的工作进行反馈,可以进行修改和改进 – 允许对部分已经完成的工作进行反馈,从而进行修改和改进 – 逐步反馈、改进完善,直至开发完成.{ 螺旋模型 (Spiral)、原型模型 (Prototype)}
增量过程模型 (Incremental process model) – 将未来系统分阶段完成,每个阶段都 会产生一个可交付成果 – 每个阶段成果都是一个增量 – 每个增量都是一个独立的开发过程, 包括分析、设计、实现、测试、交付.{增量模型 (Incremental)、快速应用开发(RAD)}
敏捷过程模型(Agile model) – 应对变化、增量开发、快速反馈、快速迭代、快速交付 – 基于迭代的敏捷过程:每次迭代,都是针对最重要的系统功能,团 队合作开发 – 基于流程的敏捷过程:不是按照迭代计划,而是根据团队能力,领 取任务,恒速开发.{XP、Scrum、Kanban、DevOps等}
预测型过程模型(Predictive model)
瀑布模型 :将SDLC各项活动规定为按固定顺序而连接的 若干阶段工作,形如瀑布流水,最终得到软 件产品,向前一阶段回溯,很难。 上一个阶段结束,下一个阶段 才能开始 每个阶段均有里程碑和提交物 上一阶段输出是下一阶段输入 每个阶段均需要进行V&V 侧重于文档与产出物
优点——追求效率 – 简单、易懂、易用、快速 – 为项目提供了按阶段划分的检查点,项目管理比较容易 – 每个阶段必须提供文档,而且要求每个阶段的所有产品必须进行正 式、严格的技术审查 缺点——过于理想化 – 在开发早期,用户难以清楚地确定所有需求,需求的错误很难在开 发后期纠正,因此难以快速响应用户需求变更 – 开发人员与用户之间缺乏有效的沟通,开发人员的工作几乎完全依 赖规格说明文档,容易导致不能满足客户需求 – 客户必须在项目接近尾声的时候才能得到可执行的程序,对系统中 存在的重大缺陷,如果在评审之前没有被发现,将可能会造成重大 损失 适用场合: – 软件项目较小,各模块间接口定义非常清晰 – 需求在项目开始之前已经被全面的了解,产 品的定义非常稳定 – 需求在开发中不太可能发生重大改变 – 使用的技术非常成熟,团队成员都很熟悉这 些技术 – 负责各个步骤的子团队分属不同的机构或不 同的地理位置,不可能做到频繁的交流 – 外部环境的不可控因素很少
V模型 V模型是由Paul Rook在1980年提出的 V模型是瀑布模型的一种变形 V模型强调测试的重要性,将开发活动与测试活动紧密联系在一起
W模型 W模型,由Evolutif公司提出,相对于V模型,W模型增加了软件开发 各阶段中同步进行的验证和确认活动 由两个V字型模型组成,分别代表测试与开发过程,明确表示出了测试 与开发的并行关系 W模型同样强调测试的重要性,将开发活动与测试活动紧密联系在一起
V模型与W模型的优缺点 优点——开发过程重视测试/验证 – 简单易用,只要按照规定的步骤执行即可 – 强调测试或验证与开发过程的对应性和并行性; 测试方案在编码之 前就已经制定了 – 与瀑布模型相比,项目开发成功的机会更高 – 避免缺陷向下游流动 缺点 – 比瀑布模型繁琐
形式化过程模型: 使用严格的数学形式来刻画每一阶段的产物(需求、设计、程序、测试) 应用一系列形式化方法在各阶段的产物之间进行自动/半自动的转换
形式化过程模型 优点: – 应用数学分析方法,歧义性、不完整性、不一致性等问题更容易被 发现和改正,目的是“提供无缺陷的软件” 缺陷: – 形式化数学方法难以理解,可视性太差,对开发人员技能要求较高 – 构造形式化模型是一件非常耗时的工作,成本也很高 – 软件系统中的某些方面难以用形式化模型表达出来(如用户界面) 应用场合: – 对可靠性和安全性要求较高的一些关键系统,在真正被投入使用之 前,需要严格保证100%的正确;传统的方法靠人去验证,难以奏效 ——太过于理想化,因此仅停留在理论研究中,实践中很少使用
增量过程模型
增量过程模型 在很多情况下,由于初始需求的不明确,开发过程不宜采用瀑布模型 等预测性模型 因此,无须等到所有需求都出来才进行开发,只要某个需求的核心部 分出来,即可进行开发 另外,可能迫切需要为用户迅速提供一套功能有限的软件产品,然后 在后续版本中再细化和扩展功能 在这种情况下,需要选用增量方式的软件过程模型 – 增量模型 – RAD模型
增量模型 软件被作为一系列的增量来设计、实现、集成和测试,每一个增量是 由多个相互作用的模块所形成的特定功能模块 本质:以迭代的方式运用瀑布模型 – 第一个增量往往是核心产品:满足了基本的需求,但是缺少附加的 特性 – 客户使用上一个增量的提交物并进行自我评价,制定下一个增量计 划,说明需要增加的特性和功能 – 重复上述过程,直到最终产品产生为
增量模型优点: – 在时间要求较高的情况下交付产品:在各个阶段并不交付一个可运 行的完整产品,而是交付满足客户需求的一个子集的可运行产品, 对客户起到“镇静剂”的作用 – 人员分配灵活:如果找不到足够的开发人员,可采用增量模型:早 期的增量由少量人员实现,如果客户反响较好,则在下一个增量中 投入更多的人力 – 逐步增加产品功能可以使用户有较充裕的时间来学习和适应新产品, 避免全新软件可能带来的冲击 – 因为具有较高优先权的模块被首先交付,而后面的增量也不断被集 成进来,这使得最重要的功能肯定接受了最多的测试,从而使得项 目总体性失败的风险比较低
增量模型困难: – 每个附加的增量并入现有软件时,必须不破坏原来已构造好的部分 – 同时,加入新增量时应简单、方便 ——该类软件的体系结构应当是 开放的 – 仍然无法处理需求发生变更的情况 – 管理人员必须有足够的技术能力来协调好各增量之间的关系
RAD模型 快速应用开发RAD (Rapid Application Development) – 侧重于短开发周期(一般为60~90天)的增量过程模型,是瀑布模型 的高速变体,通过基于构件的构建方法实现快速开发 – 多个团队并行进行开发,但启动时间有先后,先启动团队的提交物 将作为后启动团队的输入 缺点: – 需要大量的人力资源来创建多个相对独立的RAD团队 – 如果没有在短时间内为急速完成整个系统做好准备,RAD项目将会 失败 – 如果系统不能被合理的模块化,RAD将会带来很多问题 – 技术风险很高的情况下(采用很多新技术、软件需与其他已有软件 建立集成等等),不宜采用RAD
迭代过程模型 (Iterative model)
迭代过程模型 软件开发过程面临的客观情况: – 软件系统会随着时间的推移而发生变化,在开发过程中,需求经常发生变 化,直接导致产品难以实现 – 严格的交付时间使得开发团队不可能圆满完成软件产品,但是必须交付功能 有限的版本以应对竞争或压力 – 很好的理解核心产品与系统需求,但对其他扩展的细节问题却没有定义 在上述情况下,需要一种专门应对不断演变的软件过程模型,即“迭代 过程模型” 本质:循环、反复、不断调整当前系统以适应需求变化 主要包括两种形态: – 快速原型法 – 螺旋模型
快速原型法的步骤 :Step 1:双方通过沟通,明确已知的需求,并大致勾画出以后再进一步 定义的东西 Step 2:迅速策划一个原型开发迭代并进行建模,主要集中于那些最终用户所能够看到的内容,如人机接口布局或者输出显示格式等 Step 3:快速设计产生原型,对原型进行部署,由客户和用户进行评价 Step 4:根据反馈,进一步细化需求并调整原型 Step 5:原型系统不断调整以逼近用户需求
“原型”的类型 Throwaway prototyping(抛弃式原型) 【例子】 – 最初的原型在完成并得到用户认可之后,将不会作为交付给用户的 最终系统的一部分,而是被抛弃,其目的只是为了收集与验证需求 – 该类原型可能是不可执行的(例如,只包含用户界面) Evolutionary prototyping(演化式原型) 【例子1】 【例子2】 【例子3】 – 最初构造的原型将具备较高的质量,包含了系统的核心功能,然后 通过收集需求对其进行不断的改善和精化 – 该类原型是可执行的,将成为最终系统的一部分
快速原型法的优缺点 优点: – 提高和改善客户/用户的参与程度,最大程度的响应用户需求的变化 – 克服预测型模型的缺点,减少由于需求不够明确带来的开发风险 缺点: – 为了尽快完成原型,开发者没有考虑整体软件的质量和长期的可维 护性,系统结构通常较差 – 可能混淆原型系统与最终系统,原型系统在完全满足用户需求之后 可能会被直接交付给客户使用 – 额外的开发费用
**螺旋式过程模型:**与增量、RAD等的最大 区别在于重视风险评估
螺旋模型沿着螺线旋转,在四个象限内表达四个方面的活动: – 制定计划:确定软件目标,选定实施方案,弄清项目开发的限制 – 风险分析:分析所选方案,考虑如何识别和消除风险 – 实施工程:实施软件开发 – 客户评估:评价开发工作,提出修正建议 举例: – 第1圈:开发出产品的规格说明 – 第2圈:开发产品的原型系统 – 第3~n圈:不断的迭代,开发不同的软件版本 – 根据每圈交付后用户的反馈来调整预算、进度、需要迭代的次数
**出发点:**开发过程中及时识别和分析风险,并采取适当措施以消除或 减少风险带来的危害 优点:结合了原型的迭代性质与瀑布模型的系统性和可控性,是一种 风险驱动型的过程模型: – 采用循环的方式逐步加深系统定义和实现的深度,同时更好的理解、 应对和降低风险 – 确定一系列里程碑,确保各方都得到可行的系统解决方案 – 始终保持可操作性,直到软件生命周期的结束 – 由风险驱动,支持现有软件的复用 缺陷: – 适用于大规模软件项目,特别是内部项目,周期长、成本高 – 软件开发人员应该擅
迭代过程模型的目的: – 需求的变更频繁,要求在非常短的期限内实现,以充分满足客户/用 户要求、及时投入市场 存在的问题: – 由于构建产品所需的周期数不确定,给项目管理带来困难 – 迭代速度太快,项目陷入混乱;迭代速度太慢,影响生产率 – 为追求软件的高质量而牺牲了开发速度、灵活性和可扩展性
其他过程模型
面向复用的软件过程 该过程模型的主要思想是复用(Reuse) 针对一个新的软件系统,不是完全从一无所有开始入手,而是通过使 用已有的软件单元(称为“软构件”)来构造系统 主要过程: – 需求分析 – 体系结构设计 – 构件获取(购买、重新开发) – 构件修改与测试 – 构件组装 – 集成测试
敏捷过程模型(Agile model)
• XP、Scrum
04 敏捷方法与过程
敏捷方法与过程本质:以快速的增量和 迭代方式进行软件开发
敏捷开发:快速交付、快速反馈
敏捷过程中最重要的因素:人
极限编程XP (eXtreme Programming)
极限编程(XP):一种广泛应用的敏捷开发方法
XP Planning:计划阶段 倾听客户陈述,形成一组“用户故事(User Stories)” ,描述其输出、 特性、功能等 按照价值或风险排序:客户为每个用户故事指定优先级(Priority) XP团队评估各个用户故事,为其指定成本(Cost, 开发周数),若超过3 周,则拆分 将若干个用户故事指定为下一次发布的增量,确定发布日期: – 所有用户故事 – 优先级高的用户故事 – 风险高的用户故事 规划整体进度(project velocity):以怎样的速度开展项目 客户可以在开发过程中扩展新故事、去除原有故事、改变优先级、拆 分等
XP Design:设计阶段 遵循KIS原则(Keep It Simple) 设计模型:面向对象方法,CRC卡片(Class-Responsibility-Collaborator) 遇到困难问题,创建“Spike Solutions”(探针原型) 对设计方案不断重构(Refactoring) – 遵循用户故事的外特性要求 – 改善内部结构 – 消除bug – 提高效率 – 提高易读性
**XP Coding & Testing:**编码与测试阶段 XP Coding – 在编码之前,根据用户故事设计单元测试用例 – 结对编程(Pair programming):两人一起编程,实时讨论、实时评审 – 测试驱动的开发(TDD):先写测试用例,再写代码 XP Testing – 自动化单元测试(Unit test) – 持续集成(Continuous Integration) – 持续进行回归测试(Regression test) – 验收测试(Acceptance test)
Pair Programming:结对编程 两个程序员肩并肩地、平等地、互补地进行开发工作 驾驶员(Driver):控制键盘输入的人 – 写设计文档,进行编码和单元测试等XP开发流程 领航员(Navigator):起到领航、提醒的作用 – 审阅驾驶员的文档、驾驶员对编码等开发流程的执行;考虑单元测 试的覆盖程度;是否需要和如何重构;帮助驾驶员解决具体的技术 问题 驾驶员和领航员不断轮换角色,不宜连续工作超过一小时;领航员要 控制时间 主动参与:任何一个任务都首先是两个人的责任,也是所有人的责任; 没有“我的代码/你的代码/他的代码”,只有“我们的代码” 只有水平上的差距,没有级别上的差异:尽管可能大家的级别资历不 同,但不管在分析、设计或编码上,双方都拥有平等的决策权利
**为何称为“极限”编程?**了解客户的需求很重要 (每时每刻都有客户在身边,时时了解需求) ;测试/单元测试能帮助提高质量 (那就先写单元测试,从测试开始写程序—TDD );代码复审可以找到错误 (从一开始就处于“复审”状态——结对编程 );计划没有变化快() 那就别做详细的设计,做频繁的增量开发,重构和 频繁地发布)
关于XP的一些反对意见: Requirements volatility(需求波动) Conflicting customer needs(客户需求冲突) Requirements are expressed informally(需求非正规表达) Lack of formal design(缺乏形式化设计)
敏捷过程模型的典型代表:Scrum Scrum – 一个敏捷开发框架:增量/迭代的开发过程 – 1990年代初,Ken Schwaber在其公司使用了一种开发方法Advanced Development Methods(先进开发方法),在90年代中期进一步完善 和实践,取名自橄榄球比赛中的术语“争球”(Scrum) – 整个开发过程由若干个短的迭代周期组成,一个短的迭代周期称为一 个Sprint,每个Sprint的建议长度是1-4周 – 使用产品Backlog来管理需求,是一个按照商业价值排序的需求列表, 列表条目的体现形式通常为用户故事 – 总是先开发对客户具有较高价值的需求 – 在Sprint中,Scrum团队从产品Backlog中挑选最高优先级的需求进行 开发;挑选的需求在Sprint计划会议上经过讨论、分析和估算得到相 应的任务列表(Sprint backlog) – 在每个迭代结束时,Scrum团队将提交潜在可交付的产品增量
Scrum的基本过程:
① Product Owner组织会议将计划开发的产品分解成若干开发项(Product Backlog),该列表是有优先级的;该表中的开发项在没有被开发前是可以新增 或删除的(引入需求变更)
② Product Backlog中的一个或几个任务项,是一次Scrum Sprint(Scrum冲 刺)要开发的任务;1个Sprint一般为2-4周;一旦Sprint启动,在开发完成前是 不允许变更需求的
③ 在Sprint开始前,Scrum Master组织Scrum Team会议将Sprint的任务分解 为更小的开发单元(Sprint Tasks,列在Sprint Backlog);Scrum Team成员的开 发任务单元就是每个Task
④ Sprint启动后,每天需要召开一次会议(Daily Scrum Meeting),一般不超 过15分钟,每人简短陈述3句话:上次Scrum例会后做了什么?遇到了什么问题? 下次Scrum例会前计划做什么?(注意:提出的问题在例会上不做任何讨论)
⑤ Sprint结束后,展示产品新功能;并做Sprint评审和回顾,即Sprint Review Meeting和Sprint Retrospective Meeting 上述Sprint过程循环进行,直到Product Backlog列表空了为止
Scrum的3人、4表、5会、6事 人 – 3种角色: – Product Owner(产品拥有者/产品负责人) – Scrum Master(Scrum主持人) – Scrum Team(Scrum团队成员,一般5-10人) 表 – 4种列表: – Product Backlog(产品任务列表) – Sprint Backlog(冲刺任务列表) – Task Board(任务墙) – Burn down/up Charts(燃尽图) 会 – 5种会议: – 产品计划发布会(产出Product Backlog列表) – 冲刺计划会议(产出Sprint Backlog列表) – 每日站会(督促激励个体工作) – 冲刺结束前的评审会(展示产品新功能) – 冲刺结束后的回顾会(总结冲刺过程的经验教训) 事 – 6种活动: – Sprint(冲刺)+5种会议
Scrum中的三种角色 Product Owner(产品负责人):确定产品的功能,负责维护产品 Backlog、deadline、priority、ROI(投资回报率);验收结果 Scrum Master(团队leader):保证开发过程按计划进行;组织每日 站会、Sprint计划会议、Sprint评审会议和Sprint回顾会议;通过外在/ 内在协调,确保团队资源完全可被利用并且全部是高产出的 Scrum Team(Scrum团队):在每个Sprint中将产品Backlog中的条目 转化成为潜在可交付的功能增量;规模在5-10人;具备交付产品增量 所需要的各种技能
Scrum中的六项活动 Sprint (冲刺):代表一个2-4周的迭代 发布计划会议(Release Planning Meeting) ➡Product Backlog Sprint计划会议(Sprint Planning Meeting)➡ Sprint Backlog 每日站会(Daily Scrum Meeting) Sprint评审会(Sprint Review Meeting) Sprint回顾会议(Sprint Retrospective Meeting)
XP 与 Scrum的明显区别
编号 | 区别点 | XP | Scrum |
---|---|---|---|
1 | 迭代周期长度 | 1-2周 | 1-4周 |
2 | 迭代中需求变化 | 允许 | 不允许 |
3 | 迭代选取的用户故事优先级 | 严格按照优先 级来开发 | 根据具体情况 允许跳跃选取 |
4 | 迭代过程控制 | 严格控制,必 须TDD、配对 编程等 | 比较随意 |
一句话归纳各类过程模型
瀑布模型:将全部需求以整体方式向前推进,无迭代 —— 基本模型
增量模型:将需求分成多份,串行推进,无迭代 —— 串行的瀑布
RAD模型:将需求分成多份,可并行推进,无迭代 —— 并行的瀑布
原型模型:始终结果可见,不断迭代修正原型,直到开发完成 —— 基本模型
螺旋模型:按瀑布阶段划分,各阶段分别迭代(原型+风险分析) —— 原型+瀑布
敏捷模型:将需求分成尽量小的碎片,以碎片为单位进行高速迭代 —— 增量+迭代+原型
05 软件项目管理
5.1软件项目管理-概述
基本概念
项目(Project) :为创建某种特定的产品或服务而组织或设计的临时的、 一次性的行动,通过执行一组活动,使用受约束的资源(资金、人、原 料、能源、空间等)来满足预定义的目标
项目管理(Project Management, PM):有效的组织与管理各类资源(资 金、人、原料、能源、空间等),以使项目能够在预定的范围、质量、 时间和成本等约束条件下顺利交付(deliver)
软件项目管理(Software Project Management):为了使软件项目能够 按照预定的成本、进度、质量顺利完成,而对人员(People)、产品 (Product)、过程(Process)和项目(Project)进行分析和管理的活动。
软件项目管理的根本目的是为了让软件项目尤其是大型项目的整个软件生 命周期(从分析、设计、编码到测试、维护全过程)都能在管理者的控制之下, 以预定成本按期,按质的完成软件交付用户使用。 – 挑战1:在各类约束条件下交付项目 – 挑战2:通过优化资源的分配与集成来满足预先定义的目标
软件项目管理的“4P”:人员(People)、产品 (Product)、过程(Process)和项目(Project)
软件项目的参与人员: 高级管理者:负责定义业务问题 项目(技术)管理者:计划、激励、组织和控制软件开发人员 开发人员:拥有开发软件所需技能的人员 – 系统分析员、系统架构师、设计师、程序员、测试人员、 质量保证人员、… **客户:**进行投资、详细描述待开发软件需求、关心项目成败 的组织/人员 最终用户:一旦软件发布成为产品,最终用户就是直接使用 软件的人
软件产品、产品分解结构(PBS) 首先应确定软件范围: – 功能和非功能(性能、可用性、安全、法律等) – 软件范围应是确定的:在管理层和技术层都必须是无歧义的和可理 解的 一旦确定了范围,需要对其进行分解——分而治之 项目管理通常使用“产品分解结构(Product Breakdown Structure, PBS)”作为产品分解的工具: – PBS:通过分层的树型结构来定义和组织项目范围内的所有产出物 (产品),自顶向下,逐级细分 – 产出物:项目结束时需要提交的最终产品,在项目之初就可以准确 预计
软件过程 Step 1: 选择合适的软件过程模型 – 存在多种过程模型 – 各过程模型适用不同类型的软件项目 Step 2: 根据所选的过程模型,对其进行适应性修改 Step 3: 确定过程中应包含的工作任务列表
工作分解结构(WBS) 项目管理里通常使用“**工作结构分解 (Work Breakdown Structure, WBS)”**作 为过程分解的工具 WBS:通过分层的树型结构来定义和组 织工作任务之间的分解关系,自顶向下, 逐级细分
项目 项目关注的四个方面 – 范围(Scope) – 时间(Time) – 成本(Cost) – 质量(Quality) 项目管理的主要任务 – 项目可行性分析与估算 – 项目进度安排 – 项目风险管理 – 项目质量管理 – 项目跟踪与控制
W5HH原则 Why 为什么要开发这个系统? What 将要做什么? When 什么时候做? Who 某功能由谁来做? Where 他们的机构组织位于何处? How 如何完成技术与管理工作? How much 各种资源分别需要多少?
可行性分析与估算
在项目开始之前,必须预先估计三件事情: – 需要多少工作量 – 需要多少时间 – 需要多少人员
此外,还必须预测所需要的资源(硬件和软件)以及蕴含的风险
从而得出“该项目是否可行”的结论
确定范围 范围(Scope):描述将要交付给最终用户的功能和特性、输入输出数据、 用户界面、系统的性能、约束条件、接口和可靠性等,以及期望的时 间、成本目标 两种方法: – 与所有项目成员交流之后,写出对软件范围的叙述性描述 – 由最终用户给出一组用例 注意: – 并不是客户所有的需求都“来者不拒”,需要分别对待 – 用户签字确认
Needs:客户/最终用户的请求、想法和业务需求 Requirements:对未来系统所应具备的功能的陈述 Exclusions:将不包含在未来系统中的功能的陈述 Baseline:对未来系统中应包含的功能的陈述
可行性分析 技术可行性: – 项目在技术上可行吗?它在技术水平范围内吗?能够将缺陷减少到 一定程度吗? 经济可行性: – 它在经济上可行吗?能以可负担的成本完成开发吗? 时间可行性: – 项目投入市场的时间可以按预期完成吗? 资源可行性: – 组织拥有取得成功所需要的资源吗?
软件项目估算:– 代码行估算法 – 功能点估算法 – 用例点估算法 – 类比估算法
绘制任务进度安排图 项目管理里通常采用甘特图(Gantt Chart)来描述任务的进度安排
资源、产出与里程碑: 将资源(resources)分配给任务 – 资金 – 人员 – 设备 – 环境 明确产出结果(outcomes) – 每一项任务的产出结果是什么?对应于PBS中的哪一部分? 明确里程碑(milestones) – 项目的关键产出物,标志着某一阶段的完成
项目进度跟踪 项目进度表只是提供了一张进度路线图,在实际执行过程中,需要定 期对其进行跟踪和控制,以决定是否需要对进度计划进行调整
5.2 成本估算
估算过程 :规模估算➡ 工作量估算➡ 成本估算
软件规模度量单位: LOC(Lines of Code) 代码行:用源代码长度的测量 FP(Function Points) 功能点:用系统的功能点数量来测量 UCP(Use Case Points) 用例点:用系统的用例点数量来测量
软件工作量度量单位: 人天/人周/人月/人年 开发团队每个人工作天数/周数/月数/年数的累计数
软件成本度量单位:RMB(元或万元),$(元或万元),等等
传统估算方法-代码行估算法:从软件程序量的角度定义项目规模
主要优点:代码是所有软件开发项目都有的“产品”,而且很容易 计算代码行数
主要缺点:1.对代码行没有公认的可接受的标准定义 2.代码行数量依赖于所用的编程语言和个人的编程风格 3.在项目早期,需求不稳定、设计不成熟、实现不确定 的情况下很难准确地估算代码量 4.代码行强调编码的工作量,只是项目实现阶段的一部 分,其他阶段无代码产生
功能点估算
传统估算方法-功能点估算: 与实现的语言和技术没有关系 用系统的功能数量来测量其规模 通过评估、加权、量化得出功能点 估算软件规模,即软件规模度量单位
功能点公式 :FP = UFC × TCF 其中:FP – Function Points 功能点 UFC – Unadjusted Function Component 未调整的功能点计数) TCF – Technical Complexity Factor 技术复杂度因子
UFC-未调整的功能点计数项: 不同类型的系统功能,其开发复杂度(TCF)是不同的 针对未来系统,需要划分一个“系统边界” Albrecht将功能点计数项分为上图所示5大类 根据经验,一般来说:TCFILF>TCFEIF>TCFEO>TCFEI ≈ TCFEQ
功能计数项:外部输入 EI ;外部查询 EQ ;内部逻辑文件 ILF ;外部接口文件 EIF ;外部输出 EO
外部输入(External Inputs: EI) : 给软件提供面向应用的数据的项(如UI窗口、输入表单、 对话框、控件,输入数据文件等) 在这个过程中,数据穿越外部边界进入到系统内部
外部输出(External Outputs EO) : 向用户提供(经过处理的)面向应用的信息 例如:报表和出错信息等
外部查询(External Query EQ) : 外部查询是一个输入引出一个即时的简单输出 没有处理过程,即不会产生任何新的数据
外部接口文件(External Interface Files EIF): 外部接口文件是用户可以识别的一组逻辑相关数据 这组数据只能被引用 用这些接口把信息传送给外部系统,或从外部系统取回接口 信息
内部逻辑文件(Internal Logical Files: ILF): 用户可以识别的一组逻辑相关的数据,而且完全存在于应用 的边界之内 通过外部输入进行改变,在系统内部进行维护的数据 例如:数据库表、数据结构等
未调整功能点UFC的计数项复杂度定级标准 前述表合并得到各类型功能计数项复杂度级别与系数取值表 数值为功能点计数项对UFC(未调整功能点)计算的功能复 杂度加权系数
软件项目技术复杂度TCF因子及取值标准 未来系统的各种特性,决定了开发的技术复杂度 IFPUG制定了技术复杂度TCF的系统特性及取值标准
1.计算“未调整的功能点UFC” 方法:查表【各类型功能计数项复杂度 级别与系数取值表】,用已知的功能计 数项个数×复杂度系数,最后累加
2.计算“项目技术复杂度TCF” 方法:对照【技术复杂度因子通用特性 表】,逐一分析对本例的影响情况,确 定影响系数Fi
给出了TCF计算公式: TCF = 0.65 + 0.01 × ∑i=1 to 14 Fi 其中Fi取值范围[0, 5],显然TCF的计算结果范围[0.65, 1.35]
3.计算“项目功能点FP” :FP = UFC×TCF
4.计算项目工作量 Effort = FP × PE
用例点估算
用例点估算方法的基本步骤:1. 计算未调整的角色权值UAW 2. 计算未调整的用例权值UUCW 3. 计算未调整的用例点UUCP 4. 计算技术复杂度因子TCF 5. 计算环境复杂度因子ECF 6. 计算调整的用例点UCP 7. 计算工作量Effort
1.计算未调整的角色权值UAW:UAW = ∑C=c aWeight©×aCardinality©
C ={simple, average, complex} aWeight© – actor Weight:复杂度级别c的角色权值; aCardinality© – actor Cardinality:复杂度级别c的角色基数
2.计算未调整的用例权值UUCW:UUCW = ∑C=c uWeight©×uCardinality©
C ={simple, average, complex} uWeight© – use case Weight 复杂度级别c的用例权值 ;uCardinality© – use case Cardinality 复杂度级别c的用例基数
3.计算未调整的用例点UUCP:UUCP = UAW + UUCW
4.计算技术复杂度因子TCF:TCF = 0.6 + ( 0.01×∑i=1 to 13 TCF_Weighti×Valuei )
5.计算环境复杂度因子ECF:ECF = 1.4 + ( -0.03×∑i=1 to 8 ECF_Weighti×Valuei )
**6.计算调整的用例点UCP:**根据(1)未调整的用例点UUCP、(2)技术复杂度因子TCF、(3)环 境复杂度因子ECF,可以计算出调整的用例点UCP UCP = UUCP × TCF × ECF
7.计算工作量:Effort = UCP × PE
三点估算法
基于任务成本的3种估算值(即最有可能成本、最乐观成 本、最悲观成本)来加权平均计算预期成本的方法
三点估算法 – 三种估算值 CM:Most possible Cost,最可能成本,比较现实的估算成本 CO:Optimistic Cost,最乐观成本,最好情况预期所得到的估 算成本 CP:Pessimistic Cost,最悲观成本,最差情况预期所得到的估 算成本 CE=f(CO,CM,CP) CE即Expected Cost,预期成本,通过CO、CM、CP来计
三点估算结果 (1)三角分布: CE = ( CO + CM + CP) / 3 (2)贝塔分布: CE = ( CO + 4 CM + CP) / 6
专家估算法 – Delphi专家估算法
\1. 组织者确定一批专家,规定:这些专家互相不见面 2. 组织者发给每位专家一份软件规格说明(重点WBS)以及估 算值记录表 3. 每位专家认真研究软件规格说明书,以无记名方式对该软件 给出3个规模的估算值:最小值ai、最可能值mi、最大值bi 4. 组织者整理并计算每位专家估算的结果: Ei = ( ai + 4mi + bi ) / 6 【贝塔分布算法】 5. 最终可以获得一个多数专家共识的软件规模: E = (E1 + E2 + … + En) / n 【n - 专家数量】 6. 如果各个专家的估算差异超出规定的范围(例如:15%), 则需重复上述过程
5.3 进度计划
关键路径法估计: 确定项目网络图 每个任务有单一的历时估算 确定网络图中任务的逻辑关系 关键路径是网络图中最长的路径 关键路径可以确定项目完成时间
项目进度管理图示:网络图PDM(Precedence Diagramming Method优先图法/节点法/单代号 网络图) 构成PDM网络图的基本特点是节点(Box) 节点(Box)表示活动(任务) 用箭线表示各活动(任务)之间的逻辑关系. 可以方便的表示活动之间的各种逻辑关系
网络图ADM( Arrow Diagramming Method箭线法/双代号网络图 ) ADM也称为双代号项目网络图, 在ADM网络图中,箭线表示活动(任务) 两个代号唯一确定一个任务 代号表示前一任务的结束,同时也表示后一任务的开始
虚活动 为了定义活动 为了表示逻辑关系 不消耗资源的
**项目进度计划编排:** 超前(Lead)与滞后(Lag) 关键路径法 时间压缩法 资源优化
项目进度计划编排:关键路径法(CPM,Critical Path Method)
项目进度计划编排:针对项目开发中的所有活动进行合理的时间安排 其核心对象是“任务”,以及与其息息相关的任务间关系网络、任务 历时估计、资源需求、相关责任人、其他假设条件等。
关于“任务/活动”属性的基本概念 : 活动名称(Task)、历时时间(Duration) 最早开始时间(Early Start,ES) 最晚开始时间(Late Start,LS) 最早完成时间(Early Finish,EF) 最晚完成时间(Late Finish,LF) 总浮动时间(Total Float,TF) 自由浮动时间(Free Float,FF) 调整超前量(lead)、调整滞后量(lag) 前置活动(Predecessor,p)、后置活动(Successor,s)
浮动时间(Float):是一个任务/活动的机动性时间,它是一个任务 /活动在不影响其它任务/活动或者项目完成的情况下可以延迟的时 间量
总浮动时间(Total Float,TF):在不影响项目最早完成时间的前 提下,一个任务/活动可以延迟的时间
自由浮动时间(Free Float,FF):在不影响后置任务/活动最早开 始时间的前提下,一个任务/活动可以延迟的时间
关键路径(Critical Path ):在一个项目中表达任务/活动关系的网络图(PDM、ADM)中: 网络图中时间最长的路径称为“关键路径” 关键路径是决定项目完成的最短时间 时间浮动为0(Float=0)的路径 关键路径上任何活动延迟,都会导致整个项目完成时间的延迟 关键路径可能不止一条(长度一定一样!)
正推法(Forward pass):按照时间顺序计算网络图中每个活动的最早 开始时间ES和最早完成时间EF,从而找到关键路径的方法
**逆推法(Forward pass):**按照时间顺序计算网络图中每个活动的最晚 开始时间LS和最晚完成时间LF,从而找到关键路径的方法
06 软件演化与配置管理
软件演化的Lehman定律
持续变化(continuing change) – 现实世界的系统要么变得越来越没有价值,要么进行持续不断的变 化以适应环境的变化 – 环境变化产生软件修改,软件修改又继续促进环境变化
复杂度逐渐增大(increasing complexity) – 当系统逐渐发生变化时,其结构和功能将变得越来越复杂,并逐渐 难以维护并失去控制,直至无法继续演化,从而需要大量额外的资 源和维护工作来保持系统的正常运行 – 软件修改会引入新的错误,造成故障率的升高
软件演化的处理策略
软件维护(Software Maintenance) – 为了修改软件缺陷或增加新的功能而对软件进行的变更 – 软件变更通常发生在局部,不会改变整个结构
软件再工程(Software Re-engineering) – 为了避免软件退化而对软件的一部分进行重新设计、编码和测试, 提高软件的可维护性和可靠性等
前者比后者的力度要小
软件维护 – (ANSI/IEEE) :在软件产品发行和投入 运行使用之后对其的修改,以改正错 误,改善性能或其他属性,从而使产 品适应新的环境或新的需求
软件维护的类型 纠错性维护:修改软件中的缺陷或不足 适应性维护:修改软件使其适应不同的操作环境,包括硬件变化、操 作系统变化或者其他支持软件变化等 完善性维护:增加或修改系统的功能,使其适应业务的变化 预防性维护:为减少或避免以后可能需要的前三类维护而提前对软件 进行的修改工作
实践表明,在几种维护活动中,完善性维护所占的比重最大,即大部 分维护工作是改变和加强软件,而不是纠错
软件配置
软件配置(software configuration):由在软件工程过程中产生的所有信 息项构成,它可以看作该软件的具体形态(软件配置项)在某一时刻的 瞬间映像
软件配置管理(Software Configuration Management, SCM)
软件配置管理的目标 目标: – 标识变更 – 控制变更 – 确保变更的正确实现 – 向开发组织内各角色报告变更 总结:当变更发生时,能够提高适应变更的容易程度,并且能够减少 所花费的工作量
SCM的基本元素 : 配置项(Configuration Item, CI) 基线(Baseline) 配置管理数据库(CMDB) 最终硬件库(Definitive Hardware Store, DHS) 最终软件库(Definitive Software Library, DSL)
持续集成
持续集成:敏捷开发的一项重要实践– Martin Fowler:团队开发成员经常集成他们的工作,每个成员每天 至少集成一次,每天可能会发生多次集成;每次集成都通过自动化 的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集 成错误,大大减少集成的问题,让团队能够更快的开发内聚的软件
价值: – 减少风险:不是等到最后再做集成测试,而是每天都做 – 减少重复过程:通过自动化来实现 – 任何时间、任何地点生成可部署的软件 – 增强项目的可见性 – 建立团队对开发产品的信心