深入核心的敏捷开发

前言

  • 从2015年看板和敏捷SCRUM的引入,到2019年7月全面规模化精益研发转型,招行经历了四年多的时间。
  • ThoughtWorks全球团队怎么做敏捷,我们商定了一个“60%Scrum+40% XP”
  • ThoughtWorks敏捷开发的核心原则:价值驱动与技术卓越。
image-20210219145336644
  • 开发人员贴在显示器前彩色的任务拆分小纸条
image-20210219145358123
  • 常用的工具是燃起图(Burn-Up)和累积流量图(CFD来源于Kanban)。
  • Scrum的燃尽图并不推荐,原因是很容易营造一种遵循计划的假象。对于客户/业务和项目管理者,从燃起图能够看到实时需求范围的变化,按期交付风险也能够实时推测。
  • 累计流量图在成熟团队广泛应用,它能够直观告诉开发团队瓶颈在哪里,驱动改进。
image-20210219145922348
  • ThoughtWorks由于历史原因,用各种平台都有,目前最多的是Jira、Mingle和Rally。但实际上这些平台主要还是为了方便离岸敏捷交付团队,本地的交付团队很多是物理墙+Excel(或Trello)。
  • ThoughtWorks持续集成纪律有两个核心
  1. 第一是必须每次提交触发构建;
  2. 第二是每次提交必须基于上次的成功构建

这两条纪律是底线。

image-20210219145955374
  • 如果有人说哪个团队CI红着没有修复,基本就等于说这个团队没有干活儿,因为理论上对着失败的构建提交代码是无效的
  • 主干开发的代码管理成本是最低的,但同时也引入了较高的代码实践能力和协同纪律的要求
  • ThoughtWorks开发团队有共识的是测试前置,落地过程中有两个经典方法,即开发的TDD和提前验收(提前验收或叫Shoulder Check)。
  • 但先写单元测试是ThoughtWorks程序员基本素养。代码走查形式多样,但成熟团队一般都从单元测试开始,如果你跟骨灰级程序员新老头走查,他的第一句会是“给我看看你的测试。”
  • 大家对代码走查和结对编程这些开发过程中的质量实践更看重,但这些实践的频繁运用在很多团队都受到了成本的约束,并非普遍。
  • 一个团队的代码集体走查现场
image-20210219150200493
  • 开发人员的结对开发,往往会达到1+1>2的效率增长
image-20210219150214232

基于效能和周期时间的持续改进

  • 持续改进是每个团队必须做的,Retro(回顾会议,全称Retrospective)是基本形式,回顾的内容很多,从交付质量、实践到团队氛围。但实质上最基本的改进还是围绕Velocity(即迭代交付的Story点数)和Cycle Time(交付时间)。
  • Kanban告诉我们流速快的团队效率高、响应力快。如果不注意Cycle Time而去“改进”(Velocity),很可能造成更多的WIP(Kanban引入的“在制品”概念)堆积在迭代内,最后大家赶工埋下质量隐患,得不偿失。在ThoughtWorks两个百人以上规模的大型团队合用中,都强调团队集体学习Kanban实践。
  • 一个团队三个半月的累计流量图,体现了某个阶段的WIP和交付周期时间并分析潜在的问题
image-20210219150315347

基于客户深度参与的统一团队

  • “站会”:都能够体会到这种模式下快速建立的信任关系。
  1. 迭代站会不超过15分钟
  2. 需求澄清每次不超过一个小时
  3. 展示会一个小时以内
  4. 回顾会不超过两小时

ThoughtWorks敏捷开发管理体系

  1. 需求管理:包含从需求澄清到需求最终实现的整个生命周期。
  2. 技术管理:包含开发、测试技术的选择和运用。
  3. 质量管理:包含开发过程中的质量管理及软件交付前的质量保障。
  4. 迭代管理:包含开发团队迭代运作规则及纪律。
  • Story的质量其实是一个核心问题,ThoughtWorks从来不提倡一句话Story描述,即仅仅表面上遵循了As…I want…So that的经典模式,验收条件对于一个Story来说至关重要
image-20210219150455375
image-20210219150521220

  1. 《代码管理核心技术及实践》
  2. 《敏捷软件开发:用户故事实战》
  3. ThoughtWorks洞见网站 :https://insights.thoughtworks.cn
  4. Thoughtworks洞见公众号

第1章 敏捷宣言到底有几句

敏捷软件开发宣言

  1. 我们一直在实践中探寻更好的软件开发方法,身体力行的同时也帮助他人。由此我们建立了如下价值观:
  2. 个体和互动 高于 流程和工具
  3. 工作的软件 高于 详尽的文档
  4. 客户合作 高于 合同谈判
  5. 响应变化 高于 遵循计划
  6. 虽然右项也具有价值,但我们认为左项具有更大的价值。

第2章 开发人员的客户思维

  • 在团队中,只有所有人都对业务有一致的理解,所有的努力都朝着一致的方向,才有可能获得成功。
  • 有客户思维的开发人员,能够把工作当作为客户提供服务:自己是服务提供方,而同事和老板就是客户。他们积极地从客户角度思考需求的真正来源,在开发过程中与客户保持沟通,适时给出合理的建议。
  • 不管是工程师提前想到了这个结论,还是与产品经理及时沟通了自己的技术方案计划,都可以提早防止浪费。

第3章 基于统一迭代节奏的全功能团队

自组织全功能团队

  • 为了尽量缩短每一辆车从开始装饰到完成交车的整个过程,也就是缩短单个车的Lead Time,我观察到整个团队是在以一种几乎完美的方式协同工作。
  1. 首先,所有的工作被高度并行化。例如我的车最多的时候有四个人在同时施工,一个人在缝真皮方向盘套,一个负责贴车左侧窗户的膜,一个负责贴车右侧的膜,一个负责贴前后挡风的膜。
  2. 其次,大家并没有清晰的角色划分,缝方向盘套的人在完成手头的工作后,立刻自觉加入到贴膜的工作之中;而两侧的膜贴完后,两名工人立刻开始帮车打蜡和做内饰清洁;整个过程自然而连贯,完全自组织,
  3. 所有人都掌握了缝方向盘套、贴膜、打蜡和内饰清洗的工作技能,并没有严格的角色分工,很难说清楚谁是贴膜师,谁是打蜡师,他们每个人都像一个专业的全栈工程师。
