Port of Rotterdam

鹿特丹港口信息管理系统开发:从LeSS的角度看

这是一篇将鹿特丹港案例与LeSS原则以及组织设计进行比较的文章。它讲的是四个跨职能特性团队交付并运维一个对业务至关重要、必须7x24小时运转的港口管理产品的故事,该产品由船舶交通服务运维人员和其他几种类型用户使用。

上下文与客户

鹿特丹港口管理局营业额约为 6 亿欧元,拥有 1,100 名员工,负责商业、航海和基础设施相关等各不相同的职责。 特性团队的首要客户是港务部门(Harbour Master)。该部门确保了航运交通(每年大约 33,000 艘远洋船舶和 110,000 艘内河船舶)能平稳、流畅并安全地运作。

用户多种多样。一些为港务部门工作,一些为其他部门工作,还有一些为鹿特丹港的众多合作伙伴工作。

port-of-rotterdam.png
图 1:在常用物理设备上显示的实际 HaMIS 用户界面

主要业务流程的核心是一个名为 HaMIS(Harbour Management Information System,港口管理信息系统)的产品。 HaMIS 的想法诞生于很多年前,当时的需要是替换掉既有的。 既有系统已经在鹿特丹港很好地运行了 20 年,但旧的技术和架构已经成为对业务流程做出任何重大改进的主要障碍。 鹿特丹港正在发展和变化,既有的老系统已无法满足要求。

产品的首要目标很简单:最小化过时的老系统带来的负面影响。 但另一方面,次要目标并不是太明确。 鹿特丹港正在增长,尤其是随着 Maasvlakte 2 的扩建。 该产品必须能在工作人员数量不变的情况下支持港口不断增长的交通情况。 这意味着需要加强信息交换、对相关利益方更好的协调,以及更好地支持港务部门的主要流程。

这一切是如何开始的

在决定用 HaMIS 替换旧系统之后,就开始了一个复杂的过程 - 制定计划、做预算、让供应商和软件集成商参与进来,还有一个糟糕的采购流程。预期中这是一个外包开发项目。在这个过程中产生了很多文档,但除了概念性验证(POC)之外没有真正的代码产生。

最终,港口管理局做出了一个勇敢的决定,全面停止这个过程。开发方案太复杂了,不可能成功。需求复杂且高风险。太多的不确定,而且如果项目失败,这将会是荷兰的大新闻。如果有缺陷的系统投入到生产,后果可能会更糟糕。

但现有系统已接近其使用寿命,因此港口管理局别无选择,只能重启该项目,眼下就是一个主要目标:用至少提供相同功能的新系统替换当前系统。但这一次,港口管理局选择了作为一个内部产品开发,而非外包给一个或多个系统集成商。

新产品的开发选择的方法是 RUP 和伪 Scrum 的组合(当然,它没有被正式宣称是“伪”Scrum)。虽然有 3 个完全由程序员组成的“Scrum”团队开始举行站立会议并尝试其它实践,但是也存在另一个独立的由 8 名不同类型的架构师和分析师组成的名为 AQUA(architecture and quality assurance)的架构和质保团队。

这么看来,最初的意向是单点改善。在现有组织的各种假定限制内,准备实施“开发级别的 Scrum”。而开发工作是由分析师和架构师这群人准备的。

从 Scrum-But-But 到 Scrum-But

RUP和Scrum-but-but的组合体并不真正地发挥作用。一家教练服务公司被引入来帮助他们学习如何转向Scrum。这家公司提供了Scrum培训和具体的工作辅导。但还是没有转为全面使用Scrum。比方说,团队决定培养并任命两个人为“Product Owner”,但无论如何实际上都还是有一个项目及项目集经理来做决策。

译者注:

  1. RUP:https://zh.wikipedia.org/wiki/统一软件开发过程
  2. Scrum-But-But:Scrum-But是指团队无法全面使用Scrum进行产品开发的状态。这些状态有特殊的句法结构来描述,“我们使用Scrum,But……”,Scrum-But也由此得名。作者这里的Scrum-But-But是指比Scrum-But还要偏离的状态。

因为Scrum被错误地作为实践,而非会影响既有团队和经理角色的组织设计变革,来导入,所以,AQUA团队仍然存在,“Scrum”团队既不跨职能、自管理,也没有展现多面学习和多技能。没有一位真正的产品负责人,项目经理仍然存在,为“达成目标”负责。还有一些SAFe实践,比如“架构跑道”,仍然被讨论或引入了。

教练辅导公司引入了许多团队及技术层面的实践。比如,一次代码提交后(使用SVN,基于主干的集成),所有代码都会被构建服务(Jenkins)构建,并使用Sonar进行质量检查。测试包含单元测试,少量的Fitnesse测试以及通过录制播放工具进行界面测试。后来后者被完全弃用。此外,在这个阶段自动化测试还没有作为自动化构建的一部分。

改善在进行并逐步靠近Scrum,成果也不断地展现出来。迭代是3周,所有的Scrum会议也都被践行。最为重要的是,每个迭代后,一个单一的潜在可交付产品增量被发布到一个预生产环境,然后一些关键客户会试用新功能。

从 Scrum-But 到 Scrum

这个时候我作为架构师兼敏捷教练入场,同时那家教练服务公司离开了。

尽管他们叫我敏捷教练和架构师,但我那时的意图是作为Scrum Master来在组织设计中引入真正的Scrum。每个团队都有一个任命的Scrum Master,但实际上他们只是比其他成员多承担了一些引导工作的普通团队成员。

LeSS规则:Scrum Master负责一个运转良好的LeSS导入。他们关注于团队、产品负责人、组织和开发实践。一个Scrum Master不只关注一个团队,而是整个组织系统。

