构建之法——现代软件工程 阅读笔记

本篇博文为本人阅读软件工程教材的个人笔记记录,因为是泛读所以只记录关键字以及本人认为书本上的重要理论,知识点也不够精确,请谨慎参考。

后面几篇内容还没有整理完,后续整理了再更新。

内容摘录自《构建之法——现代软件工程》第三版,邹欣,人民邮电出版社。邹欣老师的课程博客为https://www.cnblogs.com/xinz/archive/2011/11/27/2265425.html

第1章 概论

1.1 软件 = 程序 + 软件工程

软件 = 程序 + 软件工程

程序 = 数据结构 + 算法

软件企业 = 软件 + 商业模式

软件:需求,功能,服务质量(维护)

软件架构,实现与设计,文件描述依赖关系、编译参数、连接参数等

软件工程的核心:构建管理,源代码管理,软件设计, 软件测试,项目管理

需求分析

源代码管理 / 配置管理:适应不同操作系统环境

质量保障

软件测试

程序理解

软件维护 / 服务运营——用户体验

除了程序之外,软件工程决定了软件的命运

软件开发的不同阶段

玩具阶段

业余爱好阶段

探索阶段

成熟的产业阶段

1.2 软件工程是什么

软件工程是把系统的, 有序的, 可量化的方法应用到软件的开发, 运营, 和维护上的过程

软件工程包括下列领域: 软件需求分析, 软件设计, 软件构建, 软件测试, 和软件维护

软件开发流程:相关的技术和过程统一到一个体系

目的:提高软件开发, 运营, 维护的效率,以及用户满意度, 可靠性,和软件的可维护性

软件的特殊性

软件分类:系统软件、应用软件、恶意软件

  1. 复杂性

  2. 不可见性(源码)

  3. 易变性(相对硬件)

  4. 服从性(队硬件、用户、行业系统有要求)

  5. 非连续性(输入到输出,变化不连续)

软件工程与计算机科学的关系

形式上证明的, 多属于计算机科学

人的行为相关, 和计算机系统的具体实现相关, 则属于软件工程

软件工程的知识领域
软件工程的目标:足够好的软件

好软件 == 没有bug

bug:软件的行为和用户的期望值不一样

bug 的多少可以直接衡量一个软件的开发效率, 用户满意度, 可靠性, 和可维护性。例如:

软件的开发效率 – 开发过程中bug 太多了, 导致软件无法按时交付;

用户满意度 – 用户使用时报告了很多bug, 纷纷表示对生活影响很大;

可靠性 – 这个软件经常会崩溃,这个操作系统会死机;

可维护性 – 这个软件太难维护了, 按下葫芦起了瓢, 修复了一个问题, 另一个问题又出来了。也没有足够的文档, 维护人员纷纷表示要把原作者找出来打一顿。

开发目标:

  1. 研发出符合用户需求的软件

  2. 通过一定的软件流程,在预计时间内发布“足够好”的软件——时间积累

  3. 能证明开发的软件是可以维护和继续发展的——文档

第2章 个人技术和流程

2.3 个人开发流程

职业成长– Personal Software Process PSP

计划

· 明确需求和其他因素,估计以下的各个任务需要多少时间

开发

· 分析需求

· 生成设计文档

· 设计复审 (和同事审核设计文档)

· 代码规范 (为目前的开发制定合适的规范)

· 具体设计

· 具体编码

· 代码复审

· 测试(包括自我测试,修改代码,提交修改)

记录时间花费

测试报告

计算工作量

事后总结

提出过程改进计划

2.1 单元测试

VSTS

(1)设置数据(一个假想的正确的E-mail地址);

(2)使用被测试类型的功能(用E-mail地址来创建一个User类的实体);

(3)比较实际结果和预期的结果(Assert.IsTrue(target!= null);)。

写规格说明书(specification)的时候,要越详细越好,最好你的各项要求都可以表达成单元测试的一个测试用例。

好的单元测试的标准

在最低的功能/参数上验证程序的正确性

从面向对象的设计原理出发,系统中最基本的功能点也应该由一个类及其方法来表现

要测试API中的每一个方法及每一个参数

单元测试必须由最熟悉代码的人(程序的作者)来写

最好是在设计的时候就写好单元测试,这样单元测试就能体现API的语义

单元测试过后,机器状态保持不变

应该在Teardown阶段把临时的文件或目录删除

单元测试要快(一个测试运行时间是几秒钟,而不是几分钟)

在测试组中可以分类,如数据库层次、网络通信层次、客户逻辑层次和用户界面层次,可以分类运行测试,

单元测试应该产生可重复、一致的结果

不要用随机数作单眼测试——无法复现

还是要用随机数等办法“增加测试的真实性”,但是不是在单元测试中

单元测试不能解决所有问题,所以也不必期望它会发现所有的缺陷

独立性——单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据,以保持单元测试的独立性。

一般情况下,单元测试中的模块可以直接引用其他的模块

如果其他的模块很不稳定 / 运行比较费时 / 不起关键的作用,可以人为地构造数据以保证这个单元测试的独立性。