image-20210219151351527

领导与管理

  • 一头扎进充满烟雾车厢的人就是这家店的老板。是的,他还是我上面提到的四名工人之一,分别完成缝方向盘套、新车除味和右侧的贴膜工作。
  • 在我的眼里,他就是一个称职的带头人。凡事冲在前面,以身作则,勇于承担一些困难甚至危险的工作。
image-20210219151418703

团队的精进之道

  • 把项目成功交付看作能力建设的副产品”口号的一种朴素实现。
  • 在ThoughtWorks,我们认为,软件开发中的一切问题,根本上都是人的能力问题。如何发展每个成员才是问题的关键。如果成员没有进步,始终是治标不治本的。
  • 团队的精进之道就是把交付过程中的一切活动都看作能力建设,把整个团队构造成促进每个成员成长的生态系统。
  • 一个人要划任务、估时间、在做的时候计时、根据实际结果进行反思。我们可以把这个方法做成非常邪恶的、仿佛流水线上工人的强制要求。我不关心你为什么超时,就通过这种方法来控制程序员,要求每个人都严格按照一个死板而僵化的步骤做一些简单重复的机械动作。也可以用这个方法来锻炼一个人的自我认知和发现知识漏洞等能力,促使他以最快的速度成长,等他成长起来马上给他更重要的任务,比如评估技术、评估项目、带新人、做架构等等。
  • 这其中的不同早在很多年前,就被一些大牛们观察到,作为敏捷宣言里的一句话表达了出来:“个体与交互 高于 流程和工具。”

第4章 基于用户故事的需求及范围实时管理

估算的目的

  • 所以,任何时候想做估算时,都应当非常清楚哪一项决策需要依赖这个估算。如果你找不到这样一项决策,或者那个决策并不是那么重要,这就是一个信号:此时做估算是在浪费时间。当你找到这样一个决策时,那要知道问题的上下文是什么,为什么估算会很重要。同样还要搞清楚期望的精度和准确性。
  • 估算是有适用期限的。我曾经记得有一位经历颇丰的项目经理说过,计划和估算就像是生菜,刚过几天还很新鲜,过了一周有点枯萎了,几个月后就完全看不出来是什么了。

需求风险的坏味道和对策

  • 作为一个大型项目的负责人,一旦进入交付落地阶段,就应该进入“风险模式”。
  • 而“控制需求”成为了“控制风险”中最重要的一环,换言之,对于一个失败的项目而言,需求未得到有效的控制,往往是最重要的原因。

识别坏味道

  • “这个需求我们实现过,只需要一周时间就可以完成。”

一个优秀的项目管理者首先需要做的是让客户完全了解你的工作量估计系统是如何工作的,并不断强调你的工作量估计是合理、公平和有效的。

  • “关于这个需求,你做个方案给我选一选。” “这两个方案我都不喜欢,要不你们再想想?”

这代表你的客户不理解在软件开发中,“需求分析”也是工作量的一部分

  • “这是领导要的,我也没办法。”

这代表你的客户正在抛开自己的决策责任,尝试用最不负责任的方式逼迫你答应需求,一旦成功,这种行为就变成一个肆无忌惮的借口。

  • “没有这个功能,我们不能上线。”

必须据理力争,请坚信,没有阻止上线的功能,只有阻止上线的、不理智的、缺乏安全的客户。

尽可能靠近决策者

  • 软件工程同样是一个“社会工程”,软件项目的失败往往是因为其社会性的复杂,导致身处其中的人无法处理所负责的合作、组织、政治和职责关系。

  • 在上一个客户中我们做了以下几件事情。

  • 为客户包装向他的上级汇报的PPT

  • 总结他的上级的想法,例如用可视化的方式概括他的上级在说什么

  • 将工作过程拍成视频,供他在组织内传播

  • 每周一次Newsletter,制作一些易于传播的图片和小视频等。

  • 使得你和你的客户不再是甲乙方的关系,而是合作者,明确这个地位,才是接近决策者的重要意义。

做系统决策人

  • 一个优秀的系统决策人需要对以下决定产生影响。
  1. 是否应该引入新的概念
  2. 是否应该将某一概念变复杂
  3. 是否应该建立新的关系
  4. 是否应该将某一关系变复杂
image-20210219152008858

不要给选择

  • 给选择的目的永远是让客户选择我们期待他选择的那一项,如果不给选择也是其中一个选项,那么尽量不给客户选择。
  • 我所使用的策略有如下几种。
  1. 采用完美的系统思维逻辑帮助客户认定我们选定的就是最优选择
  2. 对我们的方案给出完整的思考和选择过程、而不是最终方案而已
  3. 给出大量的假设让客户认为反正都不知道最后结果是怎样,选什么其实都没那么重要
  4. 最后才是给出多个方案,对优缺点进行分析

管理结果而非解决方案

image-20210219152104077
  • 切记,不是因为东西难就不做,也不是因为东西简单就做,而是思考一个需求对于整体结果的影响。
  • 需求是结果的副产品,应该由产品经理、设计师、架构师来保证,你只需要和客户讨论最终产品在多大程度上可以满足预期的结果。
  • 如果没有影响,无论有多简单,都不应该做,如果至关重要,无论多难,都应该完成。