我们做的第一件事是以系统改善为目标,废除AQUA团队。废除工作通过逐步把决策权转移到特性团队来进行。此外,剩余的AQUA团队成员并没有坚持待在老团队中。尽管如此,他们中有些人在AQUA团队被废除后仍然想保留他们在分析、架构及质量保证领域的权威性。

最后,没有什么活儿留给那个团队做了。换句话说,真正的可以端到端交付的Scrum特性团队成功地建立起来了。在特性团队与用户之间也没有任何人了。AQUA团队成员要么离开了,要么加入特性团队,要么就是做一些产品开发组织之外的任务。

与需求和架构关注点相关的知识、经验、新的洞察以及业务的持续改变都开始出现在团队中。

这一转变真正有挑战的地方是AQUA团队成员的特定头衔和角色。在经过很大的努力后,它们才被完全移除。这些头衔和角色,如不同的分析师和架构师,是双重的。他们真正的在组织中被公司和HR授予的岗位从来没有被正式地改变过。与此同时,在组织变革后,这些岗位和角色从HaMIS产品开发的角度看已经变得没有意义了。

有时,当直线部门试图通过人们的角色来影响产品开发时,这会产生一个小问题。一个例子是对“项目完成后移交到运维”的讨论。但实际上,项目已经不再存在,只有持续的产品开发和管理。另一个稍大一点的挑战是直线经理试图(并没有成功)将任务分配给他的下属,尽管他们已经完全分配给 HaMIS 产品开发。此外,还有一些KPI是与年度评估关联的。一些团队成员因为没有达成他们的KPI而没有获得全额加薪。

这些问题的根本原因是一直存在的矩阵管理结构,从官方定义来说人们汇报给他们的职能直线经理及项目经理。组织变革移除了对项目经理的汇报,但是对职能直线经理的汇报仍然保留在后台。这个问题只是影响着少数人,并且由于典型的荷兰企业文化以及优秀的总体成果,他们能够简单地忽略直线经理的影响。

在这个时间点上,我们仍然有一个活跃的项目经理在逐渐学习着放手。他仍然表达他想要什么,而非在一个真正的产品负责人手中对产品的完全控制。

其中一个伪产品负责人开始表现得像,也被看作是,一个真正的产品负责人。两个产品负责人都是从港口管理(业务)部门来的。真正的产品负责人也是那个做优先级排序以及产品待办列表更新的人。他拥有足够的权力来做产品相关的决策。第二个人官方也被叫做产品负责人,但是实际上并不被视为“产品负责人”。不幸的是,他继续充当着团队和用户之间的中间人(业务分析师),增加了交接,与人们谈话并且收集反馈。这个问题从来没有被完全解决,只是及时减少其影响。我后来学到的教训是拥有一个待在团队和用户之间做分析师的伪产品负责人存在非常重要的缺点。我曾经在一开始时(错误地)以为这是一个可接受的妥协,并没有预见到它会带来的复杂度。

LeSS规则:对整个可以交付的产品有一个产品负责人和一个产品待办列表。

在这个阶段真正的产品负责人负责对产品待办列表的排序,并且通过澄清条目及提供对任何问题的解答与团队合作。不幸的是他有时仍继续充当团队与干系人的中间人,而不是去直接连接团队和干系人。

LeSS规则:产品负责人不应该独自工作于产品待办列表梳理;他通过让多个团队直接和客户/用户以及干系人工作来获得支持。

在这次更具意义的组织设计变革之后的最初五个月里,在产品待办列表上高优先级条目已经不再是老功能的替代,而是全新的功能。由此带来的结果是新功能的技术牵涉相当简单,从而团队可以快速交付。此外,用户也更期待着去使用这些在HaMIS中具有真正价值、在老系统中却没有的新功能。

在这一切之前,当陷在超载的RUP和SAFe船里时,注意力集中在交付各种文档和做出太多推测性的架构决策上。在移除RUP并开始Scrum培训后的第一个迭代中,焦点已经转向嵌入敏捷思维。每个人都在谈论这个叫做Scrum的东西以及它是如何工作的。有些人持怀疑态度(例如,关于持续的实验),但大多数人都在渴望尝试和学习。此外,开发生命周期的每个方面都已开始改善。持续集成、TDD、ATDD、结对编程和其它XP实践逐渐被嵌入。有人可能会说,尽管在学习上花费了精力,但团队已经在每个迭代之后,根据统一的完成的定义将新功能交付到生产环境中。但我更愿意说,因为花费精力在学习上,团队才在每个迭代都交付了新功能!

代码的签出和签入周期时间开始从每个/对开发人员每天一次改进为大约每小时一次。简而言之,团队开始走向真正的持续集成(CI)。开发人员在本地构建期间不断扩展质量检查。最终,即使是稍微复杂的函数也会使构建失败。产品始终处于准备好发布的状态。每当有人在没有运行这些检查而匆忙提交时,为大家带来美味的蛋糕成为一种惯例。这不包括由于频繁集成而破坏构建。过了一段时间,构建系统变成了一个多阶段CI系统,3个构建阶段主要由自动推进和一些并行处理来驱动。最终,开发人员形成了一种行为改变的文化,即持续地集成(这才是真正的“CI”),而不仅仅是使用了构建服务器就错误地认为这就是“CI”。

LeSS

因为LeSS(大规模Scrum)是在多团队工作场景下对Scrum的直接、简单、一致的扩展,所以即便不熟悉2008年和2010年出版的LeSS书籍(由Larman和Vodde出版),各种群体已经重新发明大部分或全部LeSS的情况可能很常见。这也是我们在2010年第一次开始这个旅程时的情况(Scrum在港口的引入)。因此,现在我对LeSS有了充分的了解,反思我们所做的工作,将我们的案例与标准LeSS进行比较和对比,这对我来说很有趣。