单元测试应该覆盖所有代码路径,包括错误处理路径,为了保证单元测试的代码覆盖率,单元测试必须测试公开的和私有的函数/方法。

代码路径:函数、语句、分支、条件 都覆盖

100%的代码覆盖率并不等同于100%的正确性:

a) 代码中并没有处理错误情况。 例如代码打开了文件,但是并没有处理一些异常情况,例如文件不存在,权限有问题,等等

b) 代码中有效能问题,虽然代码执行了,并且也正确地返回了。但是代码执行得也许非常慢。

c) 多线程环境中的同步问题, 这个问题和本地代码执行与否关系不大。

d) 其它和外部条件相关的问题 (例如和设备相关,和网络相关的问题)

单元测试应该集成到自动测试的框架中。

单元测试必须和产品代码一起保存和维护

回归测试

回归:回归到以前不正常的状态

一个模块或功能以前是正常工作的,但在新的构建中出了问题,那这个模块就出现了一个“退步”(Regression),从正常工作的稳定状态退化到不正常工作的不稳定状态。

针对一个Bug Fix, 我们也要作Regression Test。

(1)验证新的代码的确把缺陷改正了。

(2)同时要验证新的代码没有把模块的现有功能破坏,没有Regression。

自动化

单元测试是回归测试的基础

2.2 效能分析工具

两种性能分析方法:

  1. 抽样(Sampling)

    程序运行时,不时查看程序运行在哪一个函数内

    得出关于程序运行时间分布的大致的印象

    优点:不需要改动程序,运行较快,可以很快地找到瓶颈

    缺点:不能得出精确的数据,代码中的调用关系(CallTree)也不能准确表示

  1. 代码注入(Instrumentation)

    将检测的代码加入到每一个函数中

    优点:数据可以被精准地测量

    缺点:程序的运行时间会大大加长,还会产生很大的数据文件,数据分析的时间也相应增加;影响了程序真实的运行情况

名词含义
调用关系树Call Tree从程序的Main()函数开始,调用者和被调用函数就形成了一个树形关系——调用树
消逝时间Elapsed Time从用户的角度来看程序运行所花的时间。当用户看到一个程序没有反应,用户并不知道程序此时是在运行自己的代码,还是被调度出去了,或者操作系统此时正在忙别的事情
应用程序时间Application Time应用程序占用CPU的时间,不包括CPU在核心态时花费的时间
本函数时间Exclusive Time所有在本函数花费的时间,不包括被调用者使用的时间
所有时间Inclusive Time包含本函数和所有调用者使用的时间

2.4 实践

具有实际意义的软件工程作业

软件:复杂性、易变性

软件设计原则

单一职责原则 Single Responsibility Princle SRP

一个模块只有一个导致他变化的原因,一个模块应该完全队某个功能负责

开放-封闭原则 Open-Close Principle, OCP

软件可扩展,不可修改-扩展时不改变模块本身

代价昂贵

有变化的轴线才有意义

程序需求的扩展

数据方面:属性-大数,数量,维度,等

需求方面:需求维度扩展,体现特点,在已有上增量

用户方面:单用户,多用户,不同背景,运行安全

软件构建:平台迁移,多语言接口,升级时减少下线时间

第3章 软件工程师的成长

3.1 个人能力的衡量和发展

Individual Contributor (IC)

• 理解问题或任务

• 提出多种解决办法并估计工作量

• 其中包括寻找以前的解决方案,因为很多工作是重复性的 – 例如实现某些类似的web页面。

• 与相关角色交流解决问题的提案, 决定最终方案

• 执行, 把想法变成实际中能工作的代码

• 修复缺陷, 对结果负责

软件工程师的成长
  1. 知识: 对具体技术的掌握, 动手能力

  2. 经验: 对问题领域的知识和经验的积累 (例如: 对于医疗行业的了解, 对于金融行业的了解)。

  3. 通用的软件设计思想, 软件工程思想的提高——原创的博客

  4. 职业技能 (区别于技术技能):

    自我管理的能力; 表达和交流的能力; 与人合作的能力; 把任务按质按量完成的执行力;

    实际成果

如何衡量, 证明自己的能力?
  1. 项目/任务有多大?(代码行)

  2. 花了多少时间?(人数*时间)

  3. 质量如何? 交付的代码中有多少缺陷? (缺陷的数量/项目的大小)

  4. 是否按时交付?(方差)

3.2 软件工程师的思维误区

模块间的复杂依赖关系

极端态度

  1. 分析麻痹:想弄清所有细节、依赖关系再动手,不想修复问题

  1. 不分主次,想解决所有依赖问题:想动手修复所有问题,达到“完美”目标,不是找“足够好”的方案

  2. 过早优化:陷在某个局部问题中

  3. 过早扩大化 / 泛化

3.3 软件工程师的职业发展

考级之路

Steve McConnell 版本

大公司 版本

自我评估

3.4 技能的反面——解决问题

技能:重复工作,不用思考