建立游戏规则

  1. 没有东西是免费的:所有东西都是有价格的,花时间的,这里包括需求的讨论、编码、改动、测试、调试、沟通等等。
  2. 讲不清楚的需求很可能是没价值的
  3. 这是系统思考:任何一个新概念的产生或者一个新关系的出现,都意味着系统其他部分的成本、变动、甚至破坏,谨慎一切新概念、新关系的产生。
  4. 社交游戏:复杂问题最终都是复杂的社交游戏,能通过政治或者社交解决的问题,尽可能不用技术解决,
  5. 每个阶段都有该阶段专属的规则:特别在需求的前期,讨论越多需求,流入后期的需求范围就越大。在一开始就应该建立“需求规则”的概念,什么该谈、什么不该谈,而不是简单跳过
  6. 交付大于一切:永远不进行项目延期,目标是在交付期中保证交付既定的结果,而非之前约定的需求列表,可以容忍瑕疵、但不容忍延期。
  7. 尊重估算:不要尝试花时间质疑估算,你所有的怀疑会变成工程师巧妙的“套路”,他们会在另外的地方找补回来,反正你不懂,若相信,请深信。

需求的冰川

  1. 用户需求:从用户自身角度出发产生的“自以为的”需求
  2. 产品需求:由综合提炼用户的真实需求而产生的符合组织和产品定位的解决方案。
  • 让产品从能用到好用,恐怕第一大忌就是“想当然”。

用户研究与验证

  • 他们不是不愿意做好用户研究与验证,而是不一定具备这种能力;即使做好了,也很难知道如何准确地把合适的信息传递给业务分析师和交付团队。 我们不止一次地强调复合型人才对产品构建和组织转型的重要性,在需求分析领域,用户研究和验证或许是呈给业务分析师的第一份考卷。
  • 我们不止一次地强调复合型人才对产品构建和组织转型的重要性,在需求分析领域,用户研究和验证或许是呈给业务分析师的第一份考卷。

『了解用户』无法一劳永逸

  • 在产品进入稳定的交付阶段后,业务分析师应该继续积极了解用户,不断验证并挖掘需求;用户和环境都在改变,该重新组织产品规划设计工作坊的时候,不能搪塞了事。

保持好奇,保持初心

  • Stay hungry,stay foolish
  • 面对客户的需求,多问一个为什么;面对用户的答案,多想一个为什么;能最大程度地避免“想当然”,或许就能最大程度地做好“用户研究和验证”。

浅谈软件项目规模估计,到底在估什么

  • 尼尔斯·玻尔说过:“预测是一件非常困难的事情,尤其是预测未来。”

非功能需求

  • 非功能需求更需要引起我们的重视,这往往是项目最容易忽略而掉到坑里的地方。
  • 最基本的要考虑以下两点。
  1. 浏览器的兼容性问题:兼容哪些浏览器和兼容版本?
  2. 移动端的兼容性问题:兼容哪些手机设备、操作系统和版本号?
  • 除此之外还包括性能、可维护性、可测试性、可用性、可移植性及可扩展性等

开发部署环境

  • 包括但不限于CI环境、开发环境、QA环境、SIT环境、UAT环境、Pre-Prod和Prod环境。

与三方的集成

  • 集成往往不是个小问题。目前的软件项目,往往都是基于现有的系统进行开发,所以集成的工作必不可少。契约的制定、数据的迁移、其他供应商三方系统开发工作的推进以及接口的集成联调等,往往都是项目全周期的工作重点。

测试

  • 敏捷项目中的测试,与传统先开发再测试这种方式极为不同的一点是:没有固定的测试人员,而是全员来保证软件的质量。
  1. 自动化测试,包括单元测试/集成测试/功能测试
  2. 迭代内探索性测试
  3. 业务回归测试
  4. 性能测试
  5. 安全测试
  6. 代码质量测试

验收交接流程

  • 软件的整个验收流程、代码交接、文档撰写工作,

软件项目规模估计,怎么估?

估计者的估算的点数是否能代表团队估算的点数?

  • 在估计的过程中,至少要引入新手,能够从不同经验的角度来看待同样的问题,使估计不会过分“乐观”。

是否有故事卡片之外的工作时间没有考虑到?

  1. 回复电子邮件(沟通成本)
  2. 面试(内部耗损)
  3. 参加会议(包括内部会议,比如站会、retro、code diff、技术研讨会议和客户沟通会议等)
  4. 为当前发布提供支持(上线支持)
  5. 培训?(内部的)
  6. 任务之间切换/被人打断(程序员出栈入栈的消耗……)
  7. 修复bug(一定会有bug,一定会花时间修……)
  8. 写各种文档(对于比较看重文档的客户,这一部分会占用不少的时间)

故事卡的需求是否清晰呢?

  • 往往只考虑了最简单的快乐通道(Happy Path),然而大部分项目中(尤其是ToB项目),异常才是相对复杂的,这些异常情况往往需要花费更多的时间完成。

问题可能的答案

  1. 首先,要进行集体估计。集体估计可以缓解因为个人能力不同所引发的单点偏差,不同开发成员对某个需求从不同角度进行的阐述,也容易让大家对需求有更全面的理解,也易于发现潜藏在需求中的风险。
  2. 其次,是方法。《敏捷估算与规划》介绍了两种基本的方法:理想人天法和故事点法。

理想人天法

  • 就是“在需求非常明确的情况下,进行编码和测试工作所花费的时间”。
  • 在实际应用中,在估完理想人天之后如何进行实际人天的换算仍然是个大问题,所以……最好不用。

故事点法

  • 点数代表的不是所需的人天,而更多的是难度系数。
  • 给项目加些缓冲(buffer)。缓冲分两种,一种是功能缓冲,一种是进度缓冲。

功能缓冲

  • 全部故事列表进行估计,假设得到总点数是100点,挑出其中的MVP(要少于总量的70%),作为必须要做(Must Have)的部分。剩下的30%作为做了更好、不做也不影响主要功能(Nice To Have)的部分,通过这种方式来缓冲项目里程碑的风险。

进度缓冲

  • 用来缓冲估计之外的异常情况引发的项目时间的拉长。
  • 不过根据Leach(2000)准则提出的建议,至少要保持整个项目的20%以上,否则也许不能为整个项目提供足够的保护。