因此,“基本的LeSS”开始形成,尽管我们从未提到过LeSS框架。工作方式和实践是根据以前的经验引入的,但更多的是作为实验。这些是开始时最重要的原则:

  • 整个产品聚焦在每个迭代产出潜在可交付的增量
  • 尽可能地离客户近
  • 每个人都聚焦在整体产品上,移除任何不必要的角色和职责
  • 让团队直面挑战,不要试图在团队外解决它们

LeSS巨型框架在这里肯定不需要。在重组之前,有3个组件团队,1个架构/QA(AQUA)团队和1个运维团队。重组后,我们有3个特性团队。很久以后,扩展到了4个特性团队,如后文解释的那样。

LeSS规则:多数团队都是以客户为中心的特性团队。

在这次重组之后,大力推动自管理。这个推动的含义将在后文解释。项目经理逐渐停止了他们的干预,他们停止了做出任何决策或分配任何工作,而只是安排预算并与组织中其他不太了解敏捷开发是如何工作的人员进行沟通。理想情况下,这项工作应该由产品负责人完成,但他缺乏项目经理的影响力。虽然项目经理态度的转变很慢,但却不难。主要原因是其中一位项目经理是Scrum的第一个也是主要的倡导者。现在,他不再是项目经理了。

LeSS规则:在LeSS里,管理者是可选的,但是如果管理者还存在的话他们的角色可能会改变。他们的焦点从管理日常产品工作转向改进产品开发系统的价值交付能力。

hamis-timeline.png
图 2: HaMIS 时间表

产品

在Scrum引入之前,产品的第一个版本已经部分实现。基本的技术元素包括使用 Java,一个用 Swing 编写的独立 Java 客户端与 JIDE 结合使用,服务器端使用 IBM WebSphere 平台,以及基于 HTTP 的 SOAP 作为客户端和服务端之间的协议。甚至还包括一个带有企业服务总线的 SOA(Service Oriented Architecture,面向服务的架构)。后端的设计和分层基于标准的 JEE 模式(服务、业务、数据)。通过使用Erdas Apollo软件的基于服务的独立解决方案向客户提供地理空间数据。总的来看,这绝对不是最简单的解决方案,它被过度设计了。事实上,前端部分是基于概念验证(POC)时的实现,不幸的是,这个实现并没有被扔掉。不管怎样,经过一些调整,它在第一个迭代中是可行的。

几乎所有的原始选择在后续的几年中都经历了重大改变或者被废除,随着不断增加的功能数量和内部复杂性,取而代之的是更简单的方案。“我们需要选择复杂技术以应对后续更为复杂的需求”这样的观点被证明产生了相反的结果。所选择的技术并不被需要,其它技术就逐步取代了它们。

与此类似,原有的总体设计在重组为跨职能特性团队后被放到了一边。焦点转移到了实际代码,也就是已经实现的设计上。

团队仍然聚焦在架构和设计上。推动着架构不断演进的是所要求的特性而非推测。对团队来说,这形成了以下几个重要的设计规则:

  • 如果这不是当前迭代或下一迭代的业务需求,那么我们不用去做决策、设计或构建。可以对此进行讨论,但是简短点就好。
  • 我们必须尽快替换掉老系统。

这里最大的挑战并不是设计技术和知识,而是如何从领域专家和用户那里得到清晰的信息。复杂的主题意味着没有多少人能够解释清楚外面的事物是如何运作的。

寻求简单解决方案的思路逐渐嵌入到每个参与者的心中。这种想法体现在不断地质疑和替换已经实现的选择,以及在澄清和估算大大小小的条目时始终选择最简单的选项。其中一个例子是使用 Hessian 二进制协议替换客户端和服务端之间的基于 HTTP 的 SOAP 接口。这主要意味着删除大量代码,感觉很棒。

然而,在进行任何这些技术讨论之前,团队不仅要知道后续迭代条目背后的需求,而且还要了解它们在上下文中的合理解释,它们背后的业务流程,以及可能影响当下选择的其它任何需求。

团队是在解决问题,而非仅仅是交付解决方案。这在一整天的产品愿景工作坊上最为明显,团队与港务长及其他业务人员密切配合来定义产品愿景。

product-vision-box.jpg
图 3: 产品愿景工作坊,初始产品待办列表工作坊的一部分

这次工作坊的成果是未来两年的共同愿景和产品待办列表的高级别条目。在这次之后还有更多不同类型的工作坊。

团队没有花大量的时间来选择能为未来二十年服务的宏伟新技术,而是重新专注于理解哪些需求将满足当前的设计和技术选择。当目前缺乏相关需求或者相关需求还很遥远时,团队将考虑:

  • 目前的选择是否会阻止我们在未来满足这些要求,
  • 取代这个选择会很昂贵吗?

如果不会的话,进一步分析就成了浪费。

换句话说,我们花费了大量的时间在理解短期和长期业务需求上,但花费了很少或根本没有花费时间在下个迭代后就不被使用的东西的设计和架构上。

所有重要的决策,有很大影响的决策,都在两类跨团队设计工作坊中做出:

  • 由任何团队针对当前或下一个迭代的即时需要来触发
  • 从主题墙上选择,任何人任何时间都可以贴上任何的讨论主题到墙上
technical-debt-wall.jpg
图 4: 技术债或架构相关主题墙

这类会议的时间盒通常是一个小时,一般遵循分散/收敛的会议讨论结构。一小时后团队或者做出决策,或者决定要进行更多的研究。