完成不熟练的任务需要专注——成熟的技能不需要付出专注度

培养技能:练习

第4章 两人合作

4.1 代码规范

风格规范,设计规范

4.2 代码风格规范

简明,易懂,无二义性

缩进:4个空格

行宽括号断行与空白的{ }行

if ( condition)
​
{
​
    DoSomething();
​
}
​
else
​
{
​
    DoSomethingElse();
​
}

命名

匈牙利命名法”。例如:

fFileExist,表明是一个bool值,表示文件是否存在;

szPath,表明是一个以0结束的字符串,表示一个路径。

下划线大小写

注释

复杂的注释应该放在函数头,很多函数头的注释都是解释参数的类型等

注释(包括所有源代码)应只用ASCII字符,不要用中文或其他特殊字符

4.3 代码设计规范

函数:只做一件事,但是要做好

goto

错误处理:参数处理,断言

处理C++中的类

避免传递类型实体的值,应该用指针传递

有显式的构造和析构函数,不要建立全局的实体

使用虚函数来实现多态(Polymorphism)—— 析构函数应该是虚函数

构造函数不应该返回错误——把可能出错的操作放到HrInit()或FInit()中

把可能出错的操作放到HrInit()或FInit()中

如果可能,实现自己的New/Delete——释放指针时不用检查NULL。

运算符的实现必须非常有效率

不要用异常作为逻辑控制来处理程序的主要流程——异常的设置和处理都要花费“异乎寻常”的开销

用Const标注不改变数据的函数。

4.4 代码复审

看代码是否在“代码规范”的框架内正确地解决了问题

代码复审的步骤
  1. 代码必须成功地编译——要用团队规定的最严格的编译警告等级

  2. 程序员必须测试过代码——DeBugger中单步执行,包括错误处理的分支

  3. 程序员必须提供新的代码,以及文件差异分析工具

  4. 复审者可以选择面对面的复审、独立复审或其他方式

  5. 在面对面的复审中,一般是开发者控制流程,讲述修改的前因后果。

  6. 复审者必须把反馈意见逐一提出

  7. 开发者必须负责让所有的问题都得到满意的解释或解答,或者在TFS中创建新的工作项以确保这些问题将来会得到处理

  8. 对于复审的结果,双方必须达成一致的意见:打回去,有条件的同意,放行

代码复审后,开发者应该把复审过程中的记录整理出来:

(1)更正明显的错误。

(2)对于无法很快更正的错误,要在TFS中创建Bug把它们记录下来。

(3)把所有的错误记在自己的一个“我常犯的错误”表中,作为以后自我复审的第一步。

4.5 结对编程

极限编程:每时每刻都处在代码复审的状态

结对编程模式下,一对程序员肩并肩地、平等地、互补地进行开发工作。两个程序员并排坐在一台电脑前,面对同一个显示器,使用同一个键盘,同一个鼠标一起工作。他们一起分析,一起设计,一起写测试用例,一起编码,一起单元测试,一起集成测试,一起写文档等。

结对编程中有两个角色:

(a)驾驶员(Driver)是控制键盘输入的人。

(b)领航员(Navigator)起到领航、提醒的作用。

结对编程中,因为有随时的复审和交流,程序各方面的质量取决于一对程序员中各方面水平较高的那一位。

开发中的复审主要包括:设计复审、代码复审、测试计划复审、文档复审

结对编程的过程也是一个互相督促的过程

如何结对编程?

(1)驾驶员:写设计文档,进行编码和单元测试等XP开发流程。

(2)领航员:审阅驾驶员的文档、驾驶员对编码等开发流程的执行;考虑单元测试的覆盖程度;是否需要和如何重构;帮助驾驶员解决具体的技术问题。

(3)驾驶员和领航员不断轮换角色,不宜连续工作超过一小时。领航员要控制时间。

(4)主动参与。任何一个任务都首先是两个人的责任,也是所有人的责任。没有“我的代码”、“你的代码”或“她的代码”,只有“我们的代码”。

(5)只有水平上的差距,没有级别上的差异。尽管可能大家的级别资历不同,但不管在分析、设计或编码上,双方都拥有平等的决策权利。

关键是如何最大限度地发挥“领航员”的作用,如果用处不大,也就无需结对。

所谓极限编程,就是把一些认为重要和有效的做法发挥到极致,

交流:平等

第5章 团队和流程

5.1 非团队和团队

团队有一致的集体目标, 团队要一起完成这目标。

团队成员有各自的分工, 互相依赖合作, 共同完成任务

5.2 软件团队的模式

一窝蜂模式 :存活的时间一般都不长

主治医师模式:首席程序员 + 其他成员

明星模式:明星的光芒盖过了团队其他人

社区模式:由很多志愿者参与, 每个人参与自己感兴趣的项目, 贡献力量

业余剧团模式:不同的人会挑选不同的角色,在下一个剧目中, 这些人也许会换一个完全不同的角色类型。在团队中听从一个中央指挥(导演)的指导和安排

