本文要点
- 团队的架构反映了产品的架构。
- 分布式团队可通过使用一些远程结对编程技术和工具开展结对编程。
- 微服务会影响良好分布团队的结构。
- 通过鼓励成为“T 形”工程师,增进团队内的协调。
- 通过使用云,增进分布式团队持续集成和自动测试的效率。
如今,分布式团队已经成为许多企业的标准形态。很多公司具有国际化背景,通信技术使员工不必待在同地“办公室”中,不少新型的工作环境可以是“游牧式”的。我们认为,一个分布式团队完全有可能成为一个高效的团队,但必须要多花一些精力去克服那些因距离而产生的固有挑战。
这是“分布式敏捷:如何与分布在全球的团队合作”系列文章的第一部分,该系列文章探讨了分布式团队文化差异的影响。读者可以通过 RSS 订阅,及时获取关于内容更新的通知。
引言
企业都希望能具有高生产率的工程师文化,但是无论企业采用的是整体共处一地的集中式办公,还是员工分别位于遍布全球的分布式团队中,工程师文化都应是一样的。
分布式团队业已成为一种工作常态。不少企业为将有才干的员工招致麾下,会考虑使用分布式团队。人才搜索通常从企业总部所在地开始,进而快速地扩展到世界各地。但是在一些情况下,建立分布式团队会引发不期望看到的结果。
很多分布式团队在建立伊始,受制于总部和各分部(Supplier)间工作合约的设立方式。其中最常见的问题就是将不同类型工作的分解发包,即“总部给出设计,各分部只编写代码”。这样的分布式工作形式对企业和合约都有深远的负面影响。我们甚至可以认定,此类分解工作方式正是导致了整个“外包”行业声誉受损的部分原因所在。
不幸的是,这种分布式结构对提高工作质量也没有任何好处。由于将工作分解为多个方面,因此工程师无法给出能切实改进整个价值链范围的举措。在生产版本交付期间,各部分间的交接为引入异常提供了过多的机会。
此外,分布式团队也会影响产品的架构。根据康威定律(Conway’s Law):
“对于一个设计系统的企业,其所产生的设计和架构等价于企业间的沟通结构。”
该定律是基于如下的推理,即为了让软件模块工作,在多位编程人员间必须经常相互通信。因而,系统的软件接口结构将反映出软件生产企业的社交边界,跨越这一边界会导致通信更加难以开展。
支持康威定律的证据已被来自 MIT 和哈佛商学院研究团队中的研究人员发表。他们发现“镜像假说(论文研究人员使用该术语描述康威定律中的“等价性”)具有强大的证据支持”,并且“在(产品)模块化中所具有的显著差异”是“与分布式团队倾向于开发更加模块化的产品这一观点相吻合的”。
因此,软件的质量依赖于企业的结构,还有团队成员间的合作程度。
分布式团队面对着多种挑战,而这些挑战是存在一些解决技术的。本文下面将分别介绍这些技术。
我正和另外三人正共同开发分布式的敏捷框架,他们分别是: Hugo Messer 、 John Okoro 和 Arjan Franzen 。
我们尚处于一种初始阶段。我们认为,将这一框架的大部分内容开源出来是非常有必要的。我们开发的框架包括如下八个“板块”:
- 文化
- 组织
- 产品
- 团队
- 架构
- 工程实践
- 沟通
- 工具
每个板块都有三个元素:
A、问题:组织可以用来评估当前状态的一系列问题
B、品德:促进分布式合作的行为
C、实践:已经完成的工作,由从业者进行分享的内容
我们应就如下问题质询分布式团队,目的在于确定团队工程师文化的健康程度及相关的挑战:
工程师文化
好的工程师文化是敏捷团队的核心问题。健康的工程师文化将使一个团队得以构建对自身而言有意义的产品。
问题
- 我们的团队是否遵循着基于工程的实践,而非基于规划的实践?
- 对实践的采纳是否均等地扩散到我们的分布式团队中?
- 在扩散采纳过程中,我们是如何做的?
- 我们的系统从设计上是否支持跨地域采纳?
优点
-
力求完美。团队应完全地拥有自身的代码,并总是力图编写干净、可读、可维护并可扩展的代码。好的敏捷团队在工作中力求完美,并深谋远虑。这意味着,团队应预见到,在缺少维护的情况下,易于更改代码的时间期限。我们在初创公司中的一个团队在解决架构问题时,总是习惯于从如何增加用户基础以及如何为达到团队目标而灵活实现代码角度考虑问题。
我曾看见开发人员和经理探讨,为解释代码的行为,应该如何添加注释或撰写文档。这听上去感觉代码并不是正确编写的干净代码。
-
内建质量。好的敏捷团队对软件的质量负责。团队会尽量根据每个客户的需求,构建高质量的软件,并以侧重于避免质量问题作为第一要务。
一个敏捷团队应谨记,自产品开发一开始,就应认真地对待质量问题,并将此贯穿于整个开发过程。
-
增量过程改进。检查和采纳是敏捷团队的核心所在。团队应不断地检查、学习并改进。企业仅需要创造一个环境,使得员工在这样的环境中可以自由地共享看法,实验新的方法,使得他们可以持续地改进产品和过程。
更进一步,如果员工具有了好的想法,可使他们并未得到授权,那么此时他们并不会分享任何改进想法,或是承担对这些想法的工作责任。一位真正的领导人,应赋予团队权力,鼓励团队从失败中学习。这种允许失败的环境,对于形成好的工程师文化是非常重要的。
-
学习。让我们正在做的事情更好。
学习的心态会导致成功的产品。团队从各种反馈中学习。他们能从单元测试中最先得到的反馈,是与代码相关的,然后是从产品和用户中。反馈的循环越短,学习到的就会越多。此外,好的工程团队中,人们会互相分享他们学到的所有东西。这是整个工程师文化在学习环境中的生存之道。
-
简洁性。该优点是极限编程中最重要的价值之一。这一方法不仅倾向于简单设计,并且对未来做了预先考虑,而且还聚焦于当前的需求,使代码完全可以扩展,以适应未来添加的新需求。
实践
远程结对编程
结对编程是一种敏捷软件开发技术,两个编程人员在同一台工作站上一起工作。其中一位称为驱动者(Driver),具体编写代码;另一位则称为观察者(Observer)或浏览者(Navigator),审核每一行输入的代码。两位编程人员的角色是频繁交换的。结对编程的优点突出,列举为:
- 质量更好;
- 缺陷更少;
- 技能改进;
- 交付更快。
但是当要与身处其它城市甚至是其它国家的编程人员共同结对编程时,我们应该怎么做?是的,借助于使用一些远程结对技术和工具,我们依然可以开展结对编程。如果我们所使用的工具提供了协作编辑器、屏幕共享、安全网络和虚拟化等功能,我们就可以创建一个远程结对编程的环境,使得结对双方就像是毗邻而坐一样。
下面列出了一些实现远程结对编程的工具:
- SelfLanguage
- SqueakSmalltalk
- VirtualNetworkComputing
- RemoteAdmin
- NetMeeting
- SpeakFreely
- ScreenMultiplexor
在和远程伙伴结对编程时,我们也可以使用下列的协作编译器:
- EmacsEditor ;
- QuantumPairs ;
- Sangam, EclipseIde 的 PairProgramming 插件( Sangam );
- Saros, EclipseIde 的 PairProgramming 插件( http://www.inf.fu-berlin.de/w/SE/DPP );
- SubEthaEdit 和 AppleiChat;
- gobby (GTK);
- MoonEdit ;
- MultitaneousEditor (Java);
- UNA( N Brain );
- beWeeVee,基于 Silverlight 的实时协作写字板, http://www.beWeeVee.com ;
微服务和分布式团队
“微服务是 SOA 架构风格的一个变体,它将应用构建为一系列松耦合的服务。”
在分布式团队中,很多时候人们会共同面对一些技术挑战。例如,如果位于不同地点的人们工作在同一个代码库上,这会导致一些覆盖或集成上的开销。那么我们应该如何设计架构,使得多个团队可以在没有任何麻烦的情况下持续生成价值?要实现这一目标,我们可采用松耦合的代码或架构。使用微服务就是最好的方式之一。微服务并非适用于任何类型或规模的应用,但是领域驱动面向服务的应用无疑将会受益匪浅。
那么微服务是如何影响一个好的分布式团队结构的?根据康威定律,破坏服务的独立性就破坏了团队的独立性,因此我们应确保企业可以处理如此层级上的通信和集成。让具有交叉功能的小规模团队处理位于不同地点上的不同服务,这种方式将会工作良好。
根据业务能力不同,多个远程交叉功能团队处理不同的服务
在分布式团队中使用微服务的一个好处是,可以使用不同的技术栈构建不同的服务。例如,可能一个国家的团队擅长使用 C++,而另一个国家的团队擅长使用 Java。我们在构建产品时,可以考虑产品的适用性和技术的可用性。这意味着一种去中心化的管理,即位于不同的地理位置上的多个小型协作团队。
虚拟办公室
分布式团队中的成员身处不同地理位置,他们之间需要一些会面时间。我们一个位于印度的团队习惯与位于阿姆斯特丹的员工保持 Skype 电话交流。这种工作方式增进了团队成员间的协作。各成员感觉可以更开放地提出问题,并相互帮助。
使用 Skype 时,我们还应将大屏幕显示用于团队工作区域,这样人们可以相互看到整个团队。此外,我们也可以通过一次呼叫联系上所有的人。
SOCOCO 是一种创建虚拟同室办公环境的好工具。使用该工具,我们可以在一个真实存在的地图上创建一种真实的办公室,而非像是“通道”、“消息线程”或“工作组”这类抽象概念。此外,仅需要做一些点击,就立即可用视频、音频和屏幕共享,这样会议就可以平滑地同步开展。
图:一次敏捷团队会议正在 SOCOCO 在线办公中进行
Arzan Franzen 提出的“即席协调、团队如一和 T 形团队成员”理念
分布式团队的正常开始状态是,团队中的每个成员主要聚焦于自身的技能专长。每个成员的关注适合自身的预算,并根据“个人工作列表”开展工作。这种工作方式可能会产生一些障碍,团队成员因而被定位为“没有时间分心做其它事情”。在分布式工作中,每个团队成员都需要为与他人的协调而额外付出一些工作,包括考虑如何设置工具、召开协调会议。这些额外付出是导致大量重做的原因所在。
如果推迟团队间通信或协调,无疑也延迟了学习过程,进而会生成或交付错误的事情。我们可以说,名目繁多的协调会议对协作具有反作用。如果我们整天都耗费在各种协调会议上,那么就没有时间去完成自己的工作。虽然这一看法切实存在,但是如果人们“节省下”讨论的时间,这就等同于延迟了对错误的审查。要实现好的分布式环境下工作,需要具有即席通信的设施。例如,“时刻保持开放的Zoom 会议室产品”(always-open-Zoom-meeting-rooms)、针对每个会议室的Zoom 产品或 SOCOCO 这样的虚拟办公室系统,可使团队易于互相碰头,并开展内部协调。
要构建一个成功的团队,需要在改进内部协调上做大量的工作。团队(对每个人以及外部利益相关者)应给出大家何时需要做一次协调,或是大家应“坐在一起”讨论一次。这就是非常重要的即席协调时间,无需等待每周的协调例会。
开完即席协调会后,必须达到团队可被企业中的其他人作为一个整体对待的程度。我们常常会看到本地专家(Local Export,也称为“英雄”,Hero)身兼数职,企业将此看成是对他们的额外补贴。这意味着他们可以在团队的惯常工作中时不时松懈一下。这种文化应该被那种将团队以整体担责并管理的文化所替代。将团队看成一个整体,这意味着外部利益相关者不能干扰团队的日常规划活动。团队知道他们是以一个团队而承担责任。虽然本地专家可以很好地完成团队的职能,但是专家是否可以超脱其中,这最终仍然取决于团队。
需要让团队明确的是,在团队内学习并非浪费时间,虽然这的确要占用一些时间。因此我们必须按时完成学习,并让知识在团队内传播。这为团队提出了一个规划上的难题,需要团队去解决。一旦团队解决了这一问题,他们就在向更自治和更成熟(从敏捷价值的角度看)的团队转变上迈进了一大步。一个行动一致的成熟团队会洞察那些能危害生产流水线稳定运行的障碍,并尝试一些能避免这种“痛苦”的方法。
“将痛苦放在台面上”这一口头禅,从本质上是团队实行的一种非正式的风险管理技术。团队试图通过缓解积压工作(Backlog)上发现的风险,防止在交付流水线产生阻塞。实现工具包括概念验证(PoC,Proof of Concept)和探针(Spike)等工作项。两者并非一定会立刻向客户交付价值,但是能确保今后的工作可在系统中持续流动。
我们所希望的是具有高度积极性的专业人士,而非“当家的”(Prima donna)英雄,人们有权根据来自于利益相关方的压力管理他们的积压工作。可能有人会指出,本文所提出的方法“永远不会起作用”,因为“每个人应必须能在任一时刻做任意事情”。恐怕我必须要指出,这个看法也是错误的。本文前面所指的是“T 形”团队成员,即这些成员具备某一个专业方向上的特长,但是也宽泛地掌握一个团队取得成功所需要的各项技能知识。这样的成员才是团队中真正的“英雄”。只有在团队行动如一并管理如一时,才会产生这样真正的敏捷“英雄”。团队需要在内部以非正式的方式扩散知识,并优化以往的资源。
Arzan Franzen 提出的“流程、持续集成和尽早测试”理念
《DevOps 手册》(The DevOps Handbook)一书介绍了“三方法”(The Three Ways)是如何用于 DevOps 实现的。首个方法是优化流程。所有的概念都源自于丰田的精益做法,这是过程控制的核心。作为流经系统的工作包(Work Package),流程是可见的。相比于传统的规划方法,这种管理方法是一种完全的转变。
传统的方法首先创建工作声明(Statement),进而评估、实现并测试该声明。所有的控制都是围绕着容量展开的。
如果工作包中存在中心视图,此时过程流管理最为适用。我们需要当前已打开工作的中心视图,并可使用当团队完全是共处一室办公时的同样方法。这时最重要的是对工作的概览,最好能将中心 JIRA 面板显示在一个大屏上,并在每个分布式团队成员的桌面上显示书签。
持续集成是团队成员必须参与的首个实践。从本质上看,这一工作用于将集成中存在的延迟尽可能多地从过程中移除。
如果在集成中存在着延迟,这表明团队中的成员在工作中各自为政,可能是独自一人,也可能是基于小组的分支。有时可能十分需要这样的解决方案,因为它能防止软件完全失败。但是,我们不能将这些类型的分支看成是一种“结构化开发的好方法”,而应看做是相当邪恶的。持续集成要求我们尽可能多地杀掉那些长期存活的分支,并且每天至少合并(Merge)到主线一次。这意味着大量的协调,可能是结对编程。
当集成工作保持一致后,团队就可以更改系统的设计,使系统对更改更为开放。要在每次发布时能给出一个可靠的发布,我们需要添加更多的鲁棒性(在工程上是逐步添加的)。团队的分布式特性并未阻碍团队成功地转向持续集成环境。随着分支的最小化以及合并的完成,我们可以去确认安装了用于保持监控的构建服务器(CI 服务器),并启动了首个质量检查。这样,我们就启动了交付流水线。
在 CI 服务器就位后,我们就可以在 CI 服务器上做构建,并编排自动化测试。这关键在于团队内部一起工作(开发 - 测试),确保经测试的代码非常适合代码块的其余部分,并且从业务角度看被测试的代码是有意义的。
我们需要协调外部利益相关者,评估哪些场景在失败时的副作用最大。为促进协调工作,我们应确保团队的确定期对外部利益相关者做了演示,这样团队中的部分人(开发和测试专家)就有机会定期了解业务场景。
为促成协调,出差在分布式团队中也是需要的,因为部分业务场景可能不宜于在基于因特网的交流平台上开展。我们应确保沿持续交付方向构建了自动化测试。我们首先从基本单元测试开始,继而开始自动回归,并以自动化容量测试结束。
基于云的分布式软件开发
云环境中的分布式软件开发(DSD,Distributed Software Development)正呈指数级增长。在很多情况下,无疑 DSD 是明确的选择,尤其是在新出现的生态系统中,企业想要在自身的开发项目或程序中引入外部开发人员或是外部开发团队。云基础架构升级是基于云的服务所固有的特性。但是对于一个已有的基于云的 DSD 项目,加入新的海外团队可能会带来一些技术上的和非技术上的挑战。
在技术上,云支持 DSD 团队的弹性、可扩展性和灵活性,进而整体提升了生产率。例如,基于云的 DSD 使团队可以快速地运行测试,对所需的计算基础设施进行动态的向上扩展或向下扩展,并快速生成工作软件更新。
基于云的工具可在分布式团队间分享,这是团队从项目中体验到的一个主要好处。分布式团队不会受困于技术环境的复制问题,进而实现快速开发。
团队可以使用云编程环境,它们是一些基于 Web 的在线应用,设计用于为开发人员提供开发能力。云编程环境通常由源代码编辑器、多个编译器或解释器(取决于编程语言)、调试器和用于管理独立子组件的项目或解决方案查看器。以此为基础,编程环境中还包括与代码块的链接、分享代码的协作特性、快速应用部署的虚拟机,甚至还有一些监控工具。
云代码库提供了 Web 托管功能,它利用了一些广为人知的版本控制系统的强大功能,例如 Git 、 Subversion 和 Mercurial 等。此外,云代码库通常支持一些服务和工具,包括软件缺陷追踪、发布版本管理、邮件列表和基于 Wiki 的文档。
结论
分布式敏捷团队的成功与同室办公(Co-located)敏捷团队的成功是同等困难的。在分布式和非分布式团队间,存在着一些围绕着团队的内部协调上的差异。由于团队可能并非是同室办公的,所以在分布式工作环境中重要的是聚焦于如何简化通信和协调。将团队作为一个整体管理,这是走向成功的下一步。我们需要的是一种反“本地英雄”的文化,相比起开发人员仅是在同一 IDE 内工作,以及测试人员仅提交测试脚本和需求并手工完成所有测试,持续集成的工程师实践和早期自动化测试具有更大的成果。已有大量的工作和平台可为本文给出的方法提供支持,在早期的开放式协调工作中,我们可以完全以这些工作和平台为基础。团队一旦与正确的工程师实践相结合,将会变得更加投入和高产。
关于作者
Savita Pahuja是 Scrum、精益、看板领域和其他可视化探索方法的专家。她的 IT 职业生涯前期是一名开发人员,之后在敏捷应用方面为组织作出贡献。然后她作为一名顾问和培训师转入敏捷领域。从那时之后她就针对敏捷应用和不同的客户一起工作,并进行 scrum 和看板的培训。
Arjan Franzen熟悉敏捷、DevOPs 和精益后,就对软件开发中的这些创新产生了浓厚的兴趣,并在他的专业环境中尽可能地去应用这些创新。他对这些软件开发新方法的热情,促使他创立了自己的软件公司 ZEN Software,公司为交付流水线、DevOPs、持续交付和精益软件开发等提供咨询服务,意在最小化企业发布软件的风险。随着每次发布的风险最小化,发布频率就得以增加。通过应用精益(和精益初创企业)原则,企业必然可以测定软件改进的有效性和价值,即“构建正确的事物”。如果企业构建了适当的软件(需求),并正确地构建了它们(质量),企业就获得了有意义的软件交付。“目标明确的软件交付”是 ZEN Software 公司的座右铭。
评论