所有的设计决策都是由团队做出。一开始,是由最有经验的团队成员来做这些决策。这在团队动态上带来了一些问题。设计相关的讨论通常产出决策和白板上的草图。由于这些图很大程度上定义了属于一个故事的任务,其他的团队成员就会感觉到脱节。

LeSS规则:跨团队协调由团队决定。

最终,设计和架构相关讨论成为了团队和跨团队的工作。他们通常在迭代计划会议第一部分开始,但真正的工作是在某个团队工作在一个特定条目之前完成的。当某个条目需要与其他团队进行协调的时候,只需直接交谈,即可自然地解决依赖问题。不需要任何在团队之外的跨团队协调。

LeSS指南:通过开放空间进行协调,加入其他团队的站会、Scrum of Scrums、多团队工作坊,或“只是”在同一空间工作,相互交谈,并使用视觉化管理。

在更详细的层面上,如果需要的话一个迭代内可能会就每一个条目有一次讨论。经验法则是当所有的团队成员都理解了设计,并可以参与具体的代码实现时,这个讨论就结束了。在这些会话中,更有经验的开发成员仍然是最活跃的。其他团队成员通常是提问题,然后经验丰富的开发成员来回答问题。所有团队都被邀请参加具有重大影响的决策和讨论会议。

架构的每个方面都在逐步地演进或变化。除了有计划地逐步替换过期的技术外,一切都是仅在需要时才引入。一开始, 只有一个服务器实例为用户提供服务,数据库和领域模型都只包括当时所构建的故事所需要的类,我们有只有一条腿的行走骨架。它可以跳跃,在那时这已经足够好了。一旦我们意识到由于额外重量导致失败的时候,我们引入了另外一条腿,一个集群由此诞生。

根据我的经验,只要团队持续地通过讨论和工作坊来投入相当大的时间在设计和架构上,一个像这样的复杂架构是一定可以涌现出来的。

code-quality-audit.jpg
图 5: 一次外部代码质量审计结果

一个了不起的成就是当产品的内在复杂性在不断增长的时候,团队也在提高整体质量。质量是通过Sonar和许多相关工具被持续监控的。那时还有一家外部机构对该系统做了审计,并将其评为他们已经度量过的所有全球系统中的前5%。对高质量的驱动力主要来源于大多数团队成员的匠艺精神。

由于团队和产品负责人一起能够决定如何使用时间,他们通常会选择进行实验和创新。我们经常举办黑客马拉松和ShipIt Days活动,在活动中,我们尝试在一天内交付尚未在产品待办列表中的东西,基本不受任何限制。

流程

聚焦用户

我们使用了许多众所周知的实践来了解业务需求:用户故事、史诗、主题以及版本规划。尽管它们很有用,但团队把主要的精力花在就是邀请用户来或者团队自己去用户工作现场,与他们交谈,而且最重要的是观察他们的工作(“我和我的影子” - 一个创新游戏)。HaMIS 团队成员在没有产品负责人参与的情况下主动地安排这些访问。作为这一努力的结果,史诗和用户故事经常被重写或者替换。团队通常会在这之后把产品负责人拉进来。虽然产品负责人经常缺席这些互动,他或她仍然决策相关需求条目是否应该放入到产品待办列表中,放的话放到什么位置。

LeSS规则:所有的优先级排序都通过产品负责人,但是澄清尽量由团队和客户/用户以及干系人直接进行。

用户参与到了开发流程中,他们每周访问团队。有些时候整个团队会带着笔记本电脑去用户所在的地方工作几天。有些功能需要更多的反馈,而近距离会让这种协作更加有效。

在迭代评审(每个团队展示他们的功能)时, 产品增量被展示并收到反馈。会议室会挤满了用户和业务人员。不幸的是,越来越难让他们在每个迭代持续能来。多年以来,不断地提供新功能已经成为惯例。一开始的时候,每个人都对这么快速的交付感到兴奋。

LeSS 规则:有一个产品的迭代评审;对所有团队都是共同的。确保足够的干系人能够参加并贡献有效检验和适应所需要的信息。

sprint-review.jpg
图 6: 迭代评审

一个重要的教训是来自于产品负责人或类似角色的人的评论,永远无法替代与用户的交谈。在复杂的挑战中与用户的协作变得更加重要。有时团队会误解需求。这会导致在后续的迭代中重写相关功能。一个有趣的观察是与用户交谈似乎有时候很困难。但用户被问到具体的问题时,他们真的很喜欢说。当我们在寻找具体问题的具体答案时,他们会阐述各种细节。这是因为在他们的世界和我们的软件世界之间有着不同视角。尽管如此,团队成员发现与真实用户交谈绝对是探索需求的最有效最准确的方法。所以即便困难重重,但总是值得付出的,所有的参与者都受益于此。

另一方面,需求往往不明确或理由不当,这通常是由于用户使用旧系统的方式与港口管理部门对改进现有流程的期待之间存在差异。解决这个问题的通常解决方案是简单地选择一个最可行的方法,并向所有人展示。换句话说,做一个实验。与进一步讨论或将问题推回业务人员相比,在这条捷径上做更改仍然更具成本效益。可能这一方式可行的最重要原因是高级管理层对产品负责人的信任。想象一下,四个团队在一个或多个迭代期间的成本,以及在后续迭代中部分或者全部替换相关功能的重复成本。

我们犯的一个重大错误是,产品负责人与所谓“主题专家”或“领域专家”的合作,他们实际上是收集信息、与人会面和编写需求的分析师。

他们创建了另一个“被职能分析过的请求队列”,包含了更多的WIP,换手和信息分散浪费。这种方式阻碍了团队真正地理解问题及去问“为什么”。不仅可能导致真正的理解在翻译过程中丢失,而且还切断了第一个反馈环。