秘密团队: 团队内部有极大的自由, 没有外界的干扰 (不用每周给别人介绍进展, 听领导的最新指示),团队成员有极大的投入。

特工 (SWAT) 团队:由一些有特殊技能的专业人士组成,负责解决一些棘手而有紧迫性的问题

交响乐团模式:各司其职, 演奏都靠谱, 同时看指挥的。都是练习过多次的曲目, 重在执行。——稳定成长阶段的模式

爵士乐模式: 不靠谱,没有现场指挥——强调个性化的表达,强有力的互动, 对变化的内容有创意的回应

功能团队模式:具备不同能力的同事平等协作, 共同完成一个功能,没有管理和被管理的关系——大型软件公司

官僚模式:“老板驱动” ——无谓的算计忽略了全局最优的绩效评估

系统体系结构沿用开发机构的内部交流模式

团队结构:解决用户需求

5.3 开发流程

写了再改 Code-and-Fix

只用一次”的程序,

“看过了就扔” 的原型,

一些不实用的演示程序,

瀑布模型 (waterfall model)

描述了单向的, 不可逆的生产过程

[分析 -> 设计-> 实现(制造) -> 销售 -> 维护]

重继话,重事先设计,重文档表达

要让产品成功, 最好把这个模型走两遍,先有一个模拟版本 (simulation of final product), 在此基础上收集反馈, 改进各个步骤, 并交付一个最终的版本:

局限性:

  • 各步骤之间是分离的,(但是软件的生产过程中的各个步骤不能这样严格分离出来。)

  • 回溯修改很困难甚至不可能, (但是软件生产的过程需要时时回溯)

  • 最终产品直到最后才出现,(但是软件的客户, 甚至软件工程师本人都需要尽早知道产品的原型, 试用)

变形:

生鱼片模型 (各相邻模块像生鱼片那样部分重叠)

大瀑布带着小瀑布

统一流程 RUP (Rational Unified Process)

各阶段由不同的成员完成

规程/工作流:业务建模,需求,分析与设计,实现,测试,部署,配置和变更管理,项目管理,环境

四个阶段:初始、细化、构造、交付

老板驱动的流程
渐进交付的流程 (Evolutionary Delivery)

[开发 -> 发布 -> 听取反馈 -> 根据反馈做改进 ]

MVP 最小可行产品:最核心功能用最小成本实现出来,更早获得用户反馈

MBP 最强最美产品

TSP的原则 Team Software Process

第6章 敏捷流程

6.1&2 流程介绍 & 敏捷流程的问题和解法

敏捷开发的原则

  1. 尽早并持续地交付有价值的软件以满足顾客需求。

  2. 欢迎需求的变化, 并利用这种变化来提高用户的竞争优势。

  3. 经常发布可用的软件,发布间隔可以从几周到几个月,能短则短。

  4. 业务人员和开发人员在项目开发过程中应该每天共同工作。

  5. 以有进取心的人为项目核心,充分支持信任他们

  6. 无论团队内外,面对面的交流始终是最有效的沟通方式

  7. 可用的软件是衡量项目进展的主要指标

  8. :敏捷流程应能保持可持续的发展。 领导, 团队和用户应该能按照目前步调持续合作下去。

  9. 只有不断关注技术和设计才能越来越敏捷.

  10. 尽可能简化工作量的技艺

  11. 只有能自我管理的团队才能创造优秀的架构, 需求和设计.

  12. 时时总结如何提高团队效率, 并付诸行动。

敏捷的步骤

  1. 找出完成产品需要做的事情 – Product Backlog

    怎样在计划中体现个任务间的依赖关系

  2. 决定当前的冲刺需要解决的事情 – Sprint Backlog.

    从产品级描述细化到技术实现的岑概念

  3. 冲刺 (Sprint). ——一切交流只能通过SCRUM MASTER 来完成。

    每日例会 (SCRUM Meeting):向同伴报告进度;每日构建,让大家每天都能看到一个逐渐完善的版本

    Burn Down Chart

    Kanban

    定义任务,记录完成任务还需要多少时间(实际剩余,预估剩余,实际花费)

    代码写完后的测试任务(由谁负责,怎么负责)

  1. 得到软件的一个增量版本,然后在此基础上又进一步计划增量的新功能和改进

    增量是否满足计划?新问题打断了计划?

6.3 敏捷的团队

Scrum/Sprint 能成功实施的关键在于 ScrumMaster

一个好的ScrumMaster 能在两种语境 (描述软件项目的商业语境,描述实现细节的技术语境) 自如地翻译和切换

对团队的要求:

自主管理self-managing:

自我组织self-organizing:联合团队成员

多功能型cross-functional:全面负责

6.4 敏捷总结

Sprint/Scrum 对项目的众多需求采取分而治之的办法, 能让相关人员集中精力, 在一定期限内解决部分问题。

它强调短时间的迭代 (iteration), 在多次迭代中不断总结, 改进团队的流程和产品功能。

它明确地指出不同人在一个项目中的投入和责任的不同 (猪和鸡), 并坚持让全身心投入的“猪”来主导项目。