不是小结的小结

  1. “输出高于结果”(output over outcome)。客户更关注功能列表的完成,而不是产生的业务价值。
  2. 开发团队倾向于裁剪用户故事的功能,3个点的故事卡,尽量控制在规定时间内完成,即使可以花更多时间把事情做得更好
  3. 控制需求变更。可以进行需求变更,但这个过程更像是一个异常的情况,而不是喜闻乐见的
  4. 当我们发现更好的业务点和想法的时候,会倾向于隐瞒,以免额外的业务功能会增加工作量。需求变更往往会涉及客户谈判,尤其是在客户观念是传统供应商管理策略时,即“我来控制需求的全景,能多做点就多做点”
  5. 在客户合作和谈判的天平上,客户关系会向谈判的方向倾斜。
  • 估计和计划会使团队和客户更多聚焦在工作量而不是工作的价值上。如果能够引导客户从输出导向思维转变为结果导向

  1. 《敏捷估算与规划》

第5章 基于持续集成和测试前置的质量内建

关于Gitflow

  • Gitflow是基于Git的强大分支能力所构建的一套软件开发工作流,最早由德里森(Vincent Driessen)在2010年提出。最有名的大概是下面这张图。
  • Github在企业软件开发中甚至不是一个最佳实践。
  • Gitflow太复杂。还对整个团队的纪律性提出了很高的要求。
image-20210219153531245

合并就是合并

  • 在软件开发的世界里,如果一件事很痛苦,那就频繁地去做它。比如集成很痛苦,那我们就每夜build或持续集成(continuous integration),比如部署很痛苦,那我们就频繁发布或持续部署(continuous deployment)。合并也是一样。

如果不用Gitflow呢?

  • Trunk-Based Development,那你应该先了解一下,赶紧用起来。
  • 所有的开发工作都在同一个master分支上进行,同时利用持续集成确保master上的代码随时都是production ready的。从master上拉出release分支进行release的追踪。
image-20210219153631172
  • 可是feature分支可以确保没完成的feature不会进入到生产部署呀!——Feature Toggle技术

  • 如果系统有一项很大的修改,比如替换掉目前的ORM,如何采用这种策略呢?你可以试试分支by Abstraction——分支by Abstraction。

改善单元测试的新方法

我们为什么要写单元测试?

  • 写单元测试的两个动机:驱动(如TDD)和验证功能实现。

基于用例的测试(By Example)

  • 单元测试最常见的套路就是Given,When,Then三部曲。
  1. Given:初始状态或前置条件
  2. When:行为发生
  3. Then:断言结果
  • 坏处。
  1. 第一是测试的意图。用例太过具体,我们就很容易忽略自己的测试意图。测试即文档,既然是文档,就应该明确描述待测方法的行为,而不是陈述一个例子。
  2. 第二是测试完备性。因为省事省心并且回报率高,我们更乐于写happy path的代码。

生成式测试

  • 测试方式“生成式测试”(Generative Testing,也称Property-Based Testing)。这种测试方式会基于输入假设输出,生成许多可能的数据来验证假设的正确性。
  • 假设我们不写具体的测试用例,而是直接描述意图,让程序自动生成入参并验证结果。

超越“审,查,评”的代码回顾

  • 代码回顾(Code Review)应该是软件开发团队“共同学习、识别模式和每日持续”的过程,而不是带有“审,查,评”等令人感到紧张气氛的过程。
  • 代码回顾的目的,是团队成员聚在一起共同学习,而不是相互“挑错”。在相互挑错的场合里,人的内心会本能地封闭起来,来抗拒那些针对自己的批评意见。
image-20210219153855821
  • 代码回顾的学习重点,是团队成员共同识别模式。这里的模式指的是程序员编写代码的习惯,包括“好模式”和“反模式”。像富有表达力的类名、单一职责的方法、良好的格式缩进等等,都是“好模式”。而像那些令人迷惑的缩写、几百行的一个类文件、负责的if-else嵌套等,都是“反模式”。
  • 代码回顾的形式,应该是每日持续进行的。因为只有这样,才能持续改进团队的代码编写水平。也需要将每日代码回顾的时间控制在半小时以内。因为代码回顾的重点是识别模式,而模式就是习惯,习惯在很少的代码中就能体现出来。每日的代码回顾仅需要在半小时内大家一起看200~300行随机抽取的当天写的代码就够了。
  • 下面是我在客户现场实践上述代码回顾的具体做法。
  1. 团队7~8位程序员,下班前半小时聚在会议室里,在一位主持人的引导下做代码回顾。
  2. 主持人问:“咱们今天回顾哪段新写的代码?”一位志愿者在投影仪上调出今天编写的一段代码的新旧对比图。
  3. 主持人说:“我们知道,如果代码编写得好,那么作者以外的其他的人就能在没有作者帮助的情况下读懂。我希望一位不是这段代码作者的志愿者,来为大家解释一下这段代码是做什么的。”一位非作者的志愿者上来逐行解释代码,并回答大家的疑问。
  4. 主持人等代码解释完后,问大家:“这段代码大家还有看不懂的地方吗?”
  5. 大家都看懂代码后,主持人问:“大家说说这段代码有没有好的编写模式咱们可以继续发扬?”
  6. 提完了好模式,主持人问:“大家说说这段代码有没有可以改进的反模式?”大家开始提反模式。注意,不要提谁是作者。
  7. 主持人在整个过程中注意计时,快到半小时的时候,可以这样结束代码回顾:“今天时间也快到了,代码回顾的重点在识别模式,而不是看全部的代码。希望大家继续发扬今天识别到的好模式。另外在明天做代码回顾时,把今天识别到的反模式改进为好模式。”

不做代码审查又怎样

  • 代码审查是一个很好的实践,可以帮助团队里的同学了解其他同学在做什么,可以分享项目的上下文,可以分享技术上的一些小魔法,可以发现很多潜在的代码缺陷,可以提高代码质量,还可以有很多很多好处……

沟通的收益和成本

  • XP中的结对编程(Pair programming)和现场客户(Onsite Customer)等。
  • 无论是20世纪80年之前就出现的PDCA环还是前两年大热的精益创业,都是在强调快速反馈和基于反馈的快速迭代,

测试金字塔

  • 和测试金字塔一样更靠近金字塔顶端的(例如迭代计划会)沟通频率越低,成本越高,但越接近业务;越靠近金字塔底端的(例如结对编程)沟通频率越高,成本越低,越接近实现。