最终,我们决定应用这条 LeSS指南:进行实际开发的特性团队更多地帮助产品负责人,与用户直接交谈并承担大多数的需求澄清工作。因此,产品负责人更聚焦在优先级排序,团队聚焦在澄清。

因此,对需求条目的分析和探索从分析师转移到了团队。“书呆子”提不出正确的问题因而不应该与业务方直接交流的假设被证明是完全错误的。

及时(Just-In-Time)交付被改善

我们已经完全移除了这个队列(被职能分析过的请求),并逐步减少了批次大小。在前20个迭代中,一个需求条目就绪前要做很多工作。 当一个需求条目不够清楚的时候,每个团队都倾向于拒绝。在早期阶段(大多数的澄清由团队来做之前),这促使了产品负责人和“领域专家”(实际上只是分析师)一直花时间“准备”。因此产品负责人通常会提前许多迭代准备条目。在某个时候人们意识到这种“准备”只会让事情变得更糟。前置时间很长,过早准备在本质上是使反馈环更长或太晚,毕竟准备的信息毕竟不是真正有用的。只会让过分加工、WIP和换手带来的浪费增加。

这首先转变为更加有意义的和强化的产品待办列表梳理活动,产品负责人有时会给出刚有的想法,然后团队对其进行定义、拆分或者编写为更细粒度的条目

换句话说,团队接手了条目澄清工作。团队做澄清更加及时。需求条目只是在一个迭代前才准备。此外,团队开始愿意接受相对“没就绪”的需求条目,然后在迭代期间进行所有需要的分析(与用户交谈以进行条目细化和澄清)。在某些时候,任务没有在迭代计划会议的第二部分中定义,而是在迭代期间当团队准备工作在下一个条目的时候才开始编写。这么做的原因是当有人问,“有人知道这项任务是关于什么的吗?”的时候就产生了浪费。这是任务太早被创建了的缘故。改变后的效果就是减少了任务的批次大小。

另外一件团队成员做的事就是在每日站会上,在准备开始一个新条目之前,先不断地互相询问如何帮助完成已开始的条目。这样的做法能够将 WIP 减少为每个团队两到三个条目。接受这么一个事实,当有团队成员没有太多工作时,先试图帮助其他人完成一个条目。结对与这样的做法非常适配。

更多的工作,所以更多的团队?

我们的团队在持续地改进,并且取得了很大的成果。组织里的其他人也注意到了。这带来了两个影响:

  • 其他的IT部门和团队开始引入看板或者Scrum
  • 有预算的业务人员开始提出越来越多的请求,甚至来自于鹿特丹港以外的地方

大概两年前阿姆斯特丹港也想要用HaMIS来替代他们的系统。这并不意味着他们直接下载我们的软件使用;这意味着我们的团队和产品负责人突然有了一群全新的干系人和用户群体。增量交付和与用户和客户密切协作的原则仍然适用。不同的是团队还需要花些时间在阿姆斯特丹。

LeSS 原则:产品的定义应该是在实际的前提下尽量广并且以终端用户/客户为导向。随着时间的推移,产品的定义可能会扩大。我们倾向于更广的定义。

产品待办列表包含了好几年的工作。所有的干系人都希望获得他们的价值,而且最好是在昨天。这自动地触发了扩展更多团队的问题。更多的人也就意味着可以交付更多,对吗?每当这个问题响起的时候,团队的答案都是“不!”

我们意识到请求更多的团队这本身就是一个不正确的请求。更多的团队和更多的交付之间的相关性充其量是微弱的。在最坏的情况下,它可能会产生完全相反的效果。在这些请求被提出之后,团队也提出了一些问题:

  • 需求到底是什么?足够清晰了吗?
  • 这应该属于HaMIS产品的范畴之内吗?

最重要的结论是团队宁愿通过更好的协作方式来提高效率、改善组织系统,特别是与用户和干系人合作,而非引入新的团队或团队成员。最终团队和管理层就这份思考达成了一致意见。我们都强烈地感觉到,即使过去四年了,系统中还有很多东西可以被改进。我们回到了这一观察,最重要的改进领域之一就是产品待办列表。这也是产生上述问题的原因。

在最初的三年,只有三个团队在开发HaMIS。最终,团队自己决定可以雇佣更多经验丰富的男女工匠,创建另一个团队,并且仍然保持战斗力。有新团队成员加入的一个好处则是他们从其他项目中带来的经验。

组织

自管理的、跨职能的特性团队

花费了很多努力才让团队做到自主决策。这其中的挑战并非来自于团队,而是来自于组织的其他部分。管理层和其他相关人员习惯了某些工作方式(“做决策是我作为一名管理人员的职责”,而这些职责是要被转移到团队的)。 每当有外部人员建议去做一些改变或做决策的时候,我们的主要口头禅变成了:“把这个问题带给团队吧!”

这种管理层对整个团队的信任创造了责任感。这是一种对于团队有能力做出具有重大影响的决策的信任。管理层和产品负责人也逐步停止了针对团队成员个人的具体任务指派或者任何形式的绩效评估或反馈。

LeSS 规则:每个团队是:(1)自管理的、(2)跨职能的、(3)同在一地的、(4)长期的

团队成员主要认同整个产品,因此是所有团队一起;其次才是他们各自的团队。团队相当稳定,尽管他们在4年内曾决定过3次团队重组,以便能更有趣、更好的知识分享,并能跟其他人更紧密工作。

