抗易碎产品开发
抗易碎产品开发
原文:https://medium.com/hackernoon/antifragile-product-development-39b8d5866b77
从无序中成长高效团队

Photo by Štefan Štefančík on Unsplash
如果你还没有读过尼古拉斯·纳西姆·塔勒布的《反脆弱》,看看我对这本书的概述。我非常非常推荐这部作品。Taleb 只字未提产品开发,但我不禁想到了成功软件与抗脆弱性的所有联系。
敏捷是抗脆弱的
最突出的一点是许多敏捷过程减少了脆弱性。在敏捷中,你学习并适应小错误,以便在更可靠的时间表上做出更好的产品。在瀑布中,您在早期就计划好一切,并且适应或学习的方法有限。
时间表
冲刺规划与前期大设计
塔勒布经常说大或快是脆弱的。瀑布是预先的大规划。这种规模很容易产生大量微小的非线性问题,并增加项目成本。敏捷遇到了同样的问题,但是它鼓励你在前进的过程中做出调整。
作者讲述了一个关于旅行没有选择性的故事。旅行时间的上升空间有限,下降空间几乎无限。如果你在路上开车,你可能会遇到更多的绿灯,或者你可能会超速行驶而没有被拦下。不管积极因素是什么,你最多提前几分钟到达。到达某个地方永远不会花费负时间。
但是有很多事情会让你慢下来:交通、被警察拦下、事故、恶劣天气、建筑等等。几年前,在罗利的一次暴风雪中,通常 20 分钟的车程花了 3 个小时。我很幸运。其他人的情况更糟。
与旅行时间一样,产品开发缺乏选择性。许多事件会导致延迟:
- 意想不到的困难的第三方集成
- 意外需求
- 隐藏的复杂性
- 新开发人员入职
是的,有时候你认为需要两周时间的功能实际上只需要四天——如果这发生在我身上的话。但是更常见的是,你认为需要三十分钟的事情却要花上两天。一个特性永远不会花费负的时间来完成,但是很容易花费十倍于估计量的时间。
使用瀑布,这些事件继续扩展时间线,通常是非线性的。有了敏捷,你可以重新排列优先次序,丢弃不太有价值的项目,这样你就可以在你的时间表和预算内做出最好的产品。
Sidenote:“快速”开发也生产易碎产品。如果你急于在紧迫的截止日期前完成,你会有更多的臭虫。如果你不做质量保证,臭虫会非线性繁殖。如果你雇用初级开发人员超越他们目前的能力,你将会得到一个很难继续开发的产品。如果不编写自动化测试,代码很可能会随着未来的变化而以意想不到的方式中断。如果你不花时间重构,随着时间的推移,改变系统会变得越来越昂贵,直到你的团队开始要求完全重写。(旁注:不要重写)
所有这些都有权衡,保持团队现在快,以后快就是平衡。例如,让我们看看自动化测试。编写自动化测试平均会将初始发布日期增加 30%,但在维护产品时会节省您的时间。在某些情况下,不编写测试是有意义的。我们无法预测因未测试而导致重大故障的风险,但我们可以断定,这会使产品更加脆弱。然后,如何降低这种脆弱性就变得简单明了:增加测试。
流程改进
回顾展
敏捷的另一个反脆弱的方面是它的回顾。你花时间谈论什么没用,什么让你慢下来,然后你改变了它。随着时间的推移,您的团队会不断进步。
在我现在所在的团队中,我们发现我们的会议结构阻碍了工作的完成。我们重复了几次,找到了一个对我们有效的方案。现在,我们的会议聚集在一起,让制造商有更长的时间投入生产。我们也为议程做好准备,所以我们花在会议上的时间更少。这些微小的改变对我们的设计和开发工作产生了很大的影响。
追溯允许你将冲刺阶段的负面事件转化为一个从中学习并变得更好的机会。坏事件越多,吸取的经验教训越多,你的团队取得的进步就越多。如果做得好,问题就会开始消散,你的团队就会从容应对。
看板法
看板是一个系统,在这个系统中,您的工作经历了不同的阶段,每个阶段的工作进度都是有限的。假设您有“参与设计”、“参与开发”、“参与质量保证”(QA)和“完成”;每个阶段你最多只能完成 3 项任务。如果您在 QA 中有 3 个项目,在您将项目从 QA 移动到完成之前,您不能将任务从开发移动到 QA。
看板是丰田方式的一部分。如果工人在装配线上遇到问题,汽车制造商允许他们停止整个生产线。这样,当流程的某个部分出现中断或瓶颈时,它就会得到需要修复的关注。像这样的实践帮助丰田主导了这个行业。小错误导致过程的大改进。
裁员
跨职能团队
抗脆弱系统通常是多余的。以人体为例。身体几乎什么都有两个,你可以失去许多器官的大部分,但仍然发挥作用。
传统团队没有这种冗余。后端开发者只写 Java。数据库人员处理 SQL 查询和存储过程。前端设计师只做 HTML 和 CSS,前端开发人员写 JavaScript 把它们插在一起。当然,有时你没有数据库工作要做。其他时候,你有大量的前端数据,而你的后端人员却遥遥领先……后来才发现,他写的东西并不能满足前端的需求,他不得不完全重写。
你可以想象团队中的每个人都擅长每件事的理想状态。每当有工作进来,谁有空,谁就去处理。创建一个应用程序所需的技能是多种多样的,所以不可能全部掌握。但是很多是可以转让的。
例如,如果您的前端开发人员可以处理设计,您的后端人员可以全权负责,而您的数据库管理员可以编写代码,那么您就有了一个跨职能团队。更少的事情会阻碍你产品的进步,你限制了负面事件的影响。
结对编程
结对编程是极限编程(敏捷的一个品牌)的核心租户。结对有助于减少错误,减少阻塞的可能性和影响,并使开发人员保持专注。但是最大的好处之一就是知识冗余。复杂的软件通常有开发人员认为神秘的边缘。
在我参与的一个特定项目中,是代码获取了一幅图像,将它分割成几个不同的颜色(对“足够接近”的颜色做了一些伪造),并将其分解成多个层,这样每种颜色都可以独立于另一种颜色进行更改。在另一个项目中,授权存储过程将六个表连接到一个查询中,以防止用户看到超出他们应该看到的内容。
在这两个例子中,单独开发人员编写了模块。当数据库授权模块的作者想离开时,管理层把银行扔给了他。他们担心没有其他人能维持它。
现在,我敢打赌,如果最初有两组人一起工作,这两段代码会更简单。这些模块本来就不会获得神秘的名声。
但是让我们假设复杂性是不可避免的。在这种情况下,你现在有两个人知道如何使用它。如果有人离开:没问题。你很快就会有另一个人接受这方面的训练。换句话说,它限制了负面影响。
里程碑
项目计划的瀑布式方法是在项目开始时设置一个时间线(通常是甘特图的形式),以准确地勾勒出事情的发展方向。我们已经讨论了为什么如此超前的计划如此容易出错:问题如何影响时间线的非线性。但是还有另一个常见的反模式:让业务定义开发需要多长时间。原因很简单:游戏中的皮肤。
游戏中的皮肤意味着负面结果在某种程度上伤害了你。如果最后期限过于激进,开发团队最终会花很长时间试图完成它。敏捷通过让开发人员致力于 sprint 计划中的工作来解决这个问题。无论如何,如果团队承诺某件事但没有完成,就要让他们负责。如果你不这样做,他们在游戏中也没有皮肤。
如果你在业务方面,你收到的时间表太长,你有几个选择:减少需要完成的事情的范围,或者在项目开始时增加资源。你越晚去做这些事情,对截止日期的影响就越小。
神话中的人类月
弗雷德·布鲁克斯(Fred Brooks)写了一本著名的书,神话中的人类月,描述了一种现象,即将资源添加到一个后期项目中会使它变得更晚。这就是干预主义:一个人需要干预复杂系统的感觉,这通常会让事情变得更糟。
在这种情况下,我们期望更多的人做这项工作意味着更多的工作要做。很多劳动都是这样的。软件不是。新员工需要时间来学习代码。在开发人员这样做之前,预计会有更慢的工作、更多的错误和意外的重新发明。
这只是干涉主义和软件开发的冰山一角。我们都知道最后一刻的改变会延长时间表。在某些情况下,如果一些工作正在进行中,或者它改变了其他部分的假设,那么即使是简化一个功能也是可以的。
要求团队延长工作时间来完成更多的工作也会导致更多的问题。随着您变得越来越疲惫或疲惫不堪,您的生产力会直线下降。也许一个团队可以应付几周的加班,但死亡行军是徒劳的。
另一个常见的干预是通过改变流程或团队结构来“改变事情”。在团队的带领下,回顾一些经常被忽视的事情。有时新的改变会有所帮助,有时他们需要回到画板上。如果改变没有达到预期的效果,我所在的团队并不害怕改变。
但是最糟糕的一种改变是当它被项目团队之外的人授权时。总是用心良苦,但大部分变化都不动针。许多人把它向后移。很久以前,管理层告诉我所在的一个大团队,要像一个大团队一样站起来开会。这些站立训练是长达 45 分钟的马拉松式训练,有几十个人参加。这个想法是每个人都在同一页上。事实很明显,在等待轮到他们发言的人们的茫然的表情中。团队说的多了,人交流的少了。
成为一个不那么脆弱的产品开发团队
以下是我对建立抗脆弱产品开发团队和流程的建议:
- 雇佣一个有经验和能力的团队来开发产品。这些并不便宜,但你会得到你所付出的。有能力的团队交付健壮的产品。一个没有能力的人可能会也可能不会给一个脆弱的人。
- 雇佣能够处理多种角色并在至少一个角色上表现出色的队友。灵活性越大,负面效应对团队的影响就越小。这是 T 型个体。
- 对产品的关键和挑战方面进行配对。如果代码听起来很复杂,或者你正在应对一个全新的技术挑战,找几个开发人员一起完成。如果你想不出设计中的一个重要部分,让一个设计师和任何一个能倾听并提供想法的人配对。如果你和客户或利益相关者一起工作,在会议上结对。不要留下任何一个失败点。
- 编写最简单的有效代码。不要试图写完美的抽象。你最终会写出许多不必要的代码,使改变变得更加困难。
- 不要过度投资测试。测试通常会让你在最初发布时慢下来。随着事情的变化越来越多,这在早期尤其痛苦。虽然您可能正在创建健壮的软件,但是您正在创建一个适应变化较慢的产品。大多数项目要么测试太多,要么测试太少。找到平衡。
- 回顾你团队的问题。所有团队都有问题。有时它们是内部的。有时它们是外在的。花时间自省,为他们解决。无论你是通过看板、Scrum 回顾还是其他方法来做这件事,确保整个团队都参与进来。
- 制作团队设定时间表。如果你对他们的时间表不满意,尽早删除功能或增加员工。
- 如果一个团队落后于计划,问他们需要什么,只提供他们需要的。否则,除非在最危急的情况下,否则不要干预。也就是说,如果他们做了明显错误的事情,介入并解决它。如果你不得不坐下来研究和思考他们的问题可能是什么,你不会对这个问题有太多积极的影响。
- 要有一个目标,但要灵活掌握实现目标的途径。成功往往是核心要素的正确运用。完美不是在没有更多可以添加的时候达到的,而是在没有什么可以拿走的时候达到的。
对我来说,变得抗脆弱的基础是这些原则:优先适应变化,选择潜在的高收益工作,避免干预你不需要的地方,以及在游戏中围绕皮肤进行构建。如果你有关于这个话题的经验或想法,或者你正在寻找建立一个抗脆弱的开发团队来使你的产品变得有生命力,伸出手来,让我们来谈谈。