它通过 daily scrum, ScrumMaster 等方法和角色,鼓励团队内部交流并优化团队和其他人员的交流方式。

它对团队成员提出了很高的要求, self-managing, self-organizing, cross-functional。 一般人不能马上做到这一点。

它不是 “银弹”,不能解决软件开发的所有问题,至于具体项目进度如何跟踪, 如何管理测试工作, 如何管理复杂项目, 还要靠战斗在一线的团队成员见招拆招,想出合适的办法。

经验:

  1. ScrumMaster 不是一个官,而是一个没有行政权力的沟通者,还要在团队中做具体的工作

  2. 不少项目需要很多暗箱操作和政治角力才能搞定, Scrum 会把这些矛盾都摆到明处

  3. 在复杂的项目里,要让一线团队成员做决定。

  4. 在复杂的项目里,要让一线团队成员做决定。

  5. 在Scrum 计划阶段的估计不是一个“合同”, 领导们不要把它当成一个合同。估计总是不准的。 坚持短期的Sprint,即使不准的估计也不会有大的损害。

  6. 不要和管理层谈 “流程”, 他们只关心 “结果”

  7. 在大型团队,复杂项目中,Scrum 并没有非常完美的答案,Scrum 的创始人也承认这一点。 (我曾看到30多人挤在会议室里搞 Daily Scrum,一叹! )

第7章 实战中的软件工程 MSF

MSF,即Microsoft Solution Framework,也就是微软推荐的做软件的方法。

7.2 MSF基本原则

(1)推动信息共享与沟通(Foster open communications)

所有信息都保留,并公开,讨论要包括所有涉及的角色,决定要公开,并告知所有人

(2)为共同的远景而工作(Work toward a shared vision)

目标必须是明确的,没有二义性;不是当前就能达到,必须是通过努力才能达到的;不是空泛的,它应该对项目成员每天的工作都有指导作用。

“共同”

(3)充分授权和信任(Empower team members)

授权:有权力在自己的职权范围内按照他们自己的承诺完成任务,同时,他们也充分信任其他同事也能实现各自的承诺

充分授权的管理方式是MSF的核心观念之一

(4)各司其职,对项目共同负责(Establish clear accountability and shared responsibility)

对此事负责任的角色要自己拿主意。

要明确:Who:谁负责; What:做什么,具体的执行方案,什么叫做“做好了”;When:什么时候开始,什么时候结束;Why:为什么是这样安排(和项目的远景是否吻合),在什么情况下可以变更?

(5)重视商业价值(Focus on delivering business value)

商业项目需要重视市场和用户

(6)保持敏捷,预期变化(Stay agile, expect change)

预期 vs 期望

高质量在任何时候都是有益的,低质量的工作,会误导客户和团队,也许会导致错误的变化。

(7)投资质量(Invest in quality)

投资要讲效率——不是要不惜一切代价达到最高的质量标准

投资要讲时机——即将需要的时候培训技术

投资是长期的

不是质量第一,而是解决用户的问题第一

缺陷 与 改正的相对性

(8)学习所有的经验(Learn from all experiences)

每一个里程碑结束时都要做一个“里程碑回顾”

请团队以外的专家来主持召开“事后诸葛亮”会

(9)与顾客合作

商业价值由用户说了算

7.3 MSF 团队模型

每个角色都被认为是同等重要的,重要的决定都要共同做出

测试团队:

(1)发现产品的问题;

(2)保证这些问题都得到处理

处理 != 解决

每个角色从自己的质量目标出发,对自己的质量目标负责。

成功的技术项目必须符合各种利益相关人(stake holder)完全不同且常常对立的质量观点——对立中寻找共同利益,在冲突中达到平衡

7.4 MSF过程模型

瀑布模型中 基于里程碑的规划优势 + 螺旋模型中 增量迭代

“阶段”:在这一段时间里团队集中精力做某一类事情,每个阶段的结束都代表了项目的进展和团队工作重心的变化

各个阶段之间会有缓冲区

7.5 MSF敏捷开发模式

更强调与用户的交流

“我觉得”和“用户觉得”是两码事

质量——防患于未然

所有的角色都要对防止缺陷的发生确保缺陷被修复负责。

重视在实战条件下的质量

保证项目的质量是“随时可用”——产品要尽早能够达到随时安装、发布的标准

自己注册成为用户和商户使用产品,了解问题

精简过程,直奔主题

不必为了交接而搞出许多文档

7.6 MSF CMMI开发模式

CMMI是英文Capacity Maturity Model Integrated(能力成熟度集成模型)的简称。CMMI目前已成为许多大型软件业者用于改善组织内部软件工程所采行的软件评估标准。

是CMM模型的最新版本

运用CMMI模型管理的项目,不仅降低了项目的成本,而且提高了项目的质量与按期完成率

保括了连续模型和阶段模型这两种表示方法

(1)连续式,主要是衡量一个企业的项目能力。可以选择自己希望评估的项目来进行评估。