重组通过一个大约 1-2 小时的自设计团队的会议完成。

  1. 在便利贴上写下一个团队应具备的所有技能/职能。
  2. 移除掉重复或者类似的技能。
  3. 对于保留下来的技能达成一致性意见。
  4. 将这组技能复制 4 份,然后放到 4 张桌子上。
  5. 每个人在三张不同颜色的便利贴上写下自己的名字:一种颜色代表自己精通的技能,第二种颜色代表自己平均水平的技能,第三种颜色代表自己想要学习的技能。
  6. 每个人四处走动,将他/她的所有便利贴放置到一张桌上对应的具体技能处。
  7. 在有第一版团队组成后,每个团队都讨论一下看看团队与团队之间是否平衡,并直接与相关的团队进行讨论,然后做出相应的调整。
self-designing_teams.jpg
图 7: 团队自设计会议

内部和外部关注

最大的挑战之一是摈弃这样一些说法,比如“我们不应为此负责,他们(业务、管理或其他一些人)才是应该去做的人。如果我们去做,那么我们编代码的时间就会变少了”。很长一段时间,由于多种因素的共同影响,团队缺乏外部关注。当人们逐步认识到这些“外部”事务 - 比如理解用户在现实世界中是如何工作的 - 对于交付真正的价值至关重要,以及工作的代码不一定就等同于价值的时候,焦点才慢慢地转移。自管理团队比外部任何人来处理这些问题都更有效率。因为没有翻译,也没有由于技术限制等原因中断的反馈环

发展多面学习团队成员

团队跨职能,能够覆盖完整交付所需的所有方面。这在很早就实现了。还发生的是在团队内部逐渐形成技能交叉。结对工作以及整体协作激活了团队成员对新技能的学习。在某些时候几乎每个团队成员都能够完成。在某个时候,几乎所有团队成员都能做任何职能的工作,从而成为了通才专家。例如,在一开始,测试人员主要是写自动化测试,但慢慢地他们也开始写生产代码。前运维团队的运维人员大部分时间都是在写代码,因为并没有那么多的运维工作。

跨组件团队

当引入 Scrum 时,团队是跨职能的,但仍然是特定团队专注于某些特定组件。一个团队负责消息传递,另一个团队负责“港口地图”,还有一个团队负责“船舶检查”。PO 要为某个特性的开发选择一个最合适的特性团队。随着时间的推移,他们开始变得跨组件,从而工作在为交付任何特性所需的的任何组件上。慢慢地,任何一个团队都有能力做任何事情。换句话说,团队在不太熟悉的领域知识学习上做了很大投资。最终,团队之间在知识领域方面没有显著差异

一个非常有趣的好处就是架构复杂性因此而降低。选择过于复杂的解决方案的倾向变得很小。相反,为了降低跨组件的复杂性,团队进行了更多的重新设计和重构。

团队间协调

在早期“Scrum-But-But”(极伪 Scrum)的时候,有一个 Scrum of Scrums 会议,每个团队所谓的 Scrum Master 会来跟项目经理们一起讨论话题。哎哟!

一段时间后,每个团队会派代表来,不一定是 “Scrum Master” 。那时,这些会议并没有讨论太多相关问题。

最终,随着所有与项目管理相关的活动消失或者被Scrum活动所代替,真正的协调以多种不同的方式直接发生在团队成员之间。没有为此召开专门的会议。当有需要时,任何人都可以为了重要决策组织多团队设计工作坊。每个人都被邀请参加,但非强制。

除了设计工作坊,我们定期组织代码道场来做知识共享,TDD kata,讨论一些棘手的方法等。由于强大的通才专家文化和人与人之间良好的协作,并且只是在同一地点工作的几个团队,因此不需要正式的实践社区。相反,涌现出来的多团队协调机制已经足够好了。

汇报

在 HaMIS 唯一的汇报途径就是 Scrum 的各个实践。其实团队不以任何方式向任何人汇报。虽然存在直线经理,但是他们甚至离得更远。半数以上的团队成员是合同工,其他的是员工。任何团队成员的直线经理其实并不知道他们在做什么,也不会对他们的工作有任何影响。

这个情形下最值得一提的是团队成员都认为他们是 HaMIS 的一部分,而非他们的官方组织。

横切活动

工作坊的决策通常会带来一些与单个功能无关的工作(通常是一些支持基础架构的工作,例如更换应用程序服务器或 Java版本升级)。这种工作条目通常被添加到产品待办列表的底部,在迭代计划会议期间得到产品负责人的同意之后,其中一个团队将负责该工作。这个团队本质上其实就是在一个或者几个迭代期间的临时基础设施团队,尽管我们并没有正式为该团队如此命名。

UI设计知识

在最初的 Scrum-But-But 时期,UI 设计是由一位专门的技术“架构师”完成的,他在概念验证中事先设计和开发了系统的前端。但他不是 UI 设计专家。在引入 Scrum 之后,这个责任就完全交给了团队。因此,任何人都可以对用户界面设计提出建议,并一起作为一个团队来决定。

不幸的是,这并不足够,因为没有人有适合的知识和经验来真正做好这项工作。每个人,包括产品负责人、用户还有团队都对 UI 设计和由此带来的用户体验不满意,但是没人知道该怎么解决这个问题。

解决方案是聘请一位专家,她在自己的团队中是一位通才专家,但同时担任其他团队的老师和教练。早期,她的时间大多花在向其他团队展示一个好的设计上;后来,她花更多的时间在结对工作和评审其他团队的 UI 设计上。

跨团队工作约定

所有团队共享一份 完成的定义。这是必然需要的,因为每个团队都可能交付任何一个特性。

任何会直接影响到生产代码的重要架构决策都在第一时间与其他团队共享。每个人都被邀请参与讨论相关解决方案,参与的团队成员能代表其他人做出决定。决策几乎都是基于共识而非妥协。

