这篇文章是第二个系列涵盖优步的移动工程团队如何开发出最新版本的我们的驱动程序应用程序,代号为碳,碳,是我们执教业务的核心组成部分。在其他新功能之外,该应用程序让我们的人口超过300万司机合作伙伴查找票价,获得指示并跟踪其收入。我们开始与2017年司机合作伙伴的反馈一起设计新应用程序,并于2018年9月开始向生产滚动。
从头开始构建一个应用程序会引发许多关于架构和设计的问题。到目前为止,对于工程师来说,最简单的陷阱就是在一个气泡中开发,按照应用应该如何工作的固定想法工作。幸运的是,以客户为中心的设计已经成为软件开发中的一个重要主题,但是识别您的客户并不总是一个简单的问题。
一旦我们决定重写优步的驱动程序应用程序,我们向我们广泛而多样的用户群寻求如何设计工作流程以及哪些新功能最有用的见解。来自世界各地城市司机合作伙伴的反馈是我们最初用户体验设计的重要动力。
与此同时,我们有另一个人口考虑:数百名工程师,现在和将来,谁将建立应用程序并迭代特色。一个深思熟虑的应用程序架构将帮助这些工程师更有效地工作,在保持可靠性的同时快速提供功能。
幸运的是,为这两个团体提供服务,包括为我们的工程师实施智能工作流程和改进的驱动程序和灵活,可靠的架构,并没有创造冲突。事实上,两组鸽子的需求很好。
在本文中,我们概述了我们如何提出我们的新驱动程序应用程序(代码碳)的核心要求,并讨论我们如何利用组合肋骨结构并插入设计模式以构建我们的应用程序逻辑。
在规模开发
优步司机应用于2013年首次发布,在接下来的四年里,它将积累许多功能,这些功能对我们的司机合作伙伴至关重要。随着应用程序变得越来越复杂,优步作为一个组织也变得越来越复杂。该应用的数百个功能是由公司内40多个不同的子团队创建和维护的。截至2017年1月,我们的Android驱动程序代码库有428,685行代码,由近200名工程师贡献。这款iOS应用共有720273行代码,由200多名工程师贡献。更重要的是,我们的应用被安装在超过300万台设备上,每天被100多个国家的100万名司机使用。
对于成功的碳,我们知道我们必须及时地将所有这些现有功能(以及一些新的功能及时地提供所有这些现有功能,并并行化尽可能多。
一起建造
将最终用户放在心上时,产品开发的效果最好。为此,我们想和优步司机合作社区一起开发这个应用程序。在开发初期,我们在用户研究上投入了大量资金,采访了11个国家12个城市的500名司机。雷竞技是骗人的
这些采访帮助我们设计了新应用的用户体验,并确定了其最重要的功能。然而,除非驾驶员能够在道路上使用该应用程序并在现实环境中进行测试,否则无法获得完整的体验。我们需要以一种能够让我们收集反馈,快速迭代并每周发布新版本的方式去创造Carbon。
实现可靠性
最困难也是最重要的挑战是真实测试中的可靠性。当你引入一个新的应用程序时,在alpha和beta阶段有一个对错误或问题的容错。在我们的案例中,测试阶段涉及到真正的司机在路上试图赚钱。实现可靠性是Carbon公司的一个关键目标。所以,当我们进入推出阶段时,我们必须确保即使在测试阶段,Carbon至少也能像现有的应用程序一样可靠。
在规模上解锁开发
制定了我们项目的限制,我们通过将项目划分为四个阶段来采用分阶段的方法。每个阶段的目标是解锁下一阶段的发展。
第0阶段:基础设施
在内部,我们有一个通用的模板来描述我们所有的应用程序必须包含的内容。该模板由用于网络、存储、反弹,分析跟踪,崩溃报告和我们本土应用架构框架,肋骨。利用此模板,我们构建了一个初始骨架应用程序,具有存储,网络,崩溃报告和基础架构组件的容量。但是,在此阶段,骨架应用程序缺乏驱动程序的功能或任何功能,仅作为我们将建立我们的功能的脚手架。
阶段1:应用根
使用肋骨架构的主要优点之一是它如何强调业务逻辑作为应用程序架构的核心。在碳的情况下,良好的起点是为驾驶员定义高级用户状态。这使我们定义了这些基肋:
- 根:当引导我们的应用程序时,根目录包含了启动一个基于ribs的应用程序所需的所有样板文件
- 注销:如果用户没有有效的会话,我们需要一个res,为它们创建一个帐户,登录并获取有效凭据。
- 登录:一旦用户通过身份验证,登出肋骨被分离,登出肋骨被附加一个有效的会话。
- 积极的:有时驾驶员可以登录,但没有活动(他们的帐户可能已被锁定出各种原因)。该肋骨确保它们具有有效的会话和允许使用该应用程序。
在内部,我们利用肋骨树图,如下面的图2所示,代表应用程序架构。这种简单的树状图显示了肋骨组件如何彼此相关。
通过关注用户状态,我们可以将自己从UI中分离出来。这种方法使我们能够更容易地将来自驱动程序合作伙伴的持续反馈合并到应用程序设计中,同时使我们能够维护应用程序的基本根。
阶段2:特性框架
有了一些基本的脚手架,我们的重点转向了合作。在第二阶段,我们的目标是扩大开发规模,允许大约40个团队在同一个应用程序上可靠无缝地并行工作。基于我们的用户反馈,并与设计和产品团队协作,我们能够定义更详细的肋骨和组件:
- 有任务:司机在线和工作时如何体验应用程序(即,导航到骑手,开始旅行,脱离车手,拿起订单等)。
- 议程(旅行计划者):驱动程序管理所有即将到来的任务的关键位置。在这里,他们可以看到他们需要做的一切,从拿起骑手放弃食物。当它是空的,这就是我们在驾驶地点和何时提供建议的地方。
- 我的枢纽:这是司机可以管理他们业务的领域。它包含了实际驾驶之外的所有内容:重要通知、评级、收益等等。
- 地图在我们的驱动程序中,许多与地图相关的功能,如导航,波动指标和其他都是使用我们新的面向rib的地图库构建的,这是一个建立在我们的地图框架之上的抽象层。一个有趣的注意,如下图所示,这张地图图书馆被视为非核心功能的应用程序,这意味着即使我们遇到灾难性的失败与我们的地图功能(我们希望永远不会发生!),我们可以禁用它,让司机通过工作流程进展。
在合并了这些特性框架之后,我们的小肋骨树变大了,如下面的图3所示。
在我们潜入细节之前,让我们澄清我们在肋骨架构中使用的一些概念:
工人
这是一个对象,它具有直接与肋骨生命周期相关联的启动/停止生命周期方法。换句话说,当附着肋骨时,将添加到肋骨的工人开始,并且在肋骨分离时停止。工人确保我们的互动者(肋骨的业务逻辑组件)不会变得太大,并允许更好地分离担忧。(可用我们的安卓和iOS存储库。)
插件
插件是一种设计模式,允许我们以可扩展的方式为我们的代码标记标记。(了解更多关于优步利用插件的信息前一篇文章)。我们首先在集成的核心代码中为我们的插件定义一个公共API,然后开发人员可以实现他们自己的这个API实例,知道这个代码被一个符合这个接口的特性标志隐式保护着。将每个插件点看作是微服务体系结构中的一个服务,而插件工厂则是该服务的消费者,这将使插件类似于API或它们之间的契约。
通过结合肋骨、插件和工作者,我们现在可以定义我们认为的体系结构中的核心和非核心组件。核心组件被认为是必不可少的,不能被特性标志禁用。另一方面,非核心组件可以被禁用,如果它们给应用带来了重大问题或回归。在上面的图4中,Map和MyHub是非核心组件的例子,它们可以在不关闭应用的基本功能的情况下被禁用。
如果我们放大我们的肋骨树的一个部分,如下面的图5所示,我们可以看到我们如何使用带插件和工作者的Core肋骨来支持使用工作者/插件模式的议程的总体功能。议程功能暴露了两个不同的插件点,议程工作者和议程部分。我们使用Worker插件点来促进非UX与Agenda肋骨的集成,使用Section插件点来扩展Agenda的UX。
使用此设计模式,我们可以为应用程序的大多数区域解锁开发。例如,虽然某些工程师构建登录和注册屏幕,但其他工程师可以专注于将地图框架暴露于有源非核心肋骨。
第3阶段:所有船上
在第三阶段,我们通过引入我们的功能团队,打开了碳开发的闸门。因为我们创建插件框架是为了确保每个功能都是相互独立的,所以功能整合是一个相对平稳的过程。如果有必要,一些肋骨被提升到核心状态,但是我们的大部分代码仍然封装在插件中,因此在我们的体系结构中是可选的。(我们计划在以后的文章中讨论这些令人兴奋的新特性)。
封闭的思想
软件工程中的架构最常见于优先考虑对您组织最重要的价值观并对他人进行妥协。虽然我们的方法使我们能够优化可靠性,可扩展性,和模块化,还有其他我们必须妥协的领域。在我们严谨的过程中,我们只允许应用中很少的组件成为核心。为了维护核心组件的质量,我们有一组内部评审人员,他们评审希望更改核心代码的每个代码提交。这个过程需要一些工程师将他们的时间投入到这些核心评审中,而这也会减慢其他工程师的提交过程。
大多数应用程序开发人员都熟悉模型视图演示器或模型视图控制器的概念。与它们相比,肋骨似乎更冗长。它有更多的组件,需要更多的前期规划。较小的工程组织可能不需要采用类似的过程。之前经历过重写我们的骑手应用程序,我们对我们想要建立碳的方式更清晰,我们可以总结我们的学习如下:
- 在规模:在乳房,规模既是最重要的约束条件,也是最有价值的资源。三百万司机使用我们的应用程序,我们不能让他们失败。与此同时,作为一个工程组织,我们已经发展到有数百名工程师可以一起构建应用程序的地步。规模是我们所有决策的关键,从计划一直到卷展览。
- 肋骨到救援通过利用肋骨和Carbon的插件基础设施,我们在关键方面获得了架构的好处:
- 模块化:除非是核心肋骨,否则以一种不依赖于另一个特征的方式开发。这种架构使工程团队更容易并行开发功能肋,而不担心人们如何影响另一个。
- 可扩展性:树状架构可以通过添加子架构垂直扩展,也可以通过添加兄弟架构或在不同工作人员中隔离业务逻辑水平扩展。
- 可靠性:使用插件框架实现的核心与非核心概念允许我们禁用代码的非核心部分,所以我们可以快速移动,但尽量减少破坏。
- 一起建造如果没有我们的驱动合作伙伴的帮助,以及他们在用户研究和beta测试阶段提供给我们的关键见解,我们不可能做到这一点。雷竞技是骗人的
优步司机应用系列文章索引
- 为什么我们决定重写优步的驱动程序应用程序
- 建筑物的Uber的新驱动程序应用在肋骨中
- Uber的新驱动程序应用程序如何克服网络滞后
- Uber Eats的现金支付比例
- 如何运送应用程序重写,而不会冒险整个业务
- 为驱动程序构建可扩展和可靠的地图界面
- Engineering Uber灯塔:匹配骑手和驱动程序24位RGB颜色
- 为驱动程序首选项构建一个安全的、可伸缩的、服务器驱动的平台
- 将实时收益跟踪器建立在Uber的新驱动程序应用程序中
- 活动/服务作为依赖项:在优步新驱动程序应用程序中重新思考Android体系结构
有兴趣每天开发数百万人使用的移动应用程序吗?考虑加入我们的团队作为一个安卓或者iOS开发人员!