(2)阶段性。它主要是衡量一个企业的成熟度,亦即企业在项目实施上的综合实力。

CMMI一级,完成级。企业对项目的目标与要做的努力很清晰,项目的目标得以实现。项目实施对实施人员有很大的依赖性。

CMMI二级,管理级。企业在项目实施上能够遵守既定的计划与流程,有资源准备,权责到人,对相关的项目实施人员有相应的培训,对整个流程有监测与控制,并联合上级单位对项目与流程进行审查。保证了企业的所有项目实施都会得到成功。

CMMI三级,明确(定义)级。有一整套的管理措施,并保障项目的完成;而且,企业能够根据自身的特殊情况以及自己的标准流程,将这套管理体系与流程予以制度化。能在不同类的项目上成功地实施。

CMMI四级,量化管理级。实现数字化的管理。降低项目实施在质量上的波动。

CMMI五级,优化级。通过信息手段与数字化手段来实现对项目的管理,而且能够充分利用信息资料,对企业在项目实施的过程中可能出现的次品予以预防。

MSF for CMMI能做什么:能帮助团队加速达到CMMI第三级“明确”阶段

第8章 需求分析

8.1 软件需求

  1. 获取和引导需求

    引导用户需求

    符合企业商业模式,技术团队要求

  2. 分析和定义需求——量化:期限,成本,优先级

  3. 验证需求——与利益相关者沟通

  4. 在软件产品的生命周期中管理需求——需求的变化

软件需求:

  1. 对产品功能性

  2. 对产品开发过程

  3. 非功能性——服务质量需求

  4. 综合需求

8.2 软件产品的利益相关者

用户:直接使用软件的人

顾客:购买/接收软件的人

市场分析者:“典型用户”的需求

监管机构

系统/应用集成商

软件团队

软件工程师

8.3 获取用户需求——用户调研

用户最需要的 > 用户表达出来的 > 软件团队能理解的 (老板/PM) + 团队的商业目标

        > 软件团队成员具体表达出来的 (PM 写 spec)

                > 在各种约束条件下, 具体执行表达出来的 (dev 写代码)

                        >验证通过的 (Test)

                                >通过各种渠道告诉目标用户 (发布/推广)

                                        >用户终于能用上了,但是他们不满意 

几种用户调研 (User Study) 的方法:

1) 焦点小组 (Focus Group)/推进会议:一群目标用户的代表

要求会议的组织者要有很强的组织能力

2) 深入面谈 (in-depth interview)

效果去接与主持面谈的团队成员的能力

1, 2 结果:用户场景

3) 卡片分类 (Card Sorting)

整理卡片,反复:讨论 -> 明晰定义 -> 归类 -> 排序

4) 用户调查问卷 (User Survey)

5) 用户日志研究 (User Diary Study)

要求用户有很高的自律能力

隐私问题

6) 民族志/人种学研究 (Ethnographic Study)

7) A/B 测试 (A/B Testing)

用已有用户对两个方案进行测试

弱点:

运行成本随着时间的推移而变大,

用户的情绪反映你看不到,你只看到交互的行为

要分清各种因素的关系,

用户可能流失

8.4 竞争性需求分析的框架

NABCD 模型

N (Need 需求):独特性

A (Approach 做法)

B (Benefit 好处):好处,成本

C (Competitors 竞争):市场,先发优势FMA first Mover advantage,后发优势SMA Second Mover Advantage

D (Delivery 交付, Data 数据)

NPS(净推荐值):评估产品效果

8.5 功能的定位和优先级

杀手功能 Core / 外为功能 Context

必要需求 Mission Critical / 辅助需求 Enabling

四象限

不同功能的不同做法:

维持:最低成本

抵消:快速达到足够好

优化:花大力气,最好

差异化:优势

不做

核心功能:用户满意度与投资力度呈线性

服务质量需求:用户满意度与投资力度 呈 斜率下降,渐进稳定

惊喜功能:用户满意度随投资力度 大幅提高

8.6 计划和估计

目标-希望,估计-了解+计算,决心-保证

假设 -> 估计

估计的能力

参考前人经验

快速原型法:先锋探路

Y = X +/- X/N

软件成本分析的经典模型COCOMO:影响软件成本的因素:

产品、平台、人员、项目

整个软件项目的时间估计:

a) 自底向上 团队成员各自估计底层模块和单个功能 (和单元测试) 所需的时间, 再加上集成, 及基本测试的时间, 就是大概的开发时间。 这还没有考虑各个模块之间的相互依赖性.

b) 回溯 团队从整个项目最终交付之日往回倒推 -

8.7 分而治之 WBS

work breakdown structure

从结果出发构建WBS

第 9 章 项目经理

9.1 PM

PM: Product Manager 产品经理, Project Manager项目精力, Program Manager,

微软的PM - Program Managers

9.2 微软PM 的来历

程序开发中,项目管理的复杂度似乎是和人员数量的平方成正比

Charles Simonyi :把程序员分成 Master Programmer (MP)Slave Programmer (SP)