任何人都可以提任何建议,随之组织一个会议,在其中可以做出重要的决定。提出建议的人必须有有效的论证,这会收到其他人的挑战。因而,除了产品负责人外,没有人有特别的权利来强制任何决定,无论是通过微妙地大力影响还是直接强加。

事件

迭代计划

在一个迭代开始时,首先所有的团队与产品负责人一起聚集在一个物理(卡片贴在墙上)产品待办列表的前面,即将到来的三个迭代的所有条目在其上始终可见。每个团队都会选择待办条目,与其他的团队一起协商,并澄清任何可能的跨团队协作问题。简而言之,这是一个常见的 迭代计划第一部分。整个会议持续10到15分钟。

在团队各自的迭代计划第二部分中他们对所选的待办条目做进一步讨论和计划。产品负责人并不总是在场,但如果需要,可以随时通过电话联系。

LeSS 规则:迭代计划由两部分组成:迭代计划第一部分是所有团队共同做,而迭代计划第二部分通常由各团队分别做。

产品待办列表梳理

第一年,我们所有团队一起举行产品待办列表梳理工作坊。每个人都非常了解所有的条目。但是感觉效率并不高。也没有太多的合作。团队成员会觉得在这样一个已经很不高效的会议上发言有罪恶感。

product-backlog.jpg
图 8: 产品待办列表,最高优先级的条目。每个横向车道贴的是一个团队选择的条目。列代表条目在每个迭代的分布

这后来变成了一个每个人都参与的“粗略估算”工作坊。在 LeSS 中,多团队 PBR关注在估算上。期间团队提出问题并讨论关键点,每个人都一直学着避免太过细节。

我们曾经考虑过团队派代表参加工作坊,但是在这种工作坊中获得的知识被证明对每个人都很有用,而且团队的数量也不多。

在聚焦于估算的多团队PBR之后,每个团队选取一些最可能他们做的条目来进行团队级别 PBR

这种方式的一个问题是,在迭代计划会议期间,由于优先级的调整或者为了消除团队间的约束,条目可能会在团队之间切换。这是很好的敏捷性,但是对于新接手条目的团队来说通常需要对这个条目重新进行梳理。

回想起来,LeSS 指南建议召开一个由每个团队的代表参加的整体 PBR,一起做一些轻量级的澄清,这将减少这个问题。所有团队中都至少有一些人会接触到所有条目,这将提高团队间的灵活性。但是我们没有做那样的尝试。

LeSS 规则:产品待办列表梳理(PBR)由每个团队对自己可能接下来要做的条目进行。

LeSS 指南:(1)在团队的PBR之前举行整体的PBR来探索哪个团队工作在哪个条目上,并增加学习和对齐程度。(2)举行多团队PBR以增加共享理解并发现协调机会加以利用。

回顾

紧接着迭代评审会议,每个团队都会举行自己团队的回顾会议,通常 1 小时。

LeSS 规则:每个团队有自己的迭代回顾。

在团队回顾之后,所有团队一起进行整体回顾。每个团队提出他们想交流的结论/行动,以及希望与其他团队交流的事情。

一个难以解决的系统问题的例子是产品待办列表优先级所导致的大爆炸效应(而非最小可行产品)。尽管目标是尽快关停老产品,一个或者多个团队注意到他们正在工作的条目与这一目标并不一致。换而言之,大多数优先级靠前的待办条目看上去并不那么重要。

在整体回顾中,如果其他团队也同意这个问题需要被解决的话,那么这个问题将被解释清楚并且定义相关行动项。行动项被分配给一个具体的人。他可以是一个团队成员、产品负责人、一个Scrum Master、或者一个管理者。就上述例子来说,产品负责人将在下一个整体 PBR 会议期间与团队一起解决问题。在这个整体 PBR 会议中,团队将深入问题的细节,向产品负责人提出排序的建议,从而重新决定优先级。

在这一流程里,只有当“我们(团队)能自己解决这个问题吗”的回答是否定的时候,这个问题才会交给其他人。一旦行动项被分配了,就不再有特定的后续流程。这个行动项假定就是越快做完越好。团队们并没有一个记录系统级问题或改进项的列表,因为他们聚焦于尽快解决问题而非维护一个列表。

在下一个整体回顾会议时,每个人都会被提醒上一个回顾时的行动项及其完成状态。通常系统级别问题只有一个,最多不超过三个。

如果行动项是分配到一个具体团队的,那么这个团队会在他们的迭代待办列表里放一个便利贴,贴在那些只与他们团队相关的行动项旁边。

LeSS 规则:在团队各自的回顾之后举行一个整体的回顾来讨论跨团队和系统性的问题,并创建改进试验。这个会议由产品负责人、Scrum Master们、团队代表和管理者(如果有的话)参加。

overall-retrospective.jpg
图 9: 一个阳光下的户外整体回顾

迭代待办列表和每日站会

每个团队的迭代待办列表都被可视化呈现,团队每天站在迭代待办列表前开站会。为了便于其他团队来观察,团队的站会并非同时召开。通常会有一些其他团队的成员来参加。

sprint-backlog.jpg
图 10: 一个团队的迭代待办列表(这并非是一个每日站会:-))

LeSS 规则:每个团队有自己的迭代待办列表。

实践

验收测试驱动开发(ATDD)

在引入 Scrum 期间,团队已经开始使用 Fitnesse 和一些其它工具。他们花了一些时间才学会正确地定义测试,同时不会弄得一团糟。在某个时候,他们通过 验收测试驱动开发(Acceptance Test Driven Development,ATDD) / 实例化需求(Specification by Example) 实践来开始使用 Fitnesse 记录需求规格。这发生在迭代开始时,团队与产品负责人、业务专家或用户一起来做。

