第三部分。大型工程团队带来的挑战
用一个小团队来构建一个应用程序,与用10个、20个或更多的移动工程师来构建是非常不同的。很多在小团队中看起来无关紧要的问题,现在变得更大了。
确保架构的一致性变得更具挑战性。如果你的公司建立了多个应用程序,你如何平衡不从头开始重写所有的东西,同时以快速的速度前进,而不是等待 "集中的 "团队?
移动团队越大,构建就越成为一个问题。更大的团队通常意味着更多的代码和更慢的构建时间。对于一个大型团队来说,缓慢构建的代价可能意味着工程上的几个月--或者几年! - 浪费的时间。寻找支持大型移动工程团队的工具变得越来越困难,一些团队在找不到支持其使用案例规模的供应商时,会诉诸于构建自定义解决方案。
让我们来看看随着你的移动工程团队规模的扩大而变得更加紧迫的挑战。
19. 规划和决策
当你在一个只有几个工程师的小型移动团队工作时,你只是去构建新的功能。你们可能会互相讨论决定,并对代码审查提出意见,但仅此而已。在一个更大的团队中,这个过程将不得不改变,既要避免踩到对方的脚趾,又要保持代码和架构选择的一致性。
规划过程的正规化是一个值得在一定的团队规模以上引入的做法。我见过一些公司在只有几个移动工程师的时候就这样做,而其他公司则推迟到他们有多达30个本地工程师的时候。Uber很早就开始了RFC规划过程,当时的移动工程师还不到几个人。
你可能想在工程规划阶段之前,或同时正式确定规范阶段。项目延误的很大一部分原因是需求不明确和范围蠕动,以及不清楚企业想要建立什么。这通常是由产品经理启动一个PRD(产品需求文件)过程来完成的,这个文件是
一个正式的,"你现在可以开始工作了 "的工程步骤。请看这个不同公司如何处理PRD的例子列表。
iOS和Android团队一起工作规划是效率的一大赢家,但在许多公司,这些团队都是各自为政。通过一起规划功能,你可以确保两个团队建立相同的功能,而且iOS和Android工程师可以了解到平台之间的差异。你可以将功能标志、分析事件命名等事情标准化,甚至可能将类结构标准化。工程师们可以互相审查对方的代码,iOS的工程师可能会指出Android代码中一个不正确的商业案例。这对所有人来说都是一种胜利。
在Uber,使用RIBs作为我们的架构的主要优势之一是应用程序的结构和组件在iOS和Android上非常相似。这使得共享规划成为一种必然,我们只是做了一些事情,甚至没有考虑到这一点。你为什么不这样做呢?
决策瘫痪是一种情况,它出现在开始做好--和彻底--规划的团队中。我观察到团队对问题空间和替代方案做了彻底的分析,然后拖延做出决定。
我建议给计划设定时间范围,最后根据你收集的信息,采用最合理的方法。我注意到,花更多的时间在计划上,而不是在短时间内进行迭代,并在你的计划是否可行上得到反馈,这样做的回报会越来越少。这在移动领域尤其如此--在那里你可能会遇到工具和框架问题--转移花在原型设计上的时间往往比白板上的进一步方法更有用。
将 "信噪比 "调到合适的位置是许多团队和公司担心的规划问题。团队常常犹豫不决,因为他们不想制造太多的噪音,而不愿意在一个新的功能上工作。高管们有时会担心,在这些团队开始更公开地广播计划之后,他们的团队是否能专注于运送功能。
我个人只见过筒仓式工作的弊端。在微软,早在2014年就出现了这种情况。在Uber,我惊讶地看到 "向所有人广播 "的模式运作得特别好。每当一个移动团队要建立一个新的功能时,他们就会向一个只有移动端的RFC邮件列表发送一个 "RFC意向 "摘要。Uber的300多名移动工程师几乎都在这个名单上。然后,一旦RFC准备好了,他们也会向这个列表发送电子邮件。这个过程有助于及早发现问题。它还能快速传播知识,甚至帮助人们决定将团队转移到他们更热衷的领域。
此后,我为初创企业和中型公司提供了关于启动设计文件或RFC流程的建议,我的建议--简单来说--是这样的。
- 为一个给定的堆栈定义一个设计文档模板(例如,为移动、后端或网络)。
- 让大多数工程师同意这个想法。
- 开始写简短的文档,并把它们发给每个人,同时明确谁是必要的批准者。
- 沟通过度而不是沟通不足。倾向于轻量级的流程和工具,而不是重量级的。
- 观察发生了什么,并根据反应进行迭代。
如果你的移动团队还没有使用轻量级设计文档或RFC进行规划:考虑给这个方法一个机会。
20. 避免踩到对方脚趾的架构方式。
直到现在我还没有提到移动架构。难道它不是一个重要的考虑因素,即使是在应用程序很小的时候?根据我的经验,当一个团队很小的时候,架构真的没有那么重要。只要你选择了一个足够可测试的结构,用MVP、MVVM、MVC、VIPER或类似的方法就可以了。
在过去,老的Uber应用在iOS上遵循 "苹果MVC "方法,在Android上遵循MVP。虽然痛点随着工程师数量的增加而不断增加,但在做出更大的架构改变之前,该应用已经发展到近100名本地工程师使用这种架构,并迁移到RIBs。
当太多的工程师最终修改了相同的文件时,麻烦就开始了。 在早期的Uber应用中,这个文件是旅行中页面的展示/视图逻辑。这是一个多达50名工程师进行修改的屏幕,并意外地破坏了彼此的功能。我们试图把这个页面分解成更小的组件,但组件的交流和导航冲突不断出现。
构建一个支持数百名移动工程师在同一代码库上协作的架构并不是一件小事。Uber的团队花了半年的时间来制作原型并试验不同的方法,从通常的嫌疑人,一直到(B)-VIPER。最后,我们建立了自己的架构,并将其开源,称为RIBs。我们对该架构进行了优化,以适用于大量的工程师和许多嵌套状态。该架构使用不可变的模型,尽可能地在整个应用中重新赋值。架构不仅仅是图表。我们建立了工具来处理增加的复杂性,从代码生成工具到上机教程。
在大型团队中,架构是控制团队和组件之间隔离程度的一种手段,限制了重叠和意外冲突,同时增加了复杂性和代码行。也许MVP、MVVP、(B)VIPER、RIBs或其他更知名的方法对你的团队来说足够好。如果不是这样,就开始正式确定哪种解决方案会有效,为什么,以及会有什么权衡。
你可以通过各种方式正式确定你的方法。
- 口头协议: 最快捷的方式。这也是留下最多解释空间的一种方式,新加入的人可能不知道过去的讨论情况。
- 记录方法: 一种常见的方法,对较小的团队很有效。遵循建议是每个工程师的责任,而代码审查员则要注意工程师何时偏离了这个协议。
- 帮助正规化的工具: 你可以建立框架,帮助实现一致性。你可以使用模板或代码生成工具,这样你的组件在点击一个按钮时就能 "正确连接 "了。你也可以把lint规则放在适当的地方,以自动捕捉 "架构违规"。团队越大,除了记录你的方法之外,还可以投入更多的资金。在Uber,我们建立了围绕组件生成的工具,并让linter "强制执行 "某些架构规则,例如Presenters不允许知道或调用Routers。
为了支持多达数百名移动工程师,你很可能需要遵循的原则包括。
对于一个移动架构来说,要支持大规模的工作--有几十名工程师--在合并到主分支之前,错误需要被清除。自动测试应该作为合并前步骤的一部分来捕捉功能问题。你需要投资于一个支持这种可测试性的架构,并保持高水平的测试覆盖。工程师应该对合并变化充满信心,知道他们没有破坏应用程序的其他部分。
21. 在多个应用程序中共享架构。
如果你的公司建立了几个应用程序,它们都将以不同的架构开始。不同的团队
不同的团队将构建每个应用程序,在早期快速发展。然而,随着时间的推移,拥有一个更 "统一 "的架构的想法将会出现。越早有移动平台团队拥有共享的组件,如实验、功能标志、性能和其他,这个想法就可能越早浮现。
虽然统一的架构在这一点上无疑会有明显的好处,但它将意味着大量的工作,如可能重写应用程序的一个很好的部分。这是一个典型的悖论:为了证明共享架构的好处,我们需要在一个共享架构上。
一个明智的中间路线是开始向统一的架构迈进,但不要重写。以下是iOS和Android应用之间统一架构的好处。
- 共享语言。 作为第一步,我们能否开始 "统一 "iOS和Android谈论架构的方式?我们能否就如何命名屏幕、导航、模态、流程等概念达成一致?
- 共享规划。 我们能不能开始用设计文档做正式但轻量级的规划?我们可以在同一个文档中为iOS和Android规划同一个功能吗?
- 打破孤岛。 组织中的移动团队是否在互相交流,即使是在不同的应用程序上工作?如果没有,他们如何才能开始对话?例如,我们是否可以开始跨团队的计划审查或其他协作?
- 一次一个共享组件。 在可以跨应用程序共享的功能或库方面,什么是一个好的候选者?如果这是在内部建立的,是否可以开始在iOS和Android之间使用更 "统一 "的架构方法?
- 在应用程序的新部分引入新的架构概念。 谁说你需要为一个新的架构重写应用程序?你能不能开始用新的方法构建新的屏幕?这类似于采取务实的方法来移动语言。例如,当在Objective C代码库中引入Swift,而不重写现有代码。
迁移到一个新的移动架构是很昂贵的。 在权衡了成本和收益之后,大多数团队会决定不全身心投入到一个新的架构中去,他们这样做通常是正确的。我唯一建议重写的时候是当应用程序要做重大改变,需要触及许多代码库的时候。即便如此,重写通常也会花费更长的时间,而且会比你最初的预算更痛苦。
Uber重写Swift的幕后故事以及沿途的痛点,已经引起了
网上有相当多的讨论。这是我在Uber的第一个项目,也是我参与的最大的一次重写。重写是有意义的,因为用户体验的变化是跨领域的,几乎影响到所有的工作流程和应用程序的部分。尽管如此,如果不是因为重大的设计和用户体验变化,我不相信Uber会进行重写和架构变化。
虽然Uber在2016年重写了使用RIB的Rider应用,后来又在2018年做了与Driver应用的全面重写,但Eats应用仍然停留在 "现有 "架构上。在我任职期间,没有足够强大的商业案例来证明停止工作并进行不影响用户体验的暗改,我也同意这个评估。遵循一种务实的方法,许多新的组件都是用RIBs构建的。还建立了一个RIBs适配器,因此使用RIBs的组件可以在多个Uber应用中共享,无论它们在什么架构上。
22. 大型工程团队的工具成熟度。
应用程序由数百万行代码编译而成的公司通常也会成立一个移动平台团队。在这种规模下,公司会有几十个原生工程师在做应用程序。他们会遇到这样的问题:原生开发工具在这种规模下开始出现性能或流程问题,而没有好的现成的解决方案。Uber就是这种情况,我听说像Facebook、Spotify和其他许多公司都面临同样的问题。
这种规模的构建时间是最大的问题之一。 我说的 "规模 "是指构建一个有几百万行的项目,每个工程师要做十几次,乘以一百或更多的工程师。再加上运行一个完整的自动化测试套件,就不难证明雇用几个人建立一个比大多数服务所能提供的更好的东西是合理的。
你应该使用Bazel、Buck、Gradle,还是xcodebuild?你在构建时可以做哪些优化?这个问题会让工程师们忙得不可开交,尤其是在构建工具领域是一个不断发展的领域。
当你有50个移动工程师在代码库工作时,将构建时间缩短30秒可能意味着每年 "获得 "几个 "工程师月"。计算一下:假设工程师每天构建应用程序五次,乘以工程师的数量,这意味着整个团队每天有两个小时的 "闲置时间",或者每年三个月。一个工程师花几周时间来获得这种减少的投资是完全有意义的,让工程师定期重新审视构建性能也是如此。
运送几个以上的应用程序的工作流程也是一种挑战。 每个应用程序都需要有检查点,从构建被切割开始,经过测试阶段,如本地化测试、手动和烟雾测试、性能测试、测试版用户和其他。为一个应用程序协调这一过程并不困难。然而,在iOS和安卓系统中跟踪几十个构建列车是内部工具可以做得更好的事情,而不是你可以随时购买的东西。你会发现自己需要为自己的需求制作一个构建或发布列车。
在iOS和Android上,工具的成熟度不断提高,我个人期望在未来几年有更多现成的解决方案。不过,将移动工具的生态系统与后台的生态系统相比较,大型移动应用的工具似乎没有大型后台系统的工具解决得好。
23. 扩展构建和合并时间。
原生移动应用的构建时间很快就会成为大多数项目的问题所在。iOS工程师很不幸地熟悉Xcode构建项目的速度似乎很慢,而Android工程师如果有一个超过 "Hello, World "的项目,也会开始计算构建时间的秒数,然后是分钟。
苹果和谷歌都没有优先考虑改善大型项目的构建时间。对于拥有几十万或几百万行代码和几十个依赖关系的项目来说,情况更是如此。
幸运的是,有一些工具可以使构建时间更快,但它们需要时间来整合、调整,并适应 "一键构建 "的工作流程。Bazel是在大规模构建移动的公司中变得最流行的工具。许多公司都在从Buck或Gradle转向Bazel的过程中。Grab、Uber、Pinterest和Android AOSP平台就是公司和项目迁移的例子。即使有了Bazel,还有很多工作要做,以加快构建速度。公司里的移动工程师越多,让他们兼职或全职从事改善应用构建体验的工作就越有意义。
随着移动开发团队的壮大,在每个平台上,专注于构建的改进是必须的。有几个低垂的果实,像这样的团队可以解决,还有其他更复杂的。一个低垂的果实的例子是,在iOS上,动态框架是如何对构建时间、应用程序大小和冷启动时间来说都是昂贵的。当更短的构建时间和更小的应用程序大小是一个优先事项时,值得切换到静态库。一个更昂贵的实现变革的方式是转移到一个单库。
是继续使用分布式源代码还是转移到单版本,是一个规模在20到40个工程师之间的团队开始问的问题。大多数团队开始从不同的存储库拉入依赖项和库,在编译前就这样做了。通过网络下载依赖项是很耗时的,所以缓存被用来优化这种方法。
随着代码库和工程师数量的增加,获取依赖关系的时间也不断增加。突然间,让所有的依赖关系都住在同一个monorepo中的想法似乎不那么疯狂了。截至2021年,仍然没有伟大的移动单版本工具,所以你将不得不自己建立许多这样的工具。
在Uber,当我们每个平台上的原生工程师达到100人左右时,我们就转移到了Android的monorepo和iOS的monorepo。你也应该这样做吗?不幸的是,没有明确的答案,只有权衡利弊来考虑。什么对你的团队更重要?是缩短构建时间、标准化版本,还是保持对定制工具或移动平台团队的低投资?
保持主绿色--在规模上。要缩短合并变化的时间,并保持主分支始终是绿色的,这有多难?如果你的构建执行速度很快--比如15分钟就能完成所有测试--而且每天的合并次数很少--比如10或20次--这就不是什么挑战。
如果你的构建需要30分钟才能完成单元、集成和UI测试呢?那么
如果你每小时有10个拉动请求进来呢?有什么办法既能保持主分支的绿色,又能保持较短的合并时间,尽可能接近30分钟?
为了实现这一点,你需要对两个构建进行并行处理。但是,当一个PR可能影响另一个PR时,平行运行两个PR是否安全?这个问题导致了一个复杂但同样令人兴奋的问题。在Uber,我们最终建立了一个提交队列,将构建工作分成平行部分。然后,它对构建队列进行概率建模,确定可能通过的变化,并对这些变化进行优先排序。如果这听起来像是你想了解的东西,你可以在这份白皮书中阅读这种方法的细节。
虽然可能很少有公司像Uber那样每天发生大量的移动公关,但如果你是其中之一,你将不得不投资于降低合并变化的平均时间,并保持工程反馈循环的低水平。
进一步阅读。
- Uber公司的在规模上保持绿色主控。
- 来自Pinterest的开发快速可靠的iOS构建
- 来自Grab的通过超级应用Bazel迁移的开拓
- 现代化的Android构建系统 来自Dropbox
- Swift中的静态与动态框架 来自Revolut工程师 Andres Cecilia Luque
24. 移动平台库和团队。
随着在一个应用程序上工作的移动工程师或公司的数量增加,出现了 "重新发明轮子 "的趋势。
往往会出现 "重新发明轮子 "的情况。团队A需要一个功能,如日志、分析、数据存储等,他们会做出自己的选择并选择自己的实现。然后TeamB也面临同样的挑战。假设他们与TeamA交谈,他们可能会决定重用TeamA所做的事情是有意义的,不仅仅是为他们,也为其他团队。
构建一个可重用的组件,还是另一个自定义的实现?一个常见的问题,随着应用程序的增长。
内部移动库通常是在应用程序的开发过程中较早而不是较晚创建的。在许多情况下,内部库可能只是一个围绕供应商解决方案的轻量级包装,编写的目的是为了在需要时轻松迁移到其他解决方案。
内部库中的内容没有限制,但常见的内部库可以包括。
- 日志
- 分析
- 数据持久性
- 功能标志、A/B测试和实验
- 网络和认证
- 测试。UI测试,单元测试,模拟生成
- 品牌UI元素、颜色、主题
- UI元素、框架和布局。
- 信息显示
- 动画
- 图片管理
- 导航框架
- 架构框架
- 性能监测/剖析工具
- 推送通知
- 特定于应用程序领域的共享功能:呼叫、PDF、扫描、位置、地图和其他。
随着团队--以及内部构建的库的数量--的增加,维护这些库通常变得很困难。 作为工程师,我们通常认为主要的挑战是建立库本身并将现有的用例迁移到它上面。然而,大多数团队发现维护工作是多么的痛苦,但只是在库编写完成后的几年。
维护的主要问题通常有以下几点。
- 原先的工程师已经不在团队中了。 这可能在几个方面成为问题。关于如何修改代码的知识可能会缺失。不过,其他工程师通常可以理解那些写给别人使用的代码,所以这很少是问题所在。更大的问题是,当原来的工程师离开后,修改往往未经检查就进来了。这就导致了下一个问题。
- 当一个团队遇到一个可以通过改变共享库来解决的问题时,他们往往会去做一个短期修复。 只要有一个库的所有者,这个所有者就可以决定不允许低质量或短期修复。
- 2.拥有者的团队没有维护或迁移的带宽。 另一个常见的问题是一个产品团队建立了几个这样的组件。然而,他们的盘子里装满了产品工作,工程师几乎没有时间做小的维护工作。如果需要做重大的改变,也没有人去承担这个任务。
当的移动工程师数量足够多时,创建移动平台团队是解决所有权和维护问题的常见方法。关于这个问题的规模没有 "黄金法则",但大多数公司在拥有--或预计拥有--20至30名移动工程师时就会采取这个步骤。
移动平台团队的所有权可以有很大的不同,基于什么被认为是公司里的 "共同"。常见的由专门的移动平台拥有的领域有以下几个。请注意,平台团队通常拥有其中的几个领域。
- 移动构建基础设施,特别是当决定保持内部构建的时候。即使使用第三方供应商,移动基础设施团队也可能拥有供应商的关系,以及构建的设置。
- 应用程序商店的发布管理。在拥有成熟的发布流程的公司,这个领域通常包括拥有构建后的手动测试流程,狗粮/beta流程,以及最后一分钟的热修复流程。
- 开发人员的工具和经验。 在规模上,如果有15个或更多的工程师从事几十万行的应用程序,"默认 "工具的限制开始变得更加痛苦。无论是在本地还是在CI上,构建应用程序或运行测试都会变得更慢。加快这些步骤不再只是一个 "快速变化",而是可能需要更复杂的工具变化、代码结构变化,或者两者都需要。
- 架构和架构维护。 第一个非infra平台的团队倾向于掌握应用的架构,确保它是以可维护的方式构建。这个团队往往既是帮助经验不足的工程师做出可持续设计决策的指导者,也是确保架构保持清洁并符合更广泛愿景的 "监督力量"。依赖性管理、代码质量管理、可测试性--以及测试--往往属于这个范畴。
- 公司内部或外部使用的SDKs。SDK通常是针对业务和团队需求的。
- 移动应用程序的可靠性和性能,从崩溃率、网络可靠性、日志和性能监测。
- 建立能力,使开发人员更有效率。随着移动框架--甚至是语言--的快速发展,生态系统的大部分都存在差距。团队越大,这些差距就越明显。一些移动平台团队决定值得建立一个解决方案,因为他们可以买到的工具还不够好。这方面的例子包括建立一个定制的UI测试框架,建立一个设备实验室,或者实施一个与整个公司的定制工具相整合的构建训练。
- 共享内部库的所有权。一旦移动平台团队到位,他们往往会接管--或建立--一些内部移动库。
这里有一些关于运行一个健康的移动平台团队的指导方针。
- 明确的任务。 确保平台团队有一个明确的任务,比 "拥有所有共享的东西 "更具体。任务的例子可以是 "使移动工程师能够更有效地工作,月复一月 "或 "在我们的行业中发送最可靠的应用程序"。
- 明确的目标。 平台团队应该对他们想要包括的领域有可衡量的目标。可能的目标包括范围内的可靠性目标、使用共享组件的团队百分比、整合某些功能的代码行、开源项目的数量,以及其他。一个没有目标的平台团队将很难决定将重点放在哪里,并将变得比一个知道要去哪里,以及如何到达那里的团队效率低下。
- 足够的人员配置。** 团队应该足够大,以便他们有足够的带宽在平台上做 "产品 "工作,同时为组织的其他部门提供支持。
- 平台和非平台团队之间有明确的合同。平台团队应该清楚他们做什么,以及他们不拥有什么,这应该是一个共同的--并达成共识的--理解。
- 明确的支持渠道。 工程师应该知道他们在哪里以及如何从平台团队获得支持。这可以是共享的聊天组、办公时间、专门的人进行联络,最可能的是,所有这些的组合。
- 明确的参与过程。 平台团队应该明确产品团队如何与他们合作提出功能请求;如何提出请求,由谁和如何优先处理这项工作,以及如何跟踪状态。
作为启发,这里有一些公司如何与移动平台团队接触的例子。注意
其中一些例子是传闻,而其他公司可能已经改变了他们的运作方式。不要忘了,每个公司都在解决自己的问题,考虑到它的人员和其他限制。不要盲目地复制其他公司正在做的事情,要遵循会导致你所需要的正确杠杆水平的设置。
- Uber有一个平台团队,拥有移动开发者的经验,包括开发工具和构建系统。另一个叫做移动平台的团队拥有架构和共享服务(RIBs和内部添加物,如实验框架)。移动平台后来分裂为应用平台(拥有应用指标/可靠性/性能、架构和核心模块治理)和移动基础(拥有可重复使用的组件和框架)。UberEats是Uber内部的一个 "初创公司",在早期几乎完全独立于Uber的其他部门运作。UberEats开始于2015年,而第一个 "官方 "移动平台团队是在四年后的2019年创建的。甚至在这个第一个平台团队之前,UberEats团队都 "投桃报李",建立其他团队会以可重复使用的方式使用的组件。
- UberEats是Uber内部的一家 "创业公司",早年几乎完全独立于Uber的其他部门运作。UberEats开始于2015年,第一个 "官方 "移动平台团队在四年后的2019年成立。甚至在这个第一个平台团队之前,UberEats团队都 "投桃报李",建立其他团队会以可重复使用的方式使用的组件。
- Twitter曾经有一个iOS和Android基础团队,各有几个工作流。随着规模的扩大,这些团队在每个基础中又分成了更小的团队,如UI、性能、架构、构建和开发者体验。
- 亚马逊有一个平台团队,拥有应用架构、日志、指标和共享的 "类似基础设施 "的功能。主要的功能通常被剥离出来,由体验团队拥有。这些体验团队与平台签订了合同,以明确代码所有权以及如何进行设计和代码审查。
- Just Eat有一个iOS和一个Android平台团队。这些团队拥有所有 "典型 "的平台工作,以及iOS或Android的发布过程。
- Skyscanner有一个移动Infra团队(拥有CI/CD,构建和发布管理)和一个移动核心团队(拥有可重复使用的库并帮助解决影响多个团队的问题)。
- VMware有一个建立移动UI组件的小型团队,另一个团队拥有内部和第三方使用的SDK。
- Zenly(一家Snap公司)有一个移动平台团队,由移动和后端工程师组成。他们发现,许多移动平台工作的性质从应用层面跨越到后端。这方面的例子包括改变网络层的传输机制而不是TCP,跨应用程序和后台的指标,自定义崩溃报告,远程调试,以及其他高级功能。
- 沃尔玛有一个iOS和一个安卓移动平台团队,他们拥有所有特定平台的工作。这意味着从移动CI/CD管道,通过测试、调试和性能工具、崩溃报告、安全实践和依赖性管理,一直到UI导航元素或分析。平台团队保持着一个他们拥有的长长的能力清单。
- 沃尔玛有一个iOS和一个安卓移动平台团队,拥有所有平台特定的工作。这意味着从移动CI/CD管道,通过测试、调试和性能工具、崩溃报告、安全实践和依赖性管理,一直到UI导航元素或分析。平台团队保持着一个长长的他们拥有的能力清单。
- N26有一个 "核心 "iOS和一个 "核心 "Android,这些团队拥有所有共享能力。他们后来探讨了将这个团队拆分成更小的跨职能团队,首先是设计系统团队。
- Sixt有一个平台团队,负责iOS、Android和Web。这个团队负责所有常见的任务,如单次重复、CI/CD、可观察性、架构、库等。他们选择将移动和网络结合起来,因为有很多类似的部分,如CI/CD或库。这有助于知识共享和减少重复工作。
- Booking.com有几个团队一起工作,他们称之为 "应用核心平台"。一个团队拥有核心组件和服务,另一个团队拥有构建和发布流程,包括测试和应用程序的稳定性。第三个团队纯粹关注应用程序的性能,如启动时间和互动时间,为重要的屏幕,而第四个团队则关注以产品为重点的团队所使用的内部开发框架。所有的团队都有一个混合的
的iOS和Android工程师。最后,这个组织还有一个后端开发团队,他们从整体治理的角度来照顾应用程序的后端,确保Booking.com应用程序调用的所有后端是健康和可靠的。
什么时候分拆出第一个移动平台团队总是一个挑战。 大型移动团队显然需要一个或多个这样的团队。但对于那些规模尚小的团队呢?当你有15个工程师的时候,你会想把一个平台团队分拆出去吗?
太晚开始一个平台团队可能意味着代码中存在大量冗余,抽象性差,相同功能之间的可重用性差。如果一个平台团队早点成立,这个团队就会自然而然地成为几个共享功能的拥有者,并且也会拥有整个应用的架构。
过早地开始一个平台团队有一个缺点,那就是很难为它提出一个商业案例。为什么要雇佣一个不会运送产品的工程师呢?此外,第一个平台团队通常会吸引最有经验的工程师。这些工程师往往也是生产力最高的产品工程师。即使公司雇佣了新的工程师,这些原来的工程师往往会在产品团队中留下几个月的空白。
我在《作为移动工程师的成长》一书中写了更多关于作为工程经理开始和运行移动平台团队的建议。
章节摘要
由Bitrise的Moataz Nabil撰写,作为本书的补充。
从早期的规划阶段一直到部署,扩大团队规模总是会带来很多挑战。用一个小团队来构建一个应用程序与用20多个移动工程师来做是非常不同的 - 大型团队总是意味着更多的代码和更慢的构建时间。随着我们的成长,我们总是需要找到支持我们解决这些挑战的架构、工具和平台,并更快地构建一个可扩展的应用程序。
之所以说挑战是从规划和决策阶段开始的,是因为作为一个大规模的团队,我们需要确保通过RFC规划使整个团队的规划过程正规化。iOS和Android团队可以在这方面合作,这将帮助我们避免未来与功能和架构有关的问题,通过标准化的东西,如功能标志,或分析事件命名的团队之间。作为一个大的团队,我们还可以就规划过程的时间框架达成一致,并将更多的时间花在短期迭代的构建上,并获得关于计划是否可行的反馈。
在这些事情上,RFC始终是一个值得推荐的解决方案:通过为特定的堆栈定义一个设计文档模板,例如移动、后端或Web,我们可以让大多数工程师同意这个想法,并开始编写简短的文档并发送给每个人,同时也明确了需要谁的批准。
当一个团队还很小的时候,移动架构并不那么重要--只要你选择一个足够可测试的结构。然而,在一个大规模的团队中,我们需要建立一个支持数百名移动工程师的架构,而不造成任何冲突。通过将应用程序分解成更小的可测试和隔离的组件,我们可以建立一个跨平台的架构框架,以尽量减少全局状态和围绕业务逻辑的决策。
请记住,要遵循其中的一些原则,你很可能需要支持多达数百名的移动工程师,并管理功能隔离、功能所有权和测试自动化。如果我们正在构建几个应用程序,并且需要在它们之间共享组件,那么统一的架构就很重要。
在大规模的情况下,建立一个有几百万行代码的项目,每个工程师做十几次,乘以一百多个工程师,随着时间的推移,将推动性能和流程问题。为了解决这个问题,我们应该通过运行不同的测试,包括单元测试、集成测试、E2E测试,来协调一个流程,优化构建时间,用并行化的工作流程来扩展构建,并在任何时候都保持主分支的绿色。
在大型团队中,一个有用的东西是建立内部可重用的组件,他们可以在他们的功能中实现这些组件,而不需要从头开始创建或使用其他组件。我们需要记住,随着时间的推移,维护这些库会因为不同的原因而变得困难。例如,最初实施一个流程的工程师已经不在团队中了,在一系列短期修复之后,库的质量下降了,或者所有者团队没有带宽来维护或迁移。建立一个移动平台团队来负责应用程序的基础设施、发布管理、开发人员工具、架构、SDK和内部库的所有权,可以帮助解决所有这些问题。