全栈算力,加速行业AI落地 了解详情
写点什么

全局角度出发讨论敏捷

  • 2018-10-17
  • 本文字数:4391 字

    阅读完需:约 14 分钟

本文要点

  • 在全局、系统工程框架中,敏捷实践可以获得最好的效果。
  • 敏捷需要有好奇心的文化。
  • 名义上的敏捷很常见,但并不实用。
  • 成熟的敏捷是一种思维方式,而不是生搬硬套的实践。
  • 敏捷不等于 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

感谢无明对本文的审校。

2018-10-17 18:266542
用户头像

发布了 218 篇内容, 共 65.2 次阅读, 收获喜欢 76 次。

关注

评论

发布
暂无评论
发现更多内容

React中常见的TypeScript定义实战

xiaofeng

React

恼人的网络时延

agnostic

网络时延

Python应用之反转字符串

芯动大师

10月月更 反向字符串输出 函数与表达式

Qt|双缓存机制

中国好公民st

c++ qt 10月月更

一文搞懂XaaS

俞凡

架构 云原生

Java 属性文件乱码问题

HoneyMoose

Servlet规范中的监听器-Listener

楠羽

Servlet 笔记 10月月更

Vue3入门指北(八)v-model

Augus

Vue3 10月月更

【C语言难点突破】指针入门讲解

Geek_65222d

10月月更

InetAddress.getLocalHost() 执行很慢?

xiaoxi666

网络 网络库

React性能优化的8种方式

xiaofeng

React

C++学习---_IO_new_fdopen函数原理分析学习

桑榆

c++ 源码分析 10月月更

硬核好文!网络拓扑类型:总线、环形、星形、网状、树形、点对点、混合

wljslmz

网络技术 网络拓扑 10月月更

React组件复用的技巧

夏天的味道123

React

书单推荐|宅家不动过国庆,好书相伴不寂寞

图灵教育

书单 国庆节

【愚公系列】2022年10月 Go教学课程 018-分支结构之switch

愚公搬代码

10月月更

深度剖析React懒加载原理

xiaofeng

React

最长回文串

掘金安东尼

10月月更 算法、

书单推荐|宅家不动过国庆,好书相伴不寂寞

图灵社区

书单 国庆节

React源码解读之任务调度

flyzz177

React

react的useState源码分析

flyzz177

React

这可能是你需要的React实战技巧

夏天的味道123

React

【牛客刷题-算法】NC16 对称的二叉树

清风莫追

算法 二叉树 10月月更

深入了解计算机语言

邱学喆

响应式编程 C语言 汇编 对象编程 C++

一Go到底】第四天---数据类型

指剑

Go golang 10月月更

ESP32-C3 学习测试 蓝牙 篇(六、添加 Service)

矜辰所致

service 蓝牙 ESP32-C3 10月月更

【牛客刷题-算法】NC22 合并两个有序的数组

清风莫追

算法 数组 10月月更

【Nacos源码之配置管理 二】Nacos中的事件发布与订阅--观察者模式

石臻臻的杂货铺

nacos 10月月更

react源码中的hooks

flyzz177

React

开发者有话说|我何以坚持编程25年?

个人成长

【牛客刷题-算法】NC25 删除有序链表中重复的元素-I

清风莫追

算法 链表 10月月更

全局角度出发讨论敏捷_Scrum_Jon Kern_InfoQ精选文章