完成的定义

LeSS 规则:完美的目标是改进完成的定义以达到每个迭代都产出可交付的产品(或者更为频繁)。

在每个迭代后都有一个潜在可交付的产品增量投入生产(只有少数例外,他们认为是很大的失败)。生产部署发生在迭代完成后的几天内。HaMIS 团队并没有参与这个大约 1 小时的短暂过程。只有流动的基础设施专家,产品负责人和外部基础设施提供商参与了该过程。

其它所有一切都属于完成的定义的一部分,并都在迭代内完成。为了达成这一点,我们付出了很多努力。随着时间的推移,这变得越来越有挑战,因为不断增加的复杂度,与其它系统的依赖,而它们并没有我们那么敏捷。这涉及到所有的测试(全部自动化),客户文档,部署脚本,生产数据库更改脚本化,等等。

LeSS 规则:对整个产品有一个共同的完成的定义。

而且,所有的支持工作也是由特性团队完成的。比如,配置、所有工具的升级。

真正的 DevOps:: 消除单独的运维组

当引入 Scrum 时,有 3 个团队在做新产品的开发,另外还有一个由 6 人组成的独立的运维团队 24/7 的全天候运维现有系统。当新系统的第一部分发布时,该运维团队也接管了新系统的运维。起初,这并不是什么大问题,因为对所交付功能可用性的要求并不高。开发团队通常可以在第二天处理相关问题。

随着时间的推移,HaMIS 发展壮大了,也引入了更大的变化。尽管运维团队的 Java 经验有限或没有经验,但我们都决定引入 DevOps:解散独立的运维团队,将运维人员分散到 HaMIS 开发团队,并将运维增加到特性团队的职责中。首先,前运维人员(现在在特性团队中)仍被安排为 24/7 待命,以防生产中发生某些事情。渐渐地,运维人员对 HaMIS 的开发贡献越来越大。他们都有机会向队友学习 Java 以及许多应用实践和技术。

另一方面,如前所述,新产品在投入生产时肯定会存在问题。也必须有人解决这些问题。解决方案是由一个特性团队在一个迭代里担当运维团队。这样,我们就不再有固定的运维团队,而是团队间轮换做。一个正常的开发团队除了做正常的特性开发外,会临时变成一个运维团队。他们会处理任何线上问题并提供二线支持。一开始,这个团队将整个迭代都花在异常、监控、问题等方面。由于任何开发人员都宁肯写代码构建一些东西也不愿解决自己创建的缺陷,所有的团队都会花时间分析和预防这些问题;这就是俗称的“吃自己的狗粮”。最终,问题的数量减少了,即使系统复杂性在不断增加。 “运维团队”开始交付越来越多的常规特性条目。更加强大的持续集成(包括行为和系统两方面)在这方面帮助也很大。

顺便提一下,团队通常将基础设施配置工作作为一个或多个产品待办列表特性条目的任务。再大的基础设施工作也最好是拆分为小的任务,在客户特性的上下文中增量地来做。

正式来说,基础设施是由外部管理的。实际上,开发团队监控整个基础架构,引入和脚本化更改。外部的公司或多或少只是执行团队定义的任务。我们花了很多精力让他们参与到这个过程中,从而越来越像一个团队,消除了这最后一个职能单元的依赖。团队和外部公司之间通过 Skype 进行直接的沟通,并且来自外部公司的人每周会有一天到访我们的办公室。

可能其中最关键的一点是让基础设施专家作为旅行者穿梭于团队之间。他确保交付过程顺利进行,并承担了大部分的与外部的服务提供商沟通的工作。理想情况下,并不需要这项工作,但幸亏有他,我们才几乎在每个迭代后能够交付。

通过此措施,基础设施和所有其它共享资源队列都将被移除。团队能够将来自业务或用户的请求完全交付到生产中。一开始,在交付 PSPI 和实际部署到生产环境之间有一周的时间。 通过外部公司的人员每周一次的到访,这一等待时间减少到大约 2 天。除此之外,团队不必等待任何人来做交付。

IT 管理层也开始意识到这不再是一个项目,而是持续的产品开发。 尤其是在去年,为大量涌入的新请求保留了新的预算。也由于取得的出色效果,项目范式组织悄然转变为产品范式组织。

项目管理

说到“项目”,在早期的 Scrum-But-But 时代,由于在更大的组织内,传统的对开发范式的假设仍然基于项目而非产品,HaMIS 有两名项目经理和一名项目集经理。其中一名项目经理是正式的 HaMIS 项目经理,另一位主要负责与其他公司或部门就相关依赖项目进行外部沟通和协调。

不幸的是,这些角色在为了更好导入Scrum所做的重组后被要求保留。这导致了一些与产品负责人之间的系统性冲突,因为产品负责人应该完全负责与外部干系人的沟通,以及与其他部分的协调。但项目经理和项目集经理也试图做那些事情。

但是,他们也确实帮助完成了一些行政事务,比如为传统管理者制作传统的项目报告,更重要的是确保每个人都发到工资。

任何与团队相关的组织方面都是由团队而非管理者来做的,包括:团队设计(重新设计)、招聘(除了财务部分)以及解雇人、重大架构决策、工作流程修改。顺便说一下,招聘是由一个团队通过一整天的实操评估来做的。活动包含与候选人结对编程、邀请他参加Scrum会议和设计工作坊。

实际上,尽管项目和项目集经理还存在,但是他们并没有以任何有意义的方式成为组织的一部分,只是偶尔通过满足团队的请求来提供帮助。