《构建之法》读书笔记
这篇文章是大三下的软件工程科目的课外阅读书籍《构建之法》的读书笔记,包括了对整本书全部十七章知识点的总结和最后一点自己的心得体会。邹欣老师在这本书中把枯燥的理论概念讲解得非常生动,寓教于乐,深入浅出,举出的例子也是形象而易懂,读完之后很受启发。
第一章 概论
在这一章中,作者为我们介绍了一些关于软件工程的基本知识。
①软件=程序+软件工程:正是因为对软件开发活动(构建管理、源代码管理、软件设计、软件测试、项目管理)相关的内容的完成,才能完成把整个程序转化成为一个可用的软件的过程。
扩展的推论:软件企业=软件+商业模式
②软件开发的不同阶段:玩具阶段→业余爱好阶段→探索阶段→成熟的产业阶段
③软件所具有的特殊性:复杂性、不可见性、易变性、服从性、非连续性(由软件的本质所决定的)
软件还有其他特性:
·有许多不同的程序设计语言、软件工具和软件开发平台
·存在许多不同的软件开发流程
·软件团队中存在许多不同的角色
·软件通常既可以存储在磁带上,也可以存储在CD/DVD上
④作者邹欣总结的自己做过的项目的各自特点:
• Build To Learn:开发软件,构建系统的目的是做进一步的试验,试图发现客观规律或某个试验方法的优点与缺点。这些项目经常是科研论文的基础工作。
• Build To Show:为了突出地展现某个技术的作用,开发一些演示为目的的软件,这些项目很吸引眼球,经常获得新闻报道,但是功能未必全面。
• Build To Serve:为了服务一定范围的目标用户而构建的工具等,有时以公开的SDK形式发布。
• Build To Win:以在市场上赢得用户为目标而构建的软件。这也是种种科学发现,技术突破最好的试金石。这是我在研究院之外的十余年中做的最多的项目类型,也是这本书的英文名字。
第二章 个人技术和流程
2.1 单元测试
①重要的单元测试:有效解决程序员对模块功能的误解、疏忽或不了解模块的变化之类的问题,使自己负责的模块功能定义尽量明确,模块的质量得到稳定的、量化的保证。
②好的单元测试的标准:
在最基本的功能/参数上验证程序的正确性
单元测试必须由最熟悉代码的人(程序的作者来写)
单元测试过后,机器的状态保持不变
单元测试要快(一个测试的运行时间是几秒钟,而不是几分钟)
单元测试应该产生可重复、一致的结果
独立性——单元测试的运行/通过/失败不依赖于别的测试,可以人为构造数据,以保持单元测试的独立性
单元测试应该覆盖所有代码路径
单元测试应该集成到自动测试的框架中
单元测试必须和产品代码一起保存和维护
③单元测试的基础上能够建立关于这一模块的回归测试,目的是:
(1)验证新的代码的确改正了缺陷
(2)同时验证新的代码有没有破坏模块的现有功能,有没有Regression
2.2 效能分析工具
效能分析方法:抽样和代码注入
2.3 个人开发流程
个人开发流程PSP(Personal Software Process)
特点:(1)不局限于某一种软件技术,而是着眼于软件开发的流程,这样,开发不同应用的软件工程师可以互相比较。
(2)不依赖于考试,而主要靠工程师自己收集数据,然后分析、提高。
(3)在小型、初创的团队中,很难找到高质量的项目需求,这意味着给程序员的输入质量不高。在这种情况下,程序员的输出(程序/软件)往往质量也不高,然而这并不能全部由程序员负责。
(4)PSP依赖于数据(工程师输入数据的时间代价、数据可能遗失或者不准确的风险、可能会出现一些数据不利于工程师本人的情况)
(5)PSP目的是记录工程师如何实现需求的效率,而不是记录顾客对产品的满意度,工程师有可能很高效地开发出一个顾客不喜欢的软件。
第三章 软件工程师的成长
3.1 个人能力的衡量与发展
①软件工程包括了开发、运用、维护软件的过程中的很多技术、做法、习惯和思想。软件工程把这些相关的技术和过程统一到一个体系中,叫“软件开发流程”,软件开发流程的目的是为了提高软件开发、运营和维护的效率,以及提升用户满意度、软件的可靠性和可维护性。
②初级软件工程师的成长包括以下几种:
(1)积累软件开发相关的知识,提升技术技能(如对具体技术的掌握,动手能力)。例如:对JAVA、C/C++、C#的掌握,诊断/提高效能的技术,对设备驱动程序、内核调试器的掌握,对于某一开发平台的掌握
(2)积累问题领域的知识和经验(例如对医疗或金融行业的了解)
(3)对通用的软件设计思想和软件工程思想的理解
(4)提升职业技能(区别于技术技能),包括:自我管理的能力、表达交流的能力、与人合作的能力、按质按量完成任务的执行力
(5)实际成果——最重要的评价标准
3.2 软件工程师的职业发展
自我评估,自我评价清单:
第四章 两人合作
4.1 代码规范
包括代码风格规范和代码设计规范
4.2 代码风格规范
代码风格原则:简明、易读、无二异性
缩进:4个空格,而不是TAB
行宽:限定为100字符
括号
断行与空白的{}行
分行
命名:匈牙利命名法
下划线:分隔变量名字中的作用域标注和变量语义
大小写(Pascal形式和Camel形式)
注释
4.3 代码设计规范
函数:只做一件事,并且要做好
goto:有助于程序逻辑的清晰体现
错误处理:参数处理、断言
类的处理
4.4 代码复审
①形式:自我复审、同伴复审、团队复审
②目的:找出代码错误、发现逻辑错误、发现算法错误、发现潜在的错误和回归性错误、发现可能需要改进的地方、传授经验
③代码复审后把记录整理出来:
(1)更正明显的错误
(2)记录无法很快更正的错误
(3)把所有的错误记在自己的一个“我常犯的错误”表中,作为以后自我复审的第一步
4.5 结对编程
①角色:
驾驶员:控制键盘输入
领航员:起到领航、提醒的作用
②好处:(1)在开发层次,可以提供更好的设计质量和代码质量,两人合作解决问题的能力更强。
(2)对开发人员,带来更多的信心,高质量的产出带来更高的满足感。
(3)企业管理层次上,有效地交流,相互学习和传递经验,分享知识,取得更高的投入产出比。
第五章 团队和流程
5.2 软件团队的模式
主治医师模式、明星模式、社区模式、业余剧团模式、秘密团队、特工团队、交响乐团模式、爵士乐模式、功能团队模式、官僚模式
5.3 开发流程
①写了再改模式
②瀑布模型(Waterfall Model) 是一个项目开发架构,开发过程是通过设计一系列阶段顺序展开的,从系统需求分析开始直到产品发布和维护,每个阶段都会产生循环反馈,因此,如果有信息未被覆盖或者发现了问题,那么最好 “返回”上一个阶段并进行适当的修改,项目开发进程从一个阶段“流动”到下一个阶段,这也是瀑布模型名称的由来。
瀑布模型的适用范围:产品的定义非常稳定但正确性非常重要、产品模块之间的接口能很好地定性定义和验证、使用的技术很成熟、子团队不能做到频繁的交流。
③瀑布模型的变形:生鱼片模型(各个相邻模块像生鱼片那样部分重叠)以及大瀑布带着小瀑布(各个子系统统一到最后进行系统测试)
5.4 统一流程RUP
统一流程Rational Unified Process,团队的各种成员在一个复杂的软件项目中的不同阶段做不同的事。这些不同类型的工作在RUP中叫做规程或者工作流。简介:
业务建模、需求、分析和设计、实现、测试、部署、配置和变更管理、项目管理。
分为四个阶段:初始阶段(达到生命周期目标里程碑)、细化阶段(达到生命周期结构里程碑)、构造阶段(达到初始功能里程碑)、交付阶段(达到产品发布里程碑)
第六章 敏捷流程
6.1 敏捷的流程
①敏捷开发原则:
(1)尽早并持续地交付有价值的软件以满足顾客需求
(2)敏捷流程欢迎需求的变化,并利用这些变化来提高用户的竞争优势
(3)经常发布可用的软件,发布间隔可以从几周到几个月,能短则短
(4)业务人员和开发人员在项目开发过程中应该每天共同工作
(5)以有进取心的人为项目核心,充分支持信任他们
(6)无论团队内外,面对面的交流始终是最有效的沟通方式
(7)可用的软件是衡量项目进展的主要指标
(8)敏捷流程应能保持可持续的发展。领导、团队和用户应该能按照目前的步调持续合作下去
(9)只有不断关注技术和设计,才能越来越敏捷
(10)保持简明——尽可能简化工作量的技艺
(11)只有能自我管理的团队才能创造优秀的架构、需求和设计
(12)时时总结如何提高团队效率并付诸行动
②敏捷流程概述:找出完成产品需要做的事情→决定当前的冲刺(Sprint)需要解决的事情→冲刺(冲刺期间每天开每日例会)→得到软件的一个增量版本并发布
6.3 敏捷的团队
自主管理:自己挑选任务、自己提出改进并实施改进
自我组织:每个人联合起来对项目负责
多功能型:每个人都全面负责,自己搞定规格说明书,和别人沟通,自己搞定测试
6.4 敏捷总结
在迭代开始时,团队审视摆在他们面前的任务,选择他们认为可以在迭代期间完成的那些任务(Plan)。然后团队独立地尽最大努力完成这些任务(Do)。在迭代结束时,团队给利益关系人展示成果(Check),并对开发流程进行调整(Act/Adjust)。
这里有一些实践者的经验教训:
(1)敏捷宣言表明的是一些优先级,不必当作圣旨或者教条来争论。
(2)Scrum Master不是一个官,而是一个没有行政权力的沟通者,就像微软的PM那样。他/她同时还要在团队中做具体的工作。直接把原来的“经理”变成Scrum Master,大多行不通。
(3)一些项目需要很多暗箱操作和政治角力才能搞定,Scrum会把这些矛盾都摆到明处。这有好处,也有风险。
(4)在复杂的项目里,要让一线团队成员做决定。
(5)创业公司的团队其实经常是运行在Scrum 的模式中(只不过大家太忙,没工夫论证自己到底有多么Scrum)。
(6)在Scrum计划阶段的估计不是一个“合同”,领导们不要把它当成一个合同。估计总是不准的。坚持短期的Sprint,这样即使不准的估计也不会有大的损害。
(7)不要和管理层谈“流程”,他们只关心“结果”。
(8)在大型团队、跨地区的团队,或者复杂项目中,Scrum并没有非常完美的答案,Scrum的创始人也承认这一点.
第七章 MSF
微软公司中关于软件开发的思想和宣言有一个方法论——微软解决方案框架(Microsoft Solution Framework,MSF),也就是微软推荐的软件开发方法
7.2 MSF基本原则
1. 推动信息共享与沟通(Foster open communications)
2. 为共同的远景而工作(Work toward a shared vision)
“共同的远景”是指产品的远景。我们做一个产品,不管是应用软件、行业软件,还是通用软件,要明确项目的目标是什么。
- 这个目标必须是明确的,没有二义性;
- 这个目标不是当前就能达到,必须是通过努力才能达到的;
3. 充分授权和信任(Empower team members)
这一点的关键是“授权”这个词,授权(Empower)有两个意思:
- 给某人权力和权威
- 给予某人更多自信和自尊在一个高效的团队中,所有的成员都应该能得到充分的授权,他们有权在职权范围内按照自己的承诺完成任务,同时,他们也充分信任其他同事能实现各自的承诺。类似地,团队的顾客(包括内部和外部的顾客)也认为团队能兑现承诺,并进行相应的规划
充分授权的管理方式是MSF的核心观念之一。MSF团队模型就是建立在以下两个原则上的:
- 平等协作—成员之间、团队之间是平等协作的关系
- 充分授权给团队和成员
这就是为什么MSF团队模型是网状,而不是层次结构。这样做有什么好处?好处有两点:
- 被授权的人会承担起自己对项目的责任,同时也期望同事们也同样对项目负责
- MSF提倡自下而上的计划,每个人有充分的权力估计并决定自己的任务需要多长时间,而不是上级交给的时间,这意味着让真正做这件事的人按照自己的估计去完成任务。这样做的结果是啥?是人人都会支持项目的计划和时间表,因为这个时间表是每个人自下而上订出来的
- 充分授权在MSF团队模型的另一个含义是:信任,鼓励团队成员成长,每人都可以在某一时段。
4. 各司其职,对项目共同负责(Establish clear accountability and shared responsibility)
在项目进展的过程中,对于每一项任务,每个人都要明确以下几点。
- Who:谁负责
- What:做什么,具体的执行方案,什么叫做“做好了”
- When:什么时候开始,什么时候结束
- Why:为什么是这样安排(和项目的远景是否吻合),在什么情况下可以变更?
与“信息共享与沟通”原则相呼应,这样的安排能让所有人都明确自己的职责,同时有“大局观”—知道别人在做什么,为什么,以及整个项目的目标
5. 交付增量的价值(Deliver incremental value)
现在的软件产业,特别是和互联网相关的产业,变化非常快,用户希望产品团队经常提供更新,以适应新的需求。我们要保证在两个方面保证客户的利益:
- 我们提供的新版本对用户真的有价值
- 和客户商讨一个最优的新版本的发布频率
6. 保持敏捷,预期和适应变化(Stay agile, expect and adapt change)
软件工程,唯一不变的是变化。所以干脆别幻想客户的需求会在第一时刻很明确,然后保持不会变。要注意,我们是预期变化,不是期望变化
除开外部原因,团队内部也在变化,我们对技术的掌握每天都在提高,原来认为不可能的事可能变得容易。我们对客观世界和软件系统的了解每天都在深化,原来觉得没问题的小细节忽然成了大问题。甚至原来一起打拼的同事忽然要离开……这些都要求我们团队保持敏捷的身段
7. 投资质量(Invest in quality)
对质量的重视,引起对质量的投资,引起对人、过程和工具的投资。
- 投资要讲效率
- 投资要讲时机
- 投资是长期的
8. 学习所有的经验(Learn from all experiences)
在学习过去的经验的同时,也要避免让过去的经验妨碍解决现在的问题
这一原则有两个含义——
- 把经验总结出来
- 分享经验
MSF在每一个里程碑结束时都要做一个“里程碑回顾”,这个回顾不必等到整个项目结束才做。这样做的好处是,大家对最近的成败都记忆犹新,能提供比较准确和全面的反馈;如果发现了错误,可以马上研究解决办法,在下一个里程碑中通过实践来验证。另外,一些好的做法可以及时得到总结和推广。
在项目结束时,MSF推荐请团队以外的专家来主持召开“事后诸葛亮”会,这样的专家会比较系统地总结团队的成功经验和失败教训,同时也客观评价团队的一些特性和团队的开发过程管理,这样能促使团队成员以客观、向前看、解决问题的心态来参加“事后诸葛亮”会,避免主观臆断或相互指责。
9. 与顾客合作(Partner with internal and external customers)
第八章 需求分析
8.1 软件需求
①获取和引导需求:软件团队需要找到软件的利益相关者,了解和挖掘他们对软件的需求,引导他们表达出对软件的需求;需求还可以来自各种管理机构;需求不仅来自外界,还可以来自软件企业本身;需求还可以来自技术团队本身;有些需求的目的是要更好地了解用户的行为和需求。
②分析和定义需求
③验证需求
④在软件产品的生命周期中管理需求
8.2 软件产品的利益相关者
8.3 获取用户需求——用户调查
几种常用的用户调研方法:焦点小组、深入面谈、卡片分类、用户调查问卷、用户日志研究、人类学调查、眼动追踪研究、快速原型调研、A/B测试
8.4 竞争性需求分析的框架——NABCD模型
1. N(Need,需求)
你的创意解决了用户的什么需求?这个需求可以是明确的、公开的(例如:希望能上网玩三国杀)也可能是说不清道不明的,例如——以前没人说:嗯,如果我能找到这样一个网站,我可以去偷菜,就好了……我们要充分了解用户的痛苦,他们对已有软件、服务不满意的地方。
2. A(Approach,做法)
好,你找到了需求,下一步怎么办,得看看你有什么招数,特别是独特的招数,来解决用户的痛苦。你不能说我会C++,所以我一定可以写好这个软件。你得有独特的办法,例如,有人脸识别技术,会做超大规模的数据处理。那你(你的团队)会什么呢?只会冒泡排序?这些招数不光是技术上的,也可以是商业模式上的(例如,我们第一个做众包的服务)、地域的(例如,我们对本市的公交线路很熟)、人脉的(例如,我们认识很多大学生)、行业的(例如,我们有地图测绘行业的资质),或者是成本上的(例如,我们能找到更便宜的资源来维护网站)。
3. B(Benefit,好处)
这时候你已经有了独特的做法,那你这个产品/服务会给客户/用户带来什么好处呢?如果用户已经有一个解决方案(例如用户已经在用QQ聊天),那你的新的聊天软件具体有哪些好处,能让用户离开现有产品,使用你的产品呢?这还有一个用户迁移成本的问题——用户要花费多少精力、时间、金钱才能得到你的产品的好处?如果你要求用户必须有8GB内存、最好的显卡、10Mbps以上的宽带连接,才能使用你的“更好的”视频聊天工具,那么会有多少用户愿意支付这个成本呢?
4. C(Competitors,竞争)
竞争对手也没有闲着,这个市场有多大,目前有多少竞争者在瓜分,你了解么?你的产品如果不是最先进入某个市场的,你还能赢么?先进入市场的产品,有所谓的先发优势(FirstMover Advantage,FMA),当然也有劣势。后面进入市场的产品,有种种不利的因素,但是也有后发优势(Second Mover Advantage,SMA)。
5. D(Delivery,推广)
在实际项目中经历多次的NABC之后,许多人意识到这个框架还应该加一个元素D:Delivery。怎样把你的创新产品交到用户的手中?例一,你想到了一个好主意,建一个比hao123更好的导航页面!我们姑且认为NABC都没问题,那如何把这么好、这么简单的产品交到(Deliver)用户手中呢?例二,你想到了一个手机的应用,NABC都不错,那如何把产品交到千万个用户手中呢?
8.5 功能的定位和优先级
杀手功能、外围功能、必要需求、辅助需求
我们以一个英汉词典软件为例子来说明。
杀手功能:OCR文字识别技术,可以在屏幕上取词解释,拥有独家权威词典,等等
外围功能:良好的界面设计,在各个平台上都能运行
必要需求:单词短语释义的准确性(如果达不到这一点,用户就不会来使用)
辅助需求:可以做各种皮肤(这也许能让一些用户更喜欢这个软件,但不是决定因素)
这四个象限能让软件团队清楚地看到自己感兴趣的功能处于什么地位,有了这些分析,我们就可以决定怎么处理不同类型的功能。 重要的是,不要把资源平摊到所有象限中,而是倾斜到可以产生差异化和独特用户价值的地方。
8.7 分而治之(Work Breakdown Structure)
一个团队项目要在一段时间内完成诸多任务,满足用户的需求,实现团队的目标,同时还希望项目能维持良好的技术架构,以便持续开发,千头万绪,从哪里入手?WBS就是一个例子
WBS通常从最终的产品开始,一层一层往下,把大型交付件(Deliverable)分割为小型、具体的交付件。这样的分割可以持续下去,直到WBS的使用者(开发团队、接收方)达到共识。从数据结构方面来看,WBS分割的结果是一棵树。所有子节点都最终有一个根节点。每个节点描述的是要交付的产品或文档,而不是开发团队的努力或花费(各个叶节点的成本可以作为次节点的属性展现出来)。做好WBS的几个要点:
- 保证所有子节点覆盖了全部父节点包含的内容
- 保证各个子节点不要相互覆盖
叶子节点要保证足够小,能在一个里程碑中完成。在通常的软件项目中,叶节点的成本最好不要超过两周。如果团队成员从常理出发,认为叶节点不宜再分下去,那就可以停止
从结果(Outcome)出发构建WBS,而不是从团队的活动(Action)出发
第九章 项目经理
9.1PM是啥
软件团队里除了能写代码、测试代码和画图做设计的成员,还有一类角色,不做上面这些事情但也很重要,我们叫他们项目经理——PM
PM的M就是Manager,但是P有这几种:Product Manager、Project Manager、Program Manager,在不同的行业和公司,他们的作用各不相同。接下来介绍的是项目经理——Program Manager
- Product Manager:产品经理——正确地做产品
- Project Manager:项目经理——正确地做流程
- Program Manager:微软的职位名称
微软产品团队三足鼎立的角色分配就是PM、开发、测试。PM负责除产品开发和测试之外的所有事情。从某种意义上说,是前面两种角色的综合。微软通常有专门的产品策划(Product Planner),他们和市场部门的专职人员一起,负责产品的长期发展和市场推广
9.4 PM 的能力要求和任务
能力要求:
1. 观察、理解和快速学习能力——PM要能够在一个新的领域中很快上手
2. 分析管理能力
每天项目中发生的事情千头万绪,PM要能够分析出重点,找到优先级,做判断、做决定……一个项目和一个人一样,每天都会碰到各种问题:
- 重要而紧急的
- 网站崩了!
- 程序员小飞突然提出离职!
- 重要而不紧急的
- 按照流量和内容的发展趋势,三个月后,目前的架构似乎撑不住,但是现在还凑合……
- 程序员们都不写文档,他们三个月前说等忙过之后会写的,但是……
- 不重要而紧急的
- 老板的老板问到了项目的进度!要写一个PPT,向若干人征求意见,并及时得到反馈
- 不重要且不紧急的
- 领导想召开全公司大会,要表演节目……
3. 一定的专业能力
如果一定要说专业能力的话,PM的专业就是理解和表达,你能否理解不同人的心理、需求和言外之意?你能否借助文字、图表、草图,甚至代码来清晰准确地表达自己的想法?PM通常也能写代码,能玩转Excel、PPT、Visio、甘特图,会PS,有文字功底,写的博客有人爱读,反正,总得有几招绝活吧!不用说还要有大量的阅读,对IT行业、用户心理、社会都要有广泛的了解
4. 自省的能力
一个PM做第一个项目时可以拍脑袋定工期,拍胸脯打包票,最后拍屁股走人(谁没年轻过呢),但是失败之后要有自省和自我改进的能力
第十章 典型用户和场景
10.1 典型用户和典型场景
①怎样定义典型用户?
我们首先要定义用户的角色。正如戏剧中有正面和反面的角色,软件系统中也有受欢迎的和不受欢迎的典型用户。
- 受欢迎的典型用户——指那些按设计者的期望使用系统的用户,如“网站的购物者”
- 不受欢迎的典型用户——指那些有不正当目的的用户,如在一个房地产业主论坛中滥发房屋中介广告的用户——这些用户也许在别的系统中(如房屋中介论坛)是受欢迎的
典型用户只是我们的设想,还要和这些典型用户的代表交流,理解用户,理解他们的工作方式和需要。然后再修改,细化典型用户
②从典型用户到场景
有了典型用户之后,我们还得决定每一个典型用户的目标——他/她使用系统想要达到什么目的。对于每一个目标,列出达到目标所必须经历的过程,这就是场景,也可以叫故事。注意,有些场景描述了成功的结果,有些场景描述了失败的结果。用户和系统有成百上千种可能的交互情况,写场景时要有针对性。
③场景怎么写?
- 首先针对每一个场景,设计一个场景入口(描述场景如何开始)
- 接着描述典型用户在这个场景中所处的内部和外部环境(内部环境指心理因素等)
- 然后给场景划分优先级,按优先级排序写场景
④场景之间如何区分呢?
- 找到这个场景的特殊之处,对于共同的流程可以一笔带过,重点描述场景中特殊的因素
- 把场景组织成一个故事,这样就能把一个完整的用户与系统交互的流程记录下来,以后进行产品演示或验收都可以以此为基础
10.2 用例
和典型人物、典型场景的方法类似,用例(UseCase)也是很常用的需求分析工具。用例有这样一些 基本元素:
- 标题:描述这个用例要达到的目标
- 角色(Actor):和软件系统交互的角色,例如用户,其他实体,甚至时间(在描述一些和时间相关的场景时有用)
- 主要成功场景(Main Success Scenario):一系列步骤描述角色是怎样和系统交互,从而达到目标的
- 步骤(Step):描述每一步的交互(例如一套正常的ATM取款流程)
- 扩展场景(Extension):描述一些扩展的交互,例如一些意外情况(例如取款时账户余额不足)
10.3 规格说明书(Spec)
①规格说明书(Specification)简称Spec,分为以下两种:
1. 软件功能说明书(Functional Spec),主要用来说明软件的外部功能和用户的交互情况(把软件当作一个黑盒子)
2. 软件技术说明书(Technical Spec),又叫设计文档(Design Doc),主要用来说明软件内部的设计规范(把软件当作一个透明的箱子)
②写好一个Spec
第一,定义好相关的概念
第二,规范好一些假设(Assumptions)
第三,避免一些误解,界定一些边界条件
第四,描述主流的用户/软件交互步骤
第五,一些好的功能还会有副作用
第六,服务质量的说明
第十一章 软件设计与实现
11.2 图形建模和分析方法
思维导图、实体关系图、Use Case Diagram
11.3 其他设计方法
形式化的方法、文学化编程
11.5 开发阶段的日常管理
第十二章 用户体验
12.1 用户体验的要素
用户的第一印象
从用户的角度考虑问题
软件服务始终都要记住用户的选择(长期的使用只会使软件更好用)
短期刺激 长期影响
不让用户犯简单的错误
注重用户体验和质量
情感设计
12.3 评价标准
对于一个软件的用户界面,我们有没有什么评价标准呢?可以参考费茨法则(Fitts law)、Nielsen启发式评估十条原则以及其他经验。下面是邹欣老师在自身实践的基础上总结的一些原则:
1. 尽快提供可感触的反馈系统状态
2. 系统界面符合用户的现实惯例(Familiarity,Avoid Surprise)
与用户沟通,软件系统要使用用户语言而不是开发者语言,所用的概念要贴近生活实际,而不是用学术概念或开发者的概念。我们说的生活实际,最好是目标用户的实际生活体验。
3. 用户有控制权
操作失误可回退,要让用户可以退出软件(很多软件都没有退出菜单,这是导致用户反感的一大原因)。用户可以定制显示信息的多少,还可以定制常用的设置。
4. 一致性和标准化
在软件中,对同一事物和同类操作的表示用语,各处要保持一致。例如,某词典软件有“帮助用户收集生词并且背诵生词”的功能。这个功能要有明确一致的称呼,不能混杂着叫“单词本”、“生词本”、“Word List”、“Word Book”、“单词文件”……等等。
5. 适合各种类型的用户
6. 帮助用户识别、诊断并修复错误
7. 有必要的提示和帮助文档
不需要文档,用户就能使用自如,当然更好,必要时还可以提供在线帮助。如果软件和用户的工作相关(而不是简单的游戏),那么基本的提示和帮助文档还是很有必要的,而且也要提供便利的检索功能。文档要从用户的角度出发描述具体步骤,并且不要太冗长。
第十三章 软件测试
13.1 名词解释
Bug :软件的缺陷
Test Case :测试用例。测试用例描述了一个完整的测试过程,包括测试环境、输入、期望的结果等
Test Suite :测试用例集。即一组相关的测试用例
13.2 Bug解释与实例
①Bug可以分解为:症状(Symptom)、程序错误(Fault)、根本原因(Root Cause)
症状:即从用户的角度看,软件出了什么问题
程序错误:即从代码的角度看,代码的什么错误导致了软件的问题
根本原因:错误根源,即导致代码错误的根本原因
②Bug例子
症状:用户报告,一个windows应用程序有时会有在启动时报错,继而不能运行
程序错误:有时候一个子窗口的handle有空,导致程序访问了非法内存地址,此为代码错误
根本原因:代码并没有确保创建子窗口,因此子窗口的handle变量有时会在访问时处于未赋值状态(为空),导致出现代码错误
13.3测试方法
①黑箱:指的是设计测试的过程中,把软件系统当做一个“黑箱”,无法了解或使用系统的内部结构及知识。一个更准确的说法是行为测试设计,即从软件的行为,而不是从内部结构出发来设计测试
②白箱子:指的是在设计测试的过程中,设计者可以“看到”软件系统的内部结构,并使用软件的内部结构及知识来选择测试数据及具体的测试方法。
第十四章 质量保障
14.1 软件质量
软件 = 程序 + 软件工程
软件(质量) = 程序(质量) + 软件工程(质量)
14.2 软件质量的保障与软件的测试
软件测试:运用一定的流程和工具,验证软件能实现预先设计的功能和特性,工作的流程和结果通常是可量化的
软件质量的保障工作:软件团队为了让软件达到事先定义的质量标准而进行的所有活动,包括测试工作
第十五章 稳定和发布阶段
15.1 从代码完成到发布
第一步:开发者提交参加会诊的Bug和修改方案,以及伙伴测试结果。开发者必须向与会者报告的是:
- Bug是什么
- 危害是什么,如果不修复,有何后果
- 用户会有什么变通办法
- 是否经过代码复审,是否经过伙伴测试
第二步:会议决定是否同意修改方案
决定哪些缺陷必须现在就进行修复,哪些可以推迟到下一个里程碑。会诊应该对每一个修复选择下列处理方式。
- Must——必须修复,缺陷很严重,修复方案可行,相关的测试都通过
- More Info——需要更多的信息
- No——不能接受,可能是推到下一个里程碑,可能是提出的解决方案不符合要求
- Like——可能,不一定必须修复,但是解决方案相对比较安全。在更复杂的项目中,可以考虑引入这一个中间的状态“Like”(在相对简单的系统中,这个选项可以不用)。如果在今天的会诊中有“Must”,那么处于待命状态的“Like”修复就可以一起集成到代码库中。如果没有“Must”级别的修复,那么“Like”级别的修复就只能处于“待命”状态,直到以后出现了“Must”级别的修复为止
第十六章 IT行业的创新
影响产品竞争的各种因素
- 产品行业的因素
这是影响产品发展的最重要的因素,2012年流传着一句俗话——“站在风口上,连猪都可以飞起来”,就是说明产业发展的成长期(竞争产品少,市场空间大,用户容忍度强)能给产品提供巨大的助力。相反,如果是在一个产业的衰落期进入这个产业(例如,在2008年做小灵通手机业务,在2013年进军网络团购市场,等等),那么就会面临巨大的发展阻力。 - 公司和市场因素
公司在目前目标用户中的品牌号召力如何?公司的现有市场能力如何?现有的市场能力能帮助打开新的领域么?从传统的产品开发角度来看,“市场”总是在产品之后才出现,而且和“产品开发”似乎没有直接的联系。但是从长期来看,产品的质量就是最有效的市场能力,产品经理往往就是市场经理。 - 团队执行因素
根据产品特性的不同(基础软件、企业管理软件、行业通用软件、办公软件、互联网服务软件、移动应用软件等),商业模式不同,团队的战略也会不一样。在正确的时间,有正确的产品,却执行了错误的策略,或者不能做出决定,那么产品也会失败。执行力的一个有效衡量标准是一个决定需要多少次会议才能达成。一些团队对市场展现的机会往往陷入过度的分析和评价,力争要弄清所有情况再动手,最后的结果是动不了手。这是“分析麻痹”(Analysis Paralysis)。 - 产品的价值因素
产品给用户带来什么价值,这是和“软件工程”最相关的内容。考虑新产品或产品的新功能时,团队要问:我们给用户带来了什么价值,这个产品是提供了独家的价值,还是“人有我也有”的价值?这个价值足以让本产品和目前市场上已有的产品区分开么?我们怎么能进一步放大产品差异性?让我们越来越领先,或者让用户觉得我们很领先?我们是否在非差异化功能上花费了太多时间和资源?
第十七章 人、绩效和职业道德
①RASCI模型
R:Responsible,负责把具体事情做好
A:Accountable,对任务负全责,有批准的权利
S:Support,对任务提供支持,辅助任务的完成
C:Consulted,咨询,拥有完成项目所需的信息或能力的角色
I:Informed,知会者,应该事后及时通知结果的角色
②团队合作的阶段:
(1)萌芽阶段,就像小苗破土而出,柔弱但充满希望
(2)磨合阶段,就像一个人的青少年时期,充满了对个人、同伴和团队的疑惑和冲突
(3)规范阶段,从磨合阶段毕业,进入规范阶段的团队,成员们意识到光争吵时没有用的,大家还是要协同作战
(4)创造阶段,经历了萌芽、磨合、规范阶段,现在团队终于可以创造一些有意义的东西
③不管从事哪一个职业,不管你是属于哪个岗位上的,都必须具有职业道德,软件工程师同样也需要
后记和个人感想
这本书的作者邹欣老师在微软公司工作,他在整本书中把对软件构建的方方面面都写得很清楚,包括需求,设计,开发,测试,项目管理......甚至国内很多公司都无法做到像书中说的流程那么全面和到位。作者的思路很清晰,文字也很有趣,让人欲罢不能。全书都有很大的参考价值,至少对于我目前这样的状态的程序员来说,了解自己要怎么做,做的方向比要做什么更重要,本书提供了很多建议和方法,比如PSP(Person Software Process,在我看这本书之前,完全没有听说过PSP这个东西,),也由此了解到作为一个软件工程师,任务清单里面不仅只有要编好程这一项而已,还有计划,需求,测试,评估工作量等能力需要刻意培养。
这本书最具特色的一个地方是把很多生涩难懂的概念用学生之间对话的诙谐幽默、生动风趣的场景来展现了出来,甚至还加入了一些电影中的经典台词、一些足球术语和篮球明星的专属名词,让我这个电影迷足球迷篮球迷一边读一边大呼过瘾,更开心的是学习到了很多知识,尤其是在软件工程项目开发过程中的许多技巧和需要注意的问题。例如在第五章讲解软件团队模式的时候用足球队的守门员、前锋、中场和后卫来类比,非常容易理解,不仅有趣而且易懂;再比如在第八章的需求分析中的人类学调查的讲解中,利用一个软件工程课上的同学的顿悟生动形象地讲解了人类学调查这个晦涩难懂的知识点。这本书还创造了很多有趣的人物形象:老成的项目带头人阿超、知识总是马马虎虎掌握的果冻、爱好丰富的小飞和产品经理小李,每个人物都很饱满,读这本书的时候也很容易让我这个读者产生代入感,读起来自然又快又让我印象深刻。
书中让我最茅塞顿开的地方是第二章的个人技术和流程以及软件工程师的成长,改变了我长期以来对我这个专业发展方向的很多困惑和误解,我一直觉得我作为一个程序员只要学如何写代码,顶多把数据结构和算法掌握清楚、操作系统和计算机网络的知识学习扎实,会写前端会折腾数据库就可以了,其他的能不了解就不用了解。我对于职业规划还一直还停留在学好算法计算机基础就可以进大公司的非常低级的想法层面上,读了这本书之后我才明白自己其实离一个优秀的程序员还差得很远,虽然我一直在努力为实现进入大公司成为优秀的软件工程师这一目标而努力,但是其实努力得还远远不够,而且光局限自己把代码写好是远远不够的,团队协作、小组敏捷开发、迭代会议、单元测试和代码复审这些部分都是我之前完全不了解的,而在我读完以后更有针对性和方法来实现自己的目标,开始关注踏实的学习和提升自己,并更加注意和身边的同学合作写代码并和自己身边的同学一起互相学习,这也提示我这样的初级软件工程师要如何让自己成长起来。
另外,我们这学期除了学习软件工程的理论外也在做一个团队项目,而我正是我们整个项目的Program Manager。这本书中所介绍的NACBD模型、分而治之方法、敏捷开发小组会议和燃尽图、结对编程这些方面的知识点和技巧我们都很好地应用到了自己的项目开发的整个过程之中去。我们每个人小组成员都利用NACBD模型在组内会议中分析了自己所想要用的一款软件,通过对比我们最终决定做一个桌面应用软件;我们通过分而治之的方法,利用WBS图拆分我们的需求,然后利用甘特图,结合每个组员的承诺工作时间把所要实现的所有功能具体化到每一天每一小时;我们在冲刺阶段采用了结对编程的方法,而且还实现了敏捷开发,并完成了至少2天一次的冲刺会议,每个人汇报自己的工作并展望第二天要做的事情,然后完善燃尽图;而且我们团队利用码云托管平台来管理代码,每个人做自己的模块,并保证一天至少merge一次所有人的分支,大大提升了团队协作的效率,每个人都完成了什么工作也是一目了然。可以说《构建之法》这本书对我们的团队的整个开发进展阶段都具有相当强的指导意义,也算是我们进行正式软件开发项目的一本入门引导手册了。
最后,《构建之法》的正文以及练习与讨论中有大量有价值的引用,这些内容可以让我们了解更多更广的知识,练习中大量的习题如果都能够独立思考并想办法解决的话,对我们的实际动手能力会有很大提升。
总之,这是一本值得反复阅读的技术书、一本可以教会我们怎样去做好一名合格软件工程师的书、一本无论是对在校学生还是一线软件工程师都会受益的书、一本很适合阅读并且反复阅读的书。很感谢何老师在软件工程这门课上为我们推荐了这么一本好书。