交付价值高于遵循实践

  • 日本剑道有个心诀,叫“守破离”:“守”,最初阶段须遵从老师教诲,认真练习基础,达到熟练的境界;“破”,基础熟练后,试着突破原有规范让自己得到更高层次的进化;“离”,在更高层次得到新的认识并总结,自创新招数,另辟出新境界。

结对编程的正确姿势,你学会了吗?

结对编程

  • 极限编程首次被用于(当时Smalltalk领域的大师级人物)肯特·贝克(Kent Beck)1996年受聘领导克莱斯勒公司一个综合工资项目开发C3(Chrysler Comprehensive Compensation)中首次采用,并在1999年10月出版的《解析极限编程》一书中被正式提出。
  • 极限编程中的“极限”(Extreme)是指将我们认同的有效软件开发原理和实践应用到极限,
  • 软件从此不再是一个人单打独斗的工作,而是要求越来越多的多角色多任务的协作。软件行业的工作者必须要有比以往更多的沟通和协作技巧。而这对于习惯了一个人的软件开发者而言是一个巨大的挑战,必然要有一个改变和适应的过程。这也是为什么结对编程会成为最具争议的实践。

结对编程的好处

培养新人,促进沟通,提升团队整体能力。

  • 包括快捷键、算法、语法、SQL、设计、解决问题的思路、做事方式等,1对1面对面师傅带徒弟式的学习是新技能最快的方式之一。

更好的知识共享和信息交流,促进团队协作。

  • 结对中可以互相分享代码的上下文,交换对代码的理解,促进质量改进和团队协作,同时也使得代码集体所有制成为可能,减少团队对某些成员的依赖,降低团队风险。

促进团队成员的沟通,提升团队凝聚力。

如何进行结对?

image-20210219154222285
  1. 领航员和驾驶员(Driver-Navigator),键霸出没,请小心
  • 驾驶员编写实现当前任务的代码,而领航员需要引领代码的编写并负责审查代码。
  • 领航员通常还要考虑当前的实现方法是否正确,是否有别的做法,它是否会影响到其他功能模块,下一步是什么。
  • 合作场景:适应于各种组合,尤其一老一新组合。
  1. 乒乓模式
  • 测试驱动测试。结对双方可以一个人编写失败的测试,一个人写实现通过测试;然后交换角色,不断循环。对于结对双方经验相当的情况下,由于交互和交换的频率很快,就如打乒乓一般,
  • 合作场景:适用于各种组合,尤其是双方经验相当的场景。乒乓模式由于它的角色分工清晰,交换频率相对较快,
  1. 鼠标和键盘模式
  • 这是驾驶员和领航员的一种具体表现方式,其中一方使用鼠标,是领航员;另一方使用键盘完成代码的编写,是驾驶员。
  • 合作场景:适用于一老一新组合。

几点提示

  1. 多沟通:彼此尊重,多沟通。
  2. 确定开发任务列表。协商开发任务列表,能够提高对开发任务理解的一致性,确保开发节奏顺利进行。
  3. 定期交换小伙伴。定期交换小伙伴可以使得知识得到充分分享,
  4. 可持续的结对工作。真正的结对会比一人工作更专注,紧凑,所以一天8小时的结对会很累,比如一个小时或两个小时休息一次,从而保证可持续的工作。
  5. 多给新人机会。与新加入的小伙伴结对,需要耐心,多给予她/她上手的时间与空间。通常建议开始时多讲解,多展示,给她/他学习的机会;比如一开始可以由熟悉代码的小伙伴写测试,而新加入的写实现;随后可采用鼠标键盘方式或者乒乓结对方式。
  6. 勇敢加勇敢。对于新加入的小伙伴,如果跟不上怎么办?要勇敢地叫停,打断结对的小伙伴,弄懂这个问题,这样做才是达到了结对的目的。更推荐及时解决,当然,深度需要把握得当。
  7. 反馈。反馈往往是最后一环,也是最有效的一环,是帮助自己和结对小伙伴的必要工具之一,温暖的“小黑屋”是可以经常光顾的。
  8. 不是所有的场景都适合结对。对于那些结果需要维护,能够促进沟通、知识传递等价值的开发行为,都建议结对。诸如方案调研和一些非常简单的问题(微小的缺陷修复如拼写错误)等是可以不用结对。

第7章 组建人人深度参与的统一团队

开不好站会?因为不同阶段站会的目的不一样

  • 布鲁斯·塔克曼(Bruce Tuckman)的团队发展阶段模型
  1. 组建期
  2. 激荡期
  3. 规范期
  4. 执行期
  5. 休整期
  • 团队在不同的阶段,面对的问题不一样,站会作为一个团队实践,它提供的价值应该也会不一样。

组建期和激荡期:建立信任

  • 什么样的团队成员能得到其他人的信任呢?
  • 搞定问题的能力 积极主动的态度
  • 团队合作的意识
  • 我昨天完成了什么?我拥有专业能力,能搞定一些工作。
  • 今天准备做什么?我积极思考,主动承担任务。
  • 我遇到了什么问题?我不是万能的,但我信任团队,我会把搞不定的问题暴露出来。

规范期和执行期:关注价值流动

  • 软件开发过程中,对于一个功能特性,只有真正被用户使用才能产生价值。所以我们要尽量缩短从需求分析到开发、测试、部署的周期,而这其中一个很大的浪费就是“等待”。
  • 这时,我们可以采用看板推崇的“拉动”的方式,大家站在看板前,不再讲三个经典问题,而是以需求为中心,从看板的右边往左边,讨论每一个需求卡片的状态,以及还需要做什么才能移动到右边一列。

执行期:仪式感

  • 团队每天按部就班地工作,激情很容易流失,团队容易进入得过且过的状态。这时站会更多的是一个仪式,产品经理要经常分享产品在市场上的反馈,比如用户的表扬信,又新增了多少用户,产品又挣了多少钱等。让大家看到工作产生的价值,持续获得成就感。
  • 敏捷不是遵循“最佳”实践,而是要搞清楚实践在什么环境下解决什么问题,然后再合理地对实践进行裁剪和改进,这样才能保持敏捷力!