光有程序员和销售人员是不够的,需要专人来把市场/销售人员那一套 MBA 的套路翻译成程序员能懂的功能说明 (spec)

9.3 PM做开发和测试之外的所有事情

PM分类:

  • 功能设计的PM; 有些需要很深的计算机科学各个分支的专业知识

  • 需要对商业和客户很强的了解能力 (如 Office 应用软件的PM );

  • 需要广泛的经验和知识面, 商业拓展能力 (如 MSN 部门的 PM);

  • 驱动流程的PM,

  • 专门深入某一领域的 PM (如国际化/本地化 localization/globalization);

  • 和研究人员合作, 琢磨前沿技术如何能进入主流产品,做技术转化的 PM。

和大家平等工作, 推动团队完成软件的功能

管事不管人

一定做具体工作

PM 的产品是 spec (规格说明书), PM 要凭自己的能力, 把用户的需求展现成 dev/test 能够了解, 能够执行的语言, 从而赢得同伴的信任和尊敬。

PM 最大的, 最独特的贡献是:保持团队的平衡。

PM 文化的盛行有副作用:“design by committee”, 一些产品不能很快跟上市场变化, 在需要个人特色的方面, 如设计/UI, “committee”设计出来的东西大多中规中矩, 但是很多方面了无新意。

PM 的能力要求和任务

学习能力,观察理解能力, 分析管理能力销售能力交流能力, 处理冲突的能力一定的专业能力转换角色的能力自省的能力

9.5 PM和风险管理

第10章 典型用户场景

10.1 典型用户和典型场景

典型用户 Persona:描述了一组用户的典型技巧、能力、需要、想法、工作习惯和工作环境

定义典型用户

受欢迎的典型用户:指那些按设计者的期望使用系统的用户

不受欢迎的典型用户:指那些有不正当目的的用户

Persona可以包括以下内容:

(1)名字(越自然越好)。(2)年龄(不同年龄和收入的用户有不同的需求)。(3)收入。

(4)代表的用户在市场上的比例和重要性(比例大不等同于重要性高,如付费的用户比例较少,但是影响大,所以更重要)。

(5)使用这个软件的典型场景。(6)使用本软件/服务的环境 (在办公室/家里/沙发/床上/公共汽车/地铁…)。

(7)生活/工作情况。(8)知识层次和能力(教育程度,对电脑、万维网的熟悉程度)。

(9)用户的动机、目的和困难(困难 = 需要解决的问题)。 (10)用户的偏好。

要和这些Persona的代表交流,理解用户,理解他们的工作方式和需要。然后再修改,细化Persona。

从典型用户到场景

场景:每一个目标,列出达到目标所必须经历的过程

成功的结果,失败的场景

场景设计

  1. 场景入口(描述场景如何开始)

  2. 描述典型用户场景中的内部和外部环境(内部环境指心理因素等)。

  3. 给场景划分优先级

  4. 写场景

场景到任务

沿着子系统/模块的所属关系把场景划分开:UI,逻辑,数据库

从任务到代码

估计时间,写原型代码,写设计文档,写代码,创建/更新单元测试,进行单元测试,重构,复审,加入代码库

代码库:

(1)根据场景和开发任务来决定集成的次序。

(2)互相依赖的任务要一起集成。

(3)在测试场景时,要保证端到端的测试。

(4)场景的所有者必须保证场景完全通过测试,然后把场景的状态改为“解决”。

10.2 用例:另一种需求分析的方法

基本元素:标题-目标,角色,主要成功场景-交互步骤,扩展场景

通过讲故事,分析用户需求

关注用户的加指

一次完成一个用力,逐步构建系统

增量开发

10.3 规格说明书

functional spec, 软件功能说明书,

technical spec, 软件技术说明书

spec – specification

功能说明书

从用户的角度描述软件产品的功能, 输入,输出,界面, 功能的边界问题, 功能的效率问题(对用户而言), 国际化, 本地化异常情况, 等

不涉及软件内部的实现细节

谁来写spec? 项目的PM, 或者其他人员

谁来实现spec? 开发人员, UX/UI 设计人员

谁来验证spec? 质量保障人员 (QA)

怎么写:定义概念,规范假设,界定边界,描述交互,写明副作用,说明服务质量

spec 的最大敌人:乏味

  1. 用活生生的人物和故事描述用户怎样用软件的 (参见上文 典型用户 )

  2. KISS - 保持简单, 直接的描述。涉及UI 的部分可以直接上图。 也可以画表格,不要写长篇累牍的文字。

  3. 如果是技术文档,最好把示例代码写上,单元测试也写好,让程序保证spec 的正确性,也让读者可以验证 spec 的正确性。

  4. 边界条件规定清楚,理工科思维的工程师们看到这里大脑就兴奋起来了 - 他们想找出你 spec 的破绽!

