“搞死”敏捷的10种方法 | IDCF
来源:老邓聊开发 作者:邓等登灯
敏捷已经从“只适合小团队小项目”的污蔑中走出来,成为了“显学”。人人都希望自己更加敏捷,没有人敢说自己不敏捷,很多人都声称自己敏捷了。但敏捷真的带来了价值吗?我们今天就从另一个角度来谈谈如何“搞死”敏捷。
1、敏捷仅仅发生在开发团队
敏捷实践仅仅在开发团队发生。业务团队还是把需求写好后,扔到开发团队来,并命令开发团队必须在某个Deadline之前完成。在这种情况下,开发团队不直接对业务目标负责,变成了工具人。这样的开发团队和业务之间很少会有交流,更别说谈判。他们只是按照业务团队命令行事,至于业务团队丢过来的需求是否合理,同样的业务目标下有无更好的解决方案,就不是开发团队考虑的事儿了。
这样的软件,实际上大部分成了并不懂开发技术的“产品经理”设计出来的产物,开发人员只是负责填上代码让机器能够工作。开发团队脱离业务,也无法建立更适合业务的模型。最后产品变为一个畸形怪,缺乏合理的抽象、设计。最后越来越僵化。
2、没有或很少自动化测试
自动化测试,特别是TDD(测试驱动开发)的作用,被IT行业严重低估了。自动化测试是可维护、高质量软件的基石,甚至可以说比生产代码还要重要。目前我们行业整体上对于自动化测试极其缺乏,大多数团队都不具备自动化测试能力,或者有一定能力但以时间紧为借口拒绝自动化测试。
失去了自动化测试的保护,我们就缺乏勇气对烂代码进行持续重构,因为谁也无法预料改几行代码会不会带来新的Bug。没有了持续重构,我们就会欠下越来越多的技术债,这会不断降低我们对业务的响应能力。没有自动化测试,我们人肉回归测试速度变得让人难以忍受,我们要不舍弃部分外在质量,仅仅测试“改动”部分(这实际上很难);要不就拉长回归测试时间。过长的回归测试时间又会让我们倾向于批量进行测试,以减少回归测试次数。这样就降低了我们的敏捷性,把持续交付变成了批量交付,敏捷变成了瀑布。
实现自动化测试的关键在于开发者测试,而不是雇佣更多测试人员编写脚本。因为测试人员编写的测试运行速度慢、对程序员反馈慢。而提高代码质量我们需要的是对程序的快速反馈,自动化测试写得越早、运行速度越快,越有利于程序员及时获得反馈。最早编写自动化测试的方式就是TDD:在写生产代码之前编写。最快运行自动化测试的方式是单元测试。
3、不注重代码质量
经常有人会说:我们现在时间很紧,先做出来再说,先不管质量。很多人认为质量是可以牺牲的,但其实不是。你写出来低质量的代码是因为你只会写出这种质量的,给你多的时间你也无法提高。要提高代码质量只能是提高人的技能。而绝大多数人(别看别人,说的就是你,也包括我)都无法一次性写出高质量的代码。因此我们要不断重构,而要支持重构,又必须有足够快的自动化测试。
另外,低质量的代码并不会带来高效能。除非你程序简单到只有几行代码,否则随着代码复杂度提升,低质量代码迟早就会拖你的后腿。我们行业中很多人称呼别人的烂代码是“屎山”,但其实大多数人自己也是这个屎山的贡献者。
软件之所以称为“软”件,是因为我们期望它容易改变。对于不大会改变的,我们会把它做成“硬”件。对于低质量的代码,我们会越来越难以对其进行改变。一个小小的改动可能导致大量Bug产生,找到需要改变的地方就颇为耗费人力,更别提改变后还需要大量人肉回归测试了。在这种软件质量下,我们还能敏捷起来吗?
4、不注重需求质量
俗话说“Garbage in Garbage out”。软件需求是软件的输入,没有良好的需求,必然产生不了良好的软件。而我们这个行业,优秀的产品经理比优秀的程序员更加稀缺。毕竟,程序员编写的东西再烂,它也有个基本原则:可以跑。而大多产品经理,编写的垃圾还没有个标准去衡量。
有些产品经理醉心于设计方案,而忽略用户价值,导致设计一堆白象功能(耗费巨大却没有用);有些产品经理对需求分析不完整,考虑场景不全面,导致产品Bug层出不穷;有些产品经理不分轻重缓急,导致团队浪费大量时间在价值不高的事项上。有些产品经理只会讲大故事,无法把需求拆分到足够小,这样交付批量就大,降低敏捷性。
5、以事儿来定人
以事儿来定人的典型就是项目制。人都是从属于某个技术团队,比如Android组、iOS组、后台组之类的。等有了项目,你张三、李四、王五过来,你们做。到了中间觉得赶不上了,再加赵六什么的。项目团队里,人员变化频繁,磨合成本高。而敏捷里面的很多实践,都是基于团队的。比如团队速率、回顾改进、人员流动。对于频繁变化的团队,很多实践就很难持续下去,即使做出了一些成绩,也很快面临项目结束,团队解散,导致知识丢失。
以事儿来定人的好处是节约了人力成本,所以外包团队都倾向于使用,特别是人头外包的。这样可以最大化企业收益。但对于企业IT或者互联网,一般来说对业务的响应才是第一优先级要考虑的。不能对业务进行响应,再低的成本也没有意义。
敏捷的实践基本上都围绕团队、围绕人进行。以事儿为目标设人,就违背了敏捷的原则,最后必然是导致不敏捷。
6、不注重提高人的能力
很多IT企业不注重对人的培养。不少人会说,我辛辛苦苦培养好了,转头就让别的企业挖走了。如果出现这种情况,企业应该反思:为何优秀的人才我都留不住?难道你只配使用劣质人力?其实就像程序员抱怨写不出高质量代码是因为时间紧,企业抱怨培养人会被挖走本质是自己不知道如何培养人。
企业把员工看作是随时可替换的螺丝钉,表面上说员工是最大财富。可实际上却对人进行工具化。软件开发是一个设计过程,面临的是不确定的、易变的。不是搬砖头。开发者不是生产者,而是设计者。对于设计者,替换成本比较高。
我们行业996让员工没有时间学习,35岁退休实际上就是压榨了员工10来年的本能。大家全凭本能干活,缺乏优秀的实践。实际上就是在低水平地不断重复。缺乏人的能力的提高,敏捷不过是空中楼阁。
7、敏捷就是工具
有些企业把敏捷转型简单定义为工具平台的使用。用了看板、开了站会就是敏捷了。使用了CI/CD工具就是DevOps了。买了个自动化测试平台就是自动化测试了。敏捷宣言第一条:“个体和互动胜于流程和工具”。流程和工具可以帮助我们更快更好完成任务,但更重要的是个体和互动。仅仅购买一堆工具就宣称自己敏捷了,这是舍本逐末。
8、人员复用
IT人员不好找这是行业难题,当然这个难题也是行业自己整出来的(不注重培养)。在这种情况下,不少企业就搞矩阵式结构。横向是产品或者项目,纵向是职能团队。很多人员在不同的产品和项目里共用。
这样的结果是看起来员工工作很饱和。但由于员工在多个产品中复用,必然导致他有多个代办事项列表,而每个待办事项列表的优先级并不一致。这样他就必须在多个事项之间不断切换,从而导致了他效率的损失。还有因为他有多个事项要处理,实际上又会造成其他人员对他的等待。所以人员复用实际上是用降低业务响应换取了人员成本效率。
9、模块复用
当企业增长到一定程度,有了多个产品线、业务线,就会自然发现有些业务似乎是类似的。本能地出于成本考虑,就会想把这部分抽出来,交给一个专门的团队维护,让用到这个模块/服务的业务调用他们。这样听起来很不错,多个业务/产品线不用考虑某一个模块/服务的使用,只管调用就是了。但实际上由于这样抽出来的模块/服务往往并不稳定,并不能满足未来其他业务的需求。
因此在以后的开发过程中,很多产品/业务线都需要对这个共享模块进行修改以满足自身需求。而由于对共享模块的维护已经交给了独立团队,那么在价值流的交接中,就会出现了团队之间的交接,这种交接成本要大很多。这就降低了产品/业务线的响应性。
10、团队内严格职能划分
团队内分成若干职能:Android开发、iOS开发、测试、后端开发、数据库、运维、架构设计、BA、安全。恨不得一个萝卜一个坑。导致的结果就是在从需求到交付的流程中,产生多次工作交接。我们知道,交接就会导致等待,等待就是浪费。
因此,为保持团队敏捷性,应该减少交接。另外,职能的严格划分会导致工作量严重不均衡,相互之间不能补位。当某个环节产生堆积的时候,其他人也只能干看,甚至不断生产让其堆积更加严重。