展示会的七宗罪

准备工作没做好

  • 浪费了很多宝贵的时间,尤其是对于PO等重要人物来说。

正确做法:充分做好准备工作

从业务的角度把整个要演示的功能尽可能串起来,准备好展示的步骤。 演示数据也需要准备好,展示的时候可以直接使用,只需要操作所演示功能部分,不需要临场创建准备数据。 演示环境要提前准备好,包括部署好需要演示的应用程序版本,而且要告诉团队不要破坏准备好的环境。

没有上下文铺垫

  • 既不先介绍一下要演示功能的来龙去脉,也不说明这个功能是干嘛的。

正确做法:开始演示前要先介绍上下文。

逐条过AC

  • 展示会的过程就是按照用户故事(Story)的验收标准(AC,Acceptance Criteria)一条一条地过一遍,没有连贯性。

正确做法:以功能为单位演示。

不要一个一个用户故事的演示,而是将整个功能串起来,

企图覆盖所有路径

  • 在系统功能中,通常会有“用不同路径实现相同或类似功能”的情况,比如一个上传文件的功能有多个入口,
  • 有人在演示这个文件上传功能的时候,企图把所有入口的文件都完整演示一遍,

正确做法:只演示最关键路径。

过多提及跟演示功能无关内容

正确做法:只提及要演示的功能。

展示可以考虑只演示最主要的功能,那些小的反馈就不需要展示了,

也不要提及任何还未完成的功能模块,特别是对于团队正在开发的技术卡或者还不成熟的技术方案等,一定不要提及。

认为展示仅仅是BA或QA的事情

正确做法:人人都可以展示

尽量多参加展示会,这是一个了解系统、听取客户反馈的绝佳机会。

不熟悉的新人负责展示

正确做法:展示前先充分了解系统和业务

但不建议采用给青涩新人提供展示机会的方式来帮助他们提高能力,如果要给新人锻炼机会,可以让新人在结

浅谈敏捷离岸团队沟通

按需互访

image-20210219154843532
  • 合作双方的互访则是建立信任的捷径,通过这扇窗户

  • 一方面可以了解双方的企业文化、工作习惯用到个人的性格特点

  • 另一方面能够利用面对面工作坊高效梳理规划,最大程度保证后续项目推进方向的正确性。在条件允许的情况下,在项目伊始就建立互访机制

  1. 在项目的重要节点,例如合作初始、项目里程碑、检查点进行在岸交流
  2. 设立双向固定互访周期,如每三个月/半年

巧用工具

  • RealtimeBoard:如果让我列举『2017年度最好用工具』,它一定榜上有名:它是我目前能找到的最好的贴板,是组织远距离工作坊的最佳搭档
image-20210219155206818

第8章 为什么你的Scrum会失败

三个角色

角色一:PO的任职资格

  • 如果是一个产品项目,面向多个潜在客户,那么你们组织中谁对产品的成败负有首要责任,谁就是PO

角色二:Scrum Master的悖论

  • Scrum Master的使命就是把自己做没,不是做媒,是做没
  • 教会团队自组织、教育PO、教育开发团队、教育组织里其他干系人。评价教练的唯一标准就是被教的人不再需要他/她了

角色三:开发团队自组织的假象

  • Scrum团队不是自组织,而是没组织。原先的职责随风而去,现在统一称团队(Team)

四个会议

Sprint计划会议:实际上就没课分开的两个会

  • 计划会议有两个主题:做什么(What)和如何做(How)

IPM

  • 某种程度上是不需要开发团队参与的。PO应该根据干系人的输入,从业务优先级上选出下个Sprint的Backlog。这个过程可称为IPM(iteration planning meeting),应该在本Sprint开始前进行,也就是推荐在上个Sprint的末尾进行,PO完全可以一个人搞定或者跟业务方的干系人来商定,具体如何取决于PO

IKM

  • IKM(Iteration Kickoff Meeting),在本Sprint开始时进行,主要目的是PO和开发团队对这个sprint的目标进行交互,解释、答疑和达成共识

总结一下,PO自己搞定规划,PO和团队一起开工,团队自己搞定怎么做。IPM不占开发团队时间

每日站会:关注接力棒,而不是运动员

  • 站会正确的关注点是:进度、障碍、新知及是否要进行调整
  • 站会是以天为周期的PDCA环中重要的一步,负责检查和提出行动建议
  • 评价站会效果的唯一方式是,会后有没有根据会上的信息做出相应调整

Sprint回顾会议

  • 只要回顾会议有效果,其他问题再大都是小问题。当回顾会议没有效果的时候,问题就大了
  • 站会/回顾/评审会议,都涉及调整。开完会后没什么调整,这个会就白开了

第9章 技术领导者即服务

  • 技术领导者(Tech Lead)需要扮演三种重要的角色
  1. 技术决策者
  2. 流程监督人
  3. 干扰过滤器

责任拆解

  1. 制订适合该项目要求的技术方案。他要参与架构设计,了解平台和编程语言、主要的框架和库、集成点、部署策略、数据迁移策略,确认总体技术方案能够支撑系统的业务要求
  2. 保障交付顺利开展。他要确保环境的一致性,搭建和管理持续集成流水线,指导并监督团队遵循持续集成的流程和实践
  3. 管理和提升团队的能力。需要确认团队是否熟悉用到的技术栈和工具,帮助团队成员组织刻意练习来提升能力

技术栈管理

  • 只有方案、交付、能力三者有很好的协同,项目和团队才能健康成长。
  • 制订组织统一的技术栈,并从技术栈推导出对应的能力评估模型和刻意练习课程。就得到了下图所示的以技术栈为核心的IT能力三环联动模型
image-20210220075555803

第10章 项目管理中的敏捷实践

  • 项目管理中三个典型难题
  1. 团队目标不一致
  2. 团队成员不熟悉
  3. 信息发布不顺畅

