本文要点
- 在全局、系统工程框架中,敏捷实践可以获得最好的效果。
- 敏捷需要有好奇心的文化。
- 名义上的敏捷很常见,但并不实用。
- 成熟的敏捷是一种思维方式,而不是生搬硬套的实践。
- 敏捷不等于Scrum。
Jon Kern对于是什么促成了敏捷的成功有着自己读到的见解。你可能会不同意他的观点。
下面列出了一些建立在项目全局角度之上的关键实践,项目本身就是从此开始的。如果不能从系统角度来做项目,那它就不能达到预期的效果,甚至可能会失败。
我最终不得不承认我是在使用Kanban过程
我很早以前就认为,开发软件就像是在完成一个很长的待办事项列表。我试了很多方法来运行项目,从记事贴到Jira(从Jira刚发布起我就开始使用)。我使用传统Scrum风格的Sprint很多年,只是我的使用方式与众不同。对我来说,Sprint就是定义广泛优先级的“储存桶”,可以说就是分组机制。我不太关心我们是否在Sprint中解决了所有问题。在一开始,我也会通过燃尽图来查看我们是否达成了预估的目标。但之后我才发现,就算完成了又怎样,完不成又怎样?
所以最后我才承认,在Sprint的伪装下,其实我们是在使用Kanban。
我认为,在选择一个过程时,最重要的是要保证能在正确的时间将正确的事情完成到正确的“水准”,然后一直做到交付为止。换句话说,你要给团队提供需要完成的业务功能的优先级列表。这样至少你会知道团队在做的是当前最有价值的事情。
Sprint计划和估算
我是怎么怎么做估算的?说实话,我尽量不去这么做。
至少我不会做传统意义上的估算,就是估算每个故事点,然后根据估算值来决定这个Sprint中可以处理的问题数量。这非常无聊。
即使是最近我们在做Sprint时,我也几乎不做Sprint计划和估算。(我想这是因为我职业生涯中有十年时间都在给海军相关的合同工作提供投标和指导建议,因此留下了“后遗症”。)我的团队和我经常拿Jira Sprint报告的燃尽图来开玩笑,有时候直线上升,有时候下降到正常的幅度,之后保持平缓。
这是因为我们不会浪费时间去思考在Sprint中我们能完成多少事情。我们只关心要安排恰当的优先级顺序,并将问题分解成合适的大小。我们把没有完成的事项放到下一个Sprint的顶部(如果仍然有必要完成的话)。
请注意我使用了“合适的大小”这个词。这里有一些隐式的“计划”。如果一个问题需要两周时间才能处理完,我们就不会把它考虑在内。相反,我们会把这个大问题分解为更有意义的小问题。我们甚至可以和业务方协商将大问题分解为不同的深度级别,这样在一开始就可以轻松一些。随着时间的推移,我们可以根据用户的反馈来添加更多功能。
什么对我来说是有用的?
无论是对一整个新项目、对一个新的主要功能,还是往遗留系统添加新功能,我都会在一开始搞清楚需求。这个过程有助于建立整个系统的全局视图,或者了解是否会对现有系统产生影响。我这里用了“全局”这个词来表示组成系统的方方面面,或与你系统的发生交互的其他系统、会修改你的系统或者对你的系统有着决定作用的人(包括用户和“业务方”)。
我的第一原则
- 发现业务需求
- 建立有效的领域模型
- 列出高优先级的故事映射或功能
-
列出任何有决定性影响的因素
- 不能改变的最后期限
- 疯狂的性能需求
- 疯狂的服务协定
- 其他
最重要的是要充分了解需要处理的业务问题(就是需求),并建立能反映业务需求的领域模型。我还会建立产品设计愿景,也许还有一些其他重要的事情。最后架构成形,它可能是一个“普通的”响应式Web应用程序,也可能是一个非常新颖的特别架构(比如语义Web)。简单来说,我喜欢做足够的“前沿”设计,这样可以避免我们没能充分了解到的风险。
你可能已经猜到了,我会花很多心思对问题领域进行建模。这有很多好处:
- 捕捉业务方使用的术语,成为项目的通用语;
- 创造领域架构,捕捉重要的关系;
- 为团队提供符合需求和UI界面模型的类信息,简化功能开发和问题修复;
- 可以很方便地讨论需要添加哪些新功能。
“足够”这一词是非常主观的。它可能来源于多年的实践经历,告诉我们什么重要,什么不重要。尽管如此,你还需要思考是否要在早期的设计中为某个功能添加更多细节。或许你可以等到实现这个功能时再考虑细节问题。
或许我可以给出一些极端的例子。
在我听到一些主题专家或用户描述他们的观点和需求时(可能通过用户故事或者将功能和抽象概念些下来),我会为他们的业务领域建立模型(即问题领域)。这些模型包括属性、方法和联系。在需求诱导的开始阶段,我主要关注大类和基本功能。通常是了解有用户存在,而且用户是借款人(比如这是一个贷款应用程序)。主题专家一开始想告诉我借款人的20个属性,我一般会阻止她。我会礼貌地问她是否有任何特定的属性会影响我们将要深入探究的需求。如果没有的话,我建议我们之后再讨论细节。如果业务专家偶尔提到几个估算或合规性需求,我可能会问他们几个问题,确保它们不是超级复杂的大需求。
极端例子:用户类的名称。如果“名称”包含名字、姓氏、中间名、称呼、头衔等等,是否会影响架构的复杂度呢?
如果不会对设计产生实际的影响,就不需要在很早的时候花太多时间来研究这些细节,因为这样的话就会忽略一些重要的元素。
另一方面,我有个客户故意将细节保留到后面再说,他认为等待是最好的。除了有一次,他又在很后面才说出细节,但我希望我能早点知道,因为影响到我对设计的看法了。(我现在忘了具体是什么了,大概是与泵动原理有关的一个技术问题。)
这个方法对我是有用的,因为我通过全局系统工程方式来进行软件开发。通过建立系统的心智模型(和纸上),我们可以了解系统组件之间的关系和影响。
要有耐心,不能操之过急。获得足够的需求,进行恰到好处的设计,不要一开始就了解太多需求细节!
大规模敏捷
在我第一次听到“大规模敏捷”这个词的时候,我在想,这是不是像“大规模Java”或“大规模Rails”一样?当然,如果你在和五个团队成员一起开发Web应用程序,那么和超过100人的团队相比自然不是一个数量级的。
但我很少将“大小”和“规模”与更多复杂性挂钩。
我曾经设计过的最大项目是IBM的生产执行系统,用在他们分散的电脑工厂里。大约有七个核心模块,200-300个问题领域类,200万行代码,分布式的瘦客户端,多用户界面选项(Windows NT、DOS graphics、OS2),多数据库选项(Oracle和DB2)。
之后采用了“敏捷”原则(就像他们现在做的一样)。应用程序范围要大得多,在我们开始正式写代码之前,有更多前期设计和架构设计要做。我们还参观了工厂,进行了用户访问,设计UI原型,并做了早期部署。这发生在敏捷和DevOps兴起前的1995年!
当然,一个与其他系统有依赖和交互的项目会更具挑战性,成本也更高。关键是要通过全局的视角理解系统和子系统,最小化大型应用程序终究会面临的“额外开支”。
无论怎样,我会遵循这里所列出的有关通过敏捷方式来开发软件的原则。大型项目当然会比小型项目需要更多的前期工作和协调。
我会尽我所能,将巨大的项目分解成一组规模较小、较自治的项目。
我永远不会采用100多人的团队,我可能会采用20个5人的团队,或者用25个(甚至更少)高绩效开发人员团队来完成100个普通开发人员的工作。
我的建议:学会分解问题,了解如何通过接口进行架构,通过解耦系统将大问题分解为合理的小问题,这样就不会产生太多开销。
敏捷宣言的状态
有时候我会被问到,如果可以的话,我是否会回到过去修改敏捷宣言。
我的回答是“不会”。
如果可能的话,我们想要(重新)让人们了解我们在编写宣言时的想法。
我们的一个尝试是 敏捷起义
(Agile Uprising),一个组织在Snowbird采访了我有关敏捷活动的内容。他们还采访了几乎所有的其他合著者。可以访问他们的网站,注册并了解一些有意思的讨论!他们正在试图将我们这些作者几年前的想法展现给大家!
现代敏捷
(Modern Agile)是另一个尝试,是由我的一些朋友牵头组织的(Joshua Kerievsky、Tim Ottinger等)。我只是留了名,是原来的“敏捷”已经老了吗?不够现代化了吗?
回到核心问题
就像《美国独立宣言》和《宪法》的核心是监管人类行为,我认为敏捷宣言的本质是关于软件开发中人的行为。
对于软件开发的未来,这四方面的内容会什么时候(为什么)不再适用?
- 个体和互动高于流程和工具;
- 可运行的软件高于详尽的文档;
- 客户合作高于合约谈判;
- 响应变化高于遵循计划。
有关作者
Jon Kern
是敏捷宣言的合著者之一,他非常乐于帮助客户通过软件交付商业价值。他具有长远的眼光,在看到大局的同时,也知道细节内容,并在关键时刻推动商业取得成功。
查看英文原文: Agile in the Context of a Holistic Approach
感谢无明对本文的审校。