spec 的另一个敌人:时间。 几乎在spec 写好的那一瞬间,spec 就开始过时了

  1. 记录版本修订的时间和负责人 - 这样出了问题好去找人。

  2. 在spec 中要说明如何验证关于功能的描述,从spec 的描述中就能知道单元测试怎么写, 最好把测试用例也链接上。

  3. 把spec 和测试用例,项目任务等放一起 (例如 TFS 上面),相互链接。

  4. 变化一定会发生的,与其在 spec 中有意忽略这一点,不如主动挑明哪些部分是容易发生变化的,提前做好预案。 哪些部分如果改变,会有何种连锁反应。

  5. 在做任何改动的时候,一定事先参考spec,事后更新spec, 团队领导人不应该在没有spec 的情况下做拍脑袋的决定。

功能说明书模板
  1. spec 的目标是什么,spec 的目标不包括什么

  2. spec 的用户和典型场景是什么

  3. spec 用到哪些术语,他们的定义是什么

  4. 用户如何使用软件的功能的

  5. 各种边界条件是什么,软件功能应该怎么样变化

    1. 这些边界条件多了去了,用户数量的变化,输入内容的上限下限, 不同国家/地区/文化/语言/硬件/软件版本/环境参数….

  6. 功能有什么副作用,对于其它功能有什么显性或隐形的依赖关系?

  7. 什么叫“好”, 什么叫这个功能测试完了,可以交付了?

技术说明书——设计文档

如何实现功能

10.4 功能驱动的设计FDD

Feature Driven Design

需求 变成 可以直接操作的开发工作

步骤:

  1. 构造总体模型:实体关系,数据流、事件流程

  2. 构造功能列表:分解为小的主题领域,描述业务活动

  3. 制定开发计划:时间,功能的先后次序、依赖关系、复杂程度

  4. 功能设计阶段:时序图、实体模型,计划到天

  5. 实现具体功能:实现,单元测试,复审,继承

第11章 软件设计与实现

11.1 分析和设计方法

软件是怎么解决这些需求的?

11.2 图形建模和分析方法

表达实体和实体之间的关系

思维导图(Mind Map)

实体关系图 (Entity Relationship Diagram)

用例图 (Use Case Diagram,UCD )

表达数据的流动 (Data Flow Diagram)

表达控制流 (Flow Chart, Finite State Machine)

统一的表达方式(Unified Modeling Language, UML)

11.3 其他设计方法

形式化的方法 (Formal Method)

文学化编程 (Literate Programming)

11.5 开发阶段的日常管理

闭门造车(leave me alone)

每日构建

构建大师

宽严皆误

明确构建大师的职责,公开显示固定的构建时间。

步骤
签出自由签出签出时候,将文件上锁很多人都会同时编辑同一文件
本地单元测试不要求要求每个模块都要求写单元测试
本地check-in test(签入测试)不要求要求BVT还没有完成
签入时间任何时候每天固定时间开放目前签入情况很混乱
签入冲突处理合并后即可签入合并后,再重新编译,测试,再提交重新测试会花费比较多的时间
签入必须经过代码复审随意必须开放人员有一半是新员工,必须通过代码复审建立良好的规范
签入时必须运行代码分析工具不要求要求代码分析工具尚未配置好
签入时单元测试必须同时签入不要求要求每个模块都要求写单元测试
签入必须是多个相关文件同时签入不要求,可以签入单个文件要求保证每一个签入都不会导致构建失败
签入必须和一个工作项关联不要求要求所有的工作必须有工作项跟踪
设定专用网络服务,自动处理提交的ShelveSet、构建、BVT、然后签入代码不要求设置需要很多人力来设计并维护

小强地狱(Bug Hell)

11.6 源代码管理

//todo:总结源代码管理的功能

11.7 代码完成

第12章 用户体验

12.2 用户体验设计的步骤和目标

用户体验设计步骤:概要设计(需求分析),行为设计(场景设计),界面设计(具体实现)

12.3 软件用户界面的评价标准

如何评估用户界面? 可以参考 Nielsen的启发式十条原则

  1. 可视性原则:给用户提供可感触的反馈

  1. 系统界面符合现实惯例

  2. 用户有自由控制权

  3. 一致性和标准化

  4. 使用各种类型的用户

  5. 帮助用户识别、诊断并修复错误

  6. 有必要的提示和帮助文档

第13章 软件测试

13.1 基本名词解释 & 分类

按测试设计分类:黑箱、白箱

按测试目的分类:功能测试,非功能测试-质量测试

按测试的时机和作用分类

冒烟测试、验证构建测试、验收测试

回归测试、随机/探索式测试、bug大扫荡、伙伴测试

13.2 各种测试方法

构建验证测试

必须能安装,必须能实现一组核心场景

探索式测试

随机的,尝试性的,不会重复的-不能自动化

场景/集成/系统测试
伙伴测试

开发人员找测试人员作为伙伴

效能测试

设计负载,令用户满意的服务质量

现实的动态、静态数据

压力测试

沿用户轴,时间轴演唱

内部 / 外部公开测试 -alpha/ beta test
易用性测试

“可用性设计师”

Bug Bash “小强”大扫荡
  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值