敏捷的项目管理:追求最大价值的成功

  • 传统项目管理的定义是:『在有限资源限定的条件下,实现或超过设定的需求和期望』。一句话概括了传统项目管理的铁三角:需求是范围,资源包括时间和成本
image-20210220080207683

那么,这个定义是正确的吗?

  • 『传统项目管理铁三角』概念忽略了『价值』这一重要因素

用户故事

  • 一个用户故事通常包括三个要素
  1. 角色:谁要使用这个功能
  2. 活动:需要完成什么样的功能
  3. 商业价值:为什么需要这个功能,这个功能带来什么价值

展示形式:作为一个<某种类型的用户角色>,我要<达成某些目的>,只有这样我才能够获取<商业价值>

  • 只有当所有AC(验收条件,Acceptance Criteria)被覆盖到,测试人员完成测试,发现所有功能是可测试的、可运行的,这个用户故事才算完成了
image-20210220080347937

估计和迭代计划

  • 需求优先级矩阵
image-20210220080455746

站会和用户故事开卡

  • 站会的时候,介绍一种有意思的实践,使用Token,也就是使用一个实物作为『令牌』,准备发言的人首先取得『令牌』,发言完成后将『令牌』传给下一个人。令牌要醒目,可以是毛绒玩具,也可以是一顶帽子
  • 用户故事开卡(Story Kick-off)指的是在每个用户故事开发之前 ,要确保BA、DEV和QA对用户故事理解 一致。这个沟通活动通常表现为由DEV讲解这个用户故事要完成的功能及AC,一旦发现任何疏漏,BA及时补充。DEV有任何疑惑,也需要及时提出来,当场确认,使这些功能得以正确实现。在后续开发中如果碰到任何疑惑,也应及时找BA了解清楚。QA会严格按照AC来验收用户故事

代码审查和回顾

  • 代码审查(Code Review)是指开发团队在完成每天代码之后,聚在一起评审当天的代码,好处是
  1. 团队经过一天高强度的思考与编码,适当停下来,看看其他人写的代码,同时将自己的代码讲解出来,往往能获得一些意外的灵感,或许能解决自己面临的阻碍
  2. 互相了解设计思路,获得更好的建议和进行思路重构,提高代码质量
  3. 及早发现潜在缺陷,降低事故成本:如果这个时候发现代码的坏味道和一些需要改进的地方,代码审核结束后可以花少量时间进行更改
  • 回顾的关注点也多种多样
  1. 项目开发
  2. 敏捷成熟度
  3. 团队角色和职责
  4. 人员技能提升
  • 回顾的形式和方法非常多,最常见的是下图所示的Well & Less Well
image-20210220080924185

最大程度的可视化

  • 除了gefi表示项目状态、项目团队还会可视化其他的元素,比如团队应坚持的规则、项目上的经验分享以及项目的里程碑
image-20210220080938509
image-20210220081015663

沟通计划

  • Inception是启动软件设计和交付项目的方法,是通过集中式、互动式的设计工作坊,帮助客户在最短时间内对项目范围达成一致,快速进入项目交付。而Inception的一个产出就是沟通计划(Communication Plan)。比如在这个沟通计划中会讨论
  1. 以什么频率、什么形式作项目的更新。比如说每周五以周报的形式作一些主要信息的更新;
  2. 站会和迭代会议什么时候召开,需要邀请哪些人,比如业务负责人和技术负责人等
image-20210220081203821

团队目标不一致

  1. 用电子墙和物理墙展示 用户故事、需求全景图、项目进度燃尽图
  2. 通过迭代会议和功能演示会议对齐迭代计划,项目进度、识别项目风险

团队成员不熟悉

  • 基于敏捷实践,创造更多的沟通机会,比如回顾会议、代码审查和站立会议。通过不断创造这样的沟通机会让团队成员配合更默契

信息发布不顺畅

  1. 共享信息,制定沟通计划
  2. 最大程度的可视化

行为心理学家研究认为

  1. 21天以上的重复就会形成习惯。任何一个运作,重复21天就会变成习惯性的运作
  2. 任何一种想法,重复21天或者重复验证21次,就会变成习惯性的思维方式

结语

  • 剑道中有这样一个心诀:守、破、离
  1. 守:最初阶段须遵从老师教诲,认真练习基础,达到熟练的境界
  2. 破:基础熟练后,试着突破原有规范让自己得到更高层次的场景化
  3. 离:在更高层次得到新的认识并总结 ,自创新招数,另辟新境界

第11章 也谈精益

  • 精益思想为什么适合于软件行业
  1. 追求快速价值交付的小批量生产模式
  2. 追求极致卓越的匠艺文化
image-20210220081623286

第12章 团队敏捷转型的三个阶段

阶段1:建立敏捷流程,缩短交付周期

  • 这个阶段,引入迭代或者建立看板是重点
  • 主要目标是将需求的反馈、开发质量的反馈、以及改进周期缩短在一个迭代内
image-20210220081839788
  • 教练主要采取以下行动
  1. 培训,给团队培训敏捷流程、各角色的职责以及各种工具的使用
  2. 现场指导,先带领团队走完整的敏捷流程,通常会有几个迭代;然后观察团队自己执行流程,并帮助团队改进;最后不再参与这类活动
  3. 需求梳理,指导PO和BA建立需求全景图(比如用户故事地图)、拆分Story、排优先级以及和团队其他成员协作等;制定Story编写规范,Story价值流和建立Story看板
  • 主要培养目标:Scrum Master,让他们能了解 敏捷流程的运作方式,并能带领团队在教练不在场的情况下,依然按敏捷流程运作

阶段2:引入技术实践,质量内建,减少返工

  • 主要目标:提升开发人员的质量意识 ,从而提升开发阶段产出的质量水平,减少后续环节的返工。用质量内建的话来说,在缺陷时就立刻修复
image-20210220082126135
  • 为了提升生产过程的质量,减少返工,提高效率,我们会引入技术实践,以缩短质量验证的反馈周期,主要包括以下实践
  1. 单元测试
  2. 集成测试:包括API测试和组件测试、契约测试等
  3. UI自动化测试
  4. CI:将以上测试定期运行并可视化报告,让所有团队看到。同时要求团队第一时间修复CI
  5. CD:建立自动部署流水线到生产环境,并集成冒烟 测试,同时实现回滚
  6. Git:建立使用git规范,建立分支策略或者指导客户做纯主干开发,培训客户使用git高级功能
  7. Operation相关技术:指导客户实践蓝绿部署、云和容器、金丝雀发布等
image-20210220082335812

阶段3:提升价值交付效率和响应力

  • 目标:培养成员的自我提升意识 ,团队的自我改善能力,并帮助团队建立自我改进的习惯
  1. 更高级的能力建设:如引入微服务、代码共享和特性团队等
  2. 以教练指导为主:我们教的内容会变少,指导的内容会变多,会让客户自己组织更多的分享,鼓励客户自学,并建立学习型文化
  3. 与业务走得更近:团队可以更好地理解 业务,同时能给业务提供更有价值的建议,因此很多业务在决策早期就会引入技术团队的成员

第13章 绩效考核,敏捷转型的鸿沟

敏捷转型过程中的必然挑战

image-20210220082618053

绩效考核的困境

  • 传统绩效考核与敏捷价值观之间的冲突
  • 传统绩效考核已经成为敏捷团队走向成熟的掣肘
image-20210220082649891

如何破局?

正如《管理3.0:培养和提升敏捷领导力》所说,所有变革最后的失败都是管理的问题。应该把绩效考核这种管理手段当成『敏捷铁三角』中一角来对待,那就是调整约束

image-20210220082755692
image-20210220082903186

清华大学管理学教授宁向东一针见血地批出,管理,其本质就是关于如何『破局』的智慧。所谓『局』就是管理者周围的各种资源相互联系,相互作用的一种状态。以上约束,也是软件工程表现出来的组织复杂性,也是一种局

  1. 《管理3.0:培养和提升敏捷领导力》

第14章 一个交付故事

  • 调整团队结构,给予团队更大的自治,从而释放生产力,这是高效交付的秘诀
  • 每个成功的互联网公司都有一个基础平台来更好支撑和实施自己的业务战略,专注在如何提升开发团队的体验、关注在如何打造一个平台来为开发团队提供更多的自治,从而释放出更大的生产力

第15章 又一个交付故事

  • 技术领导者(Tech Lead)的倾向从追逐『正确』的决策,变成了开始作出『合适』的技术决策
  • 交易成本的不断降低,打破了壁垒,促进了无数的人投身创业一样,技术成本的不断降低,技术壁垒的不断降低,也会带来更大范围的结构性变化

比如自动化测试技术干掉了传统的测试部门,数据库的自动化技术干掉了DBA,部署、运营的自动化干掉了运营,云化、安全内嵌也许将要干掉采购和安全。当这些东西,因为技术的进步而标准化后,当全面的数字化平台就绪之后,那么剩下的就仅仅是业务解决方案、技术栈与实现代码了,王老师把决策权交给开发团队是一个自然而然的选择……


第17章 如何在团队建设工程师文化?阿里资深技术专家这么做

工程师文化的特征

小团队

7-12人的团队是比较适合的团队大小。有人用毕节团队来形容一个团队大小(两张比萨可以喂饱这个团队)。脸书和谷歌经常有两三个人的团队。小团队特征

  1. 不破不立
  2. 以少为多,精准打击
  3. 勇敢追求卓越

技术创新

技术决策权大

  • 尊重技术决策的前提就是信任技术决策

技术数据可视化

  • 圈复杂度、测试覆盖率、重复率等

分享多会议少

测试原则

  1. 用given/when/then语态写单元测试
  2. 要让测试代码更容易写
  3. 合理使用mock/stub技术,测试你要测的,让你的测试更有效
  4. 异步测试不要用sleep
  5. 最好的debug手段就是测试
  6. 单元测试耗时最短,多用单元测试覆盖代码逻辑
  7. 越是集成测试数量应该越少,因为代价很大,性价比不高
  8. 静态代码质量分析应该伴随每次持续集成

分支策略

  • 分支尽量少,持续集成越没意义,合并(merge)成本越高,团队分支最多也不能超过下图
image-20210220101910212

结对编程

  1. 一个主机,两个键盘,一个显示器
  2. 新老员工结对是新员工掌握实践的最快手段
  3. 结对让员工有机会互相学习对方良好的编程方式,形成团队独有的代码风格,而不是个人代码风格
  4. 时不时的结对不会降低开发效率,会提高学习热情

代码回顾

  • 很难说还有哪个实践比这个实践对代码质量更有意义,回顾的方式有
  1. 团队代码回顾,总共最好1个小时左右
  2. 每天代码回顾
  3. 每个人的代码都要回顾,每个人都要讲解
  4. 发现的问题当天就改掉

第18章 敏捷转型下的团队管理:来自一线管理者的思考

  • 初入管理往往会陷入两个误区
  1. 集中控制管理
  2. 微观管理

杰克 韦尔奇先生的一句名言:『在GE,我做得最棒的一件事情是创造了一台准确报时的钟』在企业中,即使是仅仅管理一个小型团队的一线管理者,管理者的目标也应该是打造一座可以自动运转并精确报时的时钟,而不是自己去报时

  • 此后,我做了很多针对公司和部门流程在团队工作层面的细化,我称之为『工作细则』,将所有日常团队可以通过自身机制自动处理的工作都落实成团队中众所周知的规则 。自己更多开始关注自身和团队中每一个人的学习和成长,团队的异常事务的处理,团队目标的设定和更高目标的找寻

敏捷转型下管理者应该如何自处?

  • 团队管理的终极目标是打造一个『自组织』的团队,比打造『时钟』的隐喻更进一步,要打造一个『生命体』,不仅可以自动报时,还可以响应变化 ,自我成长

需要团队管理者首先要做到信任和放手

  • 团队通过自己的成长持续的把事情做对,以致做得更好

  1. 《走出硝烟的精益敏捷:我们如何实施Scrum和Kanban》

推荐阅读更多精彩内容