从无到有,开发一个 App(一)---在开发之前我们要想些什么

0x00 Before takeoff

在这个 App 泛滥的时代,从无到有开发一个 App 看似是一个很简单的事情,网上也有大把的教程来告诉你如何开发各种 App 和网站等等。但是在实际工作中,当我们提到“做一个 App”的时候,含义却十分深奥,那么这个坑到底有多深呢?我希望能够通过几篇文章的篇幅来做一个简要的叙述。

要说明的是,这个系列的文章并不会和网上大量的 App 开发指南类文章一样只是简单着眼于技术细节。而是通过对几年工作经验的总结来讲述当你在一个企业中从事客户端或者前端开发工作,面临一个全新的 App 开发任务时需要如何从头开始考虑整个任务以及流程。

只是一点微小的见解,希望能够给观众一点帮助。如有考虑不周,欢迎指教;如有失误,请多包涵(作揖)。

0x01 项目有啥背景?

有一天老板突然跟你讲,来吧,我们要做一个新的 App。作为一个有经验的开发者你一定知道,OK,你将会面临一箩筐需要考虑的问题。但是我们很容易直接陷入技术细节的思考,却忽视了一个重要的问题:这个项目的背景是什么?

项目的背景,听起来是一个非常泛泛的说法,没错,下面我们来明确一下到底需要留意哪些方面。

这是一个什么行业的项目?

不同行业不同功能的 App,同时也是面向不同用户群体的 App,这些不同点会影响 潜在的需求 以及日后的 技术选型

潜在的用户量

用户的规模大小也会对开发产生影响,一般来讲金融行业的 App,有效用户数量相对而言都比较少,以我之前在某基金公司实习时开发的某基金 App 来看,用户量基本处于 40-50w 的水平。但是对于现象级的互联网娱乐产品来讲,亿级用户是十分普遍的。用户规模的大小会对 App 设计的理念,需求的优先级带来影响,从而影响开发成本和开发的节奏。用户群体庞大的 App 可能需要将所有功能都做得很完善之后才敢对外发布,反之的话,就可以现将主要功能做到可用,其他次要问题可以迭代优化解决。

可用性

对于可用性,一般来讲都是要求比较高的,毕竟可用性越高用户流失的几率越小。这里讨论的是对于可用性保障的程度。如果我们做的是一个八卦新闻 App,那么对于它的可用性要求相对支付宝这样的 App 来讲就会低一些。可用性要求的高低会影响到软件设计者在开发初期采用什么样的策略来保障可用性。

可用性保障的方式有很多,包括异常上报,闪退检测(安卓甚至可以闪退后主动拉活 App),崩溃恢复,异常恢复,热更新修复,功能降级,可用性测试,更深层次的还有 App 问题自动修复(数据修复,版本回滚)等等。

有关的技术方案可以参见亿级APP支付宝在移动端的高可用技术实践

在这么多手段中,显然实现的难度和维护的成本是有巨大差异的。到底选择哪一种,也需要结合 App 的定位来分析

实时性

以金融行业为例,金融行业涉及到众多金融资产的流转和存储,所以交易功能和资产的浏览几乎是每个金融类 App 的最主要功能。由于这两个操作都和客户的财产安全紧密相关,那么我们的 App 需要非常高的实时性以保证客户可以实时看到名下资产的变动状况,以便准确地处理交易。否则很容易出现投诉等情况。这一点也深刻地影响着 App 的缓存策略设计。

安全性

有些安全性的操作比较繁琐甚至会带来高昂成本,比如安卓加固,项目对安全性的要求也是在项目初期需要探讨的问题。

出现问题的后果严重性

这方面问题的探讨主要是为了发现系统中最不能出问题的地方在哪里,也就是一旦出现问题后果最严重的部分是什么。对于这些功能点可以设计兜底方案,也就是功能的降级处理,确保即便出现问题也能够挺过去。

项目中各方的利益是怎样的?

这个问题在小公司一般不存在,在大企业中由于各个部门是不同的利益实体,在同一个项目的合作中不同利益实体所能得到的投入产出比一般是很不相同的。所以不得不说,虽说是同一个公司,在同一个项目中合作的团队主观的动能是有相当差距的。这里说这个问题并不是想批评公司的弊病之类,只是想表达一个观点,尽早明确各方利益关系有助于提前发现项目的风险点。比如,某团队在开发流程的关键路径上,但是这个团队对项目的主管动能明显不足,那么就很有可能在这个位置上出现重大风险,提前预计到这些风险对项目的规划和安排很有帮助。

0x02 有什么隐藏的坑?

小心隐藏的需求

往往会在开发进行到后期才会提出,这时已经为时已晚,措手不及
比如

  1. 是否有特殊的安全需求?比如,接入其它安全插件等等。
  2. 是否需要热更新和修复的能力?
  3. 异常处理的方式是怎样的?比如,网络异常,服务器错误,应用崩溃闪退等等。
  4. 网络状态切换是否需要判断和提示?
  5. 是否支持多国语言?
  6. 是否会规划类似夜间模式,更换皮肤的功能?
  7. 数据实时性要求,涉及到缓存系统的设计。

需求变化的可能性?

需求经常变化一定会导致软件质量不断下降,开发周期被拖长。让需求不断趋于稳定,需要流程的控制和强有力的执行来保证。

由其他团队提供的技术方案是否完善,是否真的可用?

项目中可能要接入某团队提供的 SDK,对于这个问题,我的看法是,首先我们需要知道这些 SDK 的作用是否不可替代?尤其是一些流程简单,但是调试复杂的关键流程,比如登录。再者,提供的技术方案有无文档,有无测试环境,支持人员是否可以及时响应,如果这些基本的保障比较贫乏的话。应该可以确认这里一定是一个坑,要提前规划风险的应对。

各类账号和证书由谁提供?

大多数 App 都会关联 QQ 和微信等三方登录,这些第三方平台需要注册开发者账号,有的甚至需要上传营业执照等等公司信息,需要在早期明确责任人,及时申请和处理这些账号资料问题。

iOS 平台开发和上线需要使用开发者账号和证书,在团队开发的模式下,这些东西需要由团队来统一提供,而非使用某个人的。如果涉及到了公司证书或者企业证书的申请,由于需要申请邓白氏编码和验证公司身份,这两种证书的申请周期相对都比较长,需要尽早明确账号归属者,敦促其尽快申请账号,以免耽误开发流程。

Android 平台虽然没有开发证书的问题,但是安卓的发布依然是一个很复杂的过程,需要确认发布的渠道,以及申请相应发布渠道的账号。

测试包如何分发?

测试包分发最重要的是权限的控制方式,公司内部是否有成熟的可控权限的安装包分发平台?如果需要使用外部平台,权限控制则可能需要后台配合在 App 中以邀请码或者体验账户方式来实现。金融机构的分发还涉及到是否合规,以及安全审计,这些也都是要考虑的范畴。

0x03 团队擅长什么技术?

设计和交互团队是否擅长 App 设计?

UI 设计在很多方面与平面设计或者其他行业的设计工作在流程,出品规格,工作流程上都有不同。

交互和设计上主要考虑几个点

  1. 是否有成熟可用的工作流程
  2. 出品的规格是否能够符合开发要求

这两点在很大程度上会影响到开发的进展,以及开发的工作量。

原生开发者是必不可少的

客户端项目需要原生开发的参与,如果没有原生开发者,那么在技术架构上应该将重心偏向于跨端技术栈,尽量减少原生的工作量。
但对于 App 项目来说,原生开发者依然是必不可少的存在。

前端技术栈

团队更侧重于什么框架的使用? Vue,React 还是 Angular。
成员是否有强类型语言经验?如果有强类型语言经验,Typescript,Dart 等强类型语言会是一个有意义的选择。

前后端交互技术

在网络通信方面熟悉什么样的技术?
RESTful API,Socket,GraphQL,Protocol Buffers 等等

0x04 制定开发规约

代码规范

这部分有很多现成的方案,谷歌,微软,FB,Airbnb 都有贡献过关于代码规范的资料。但这些规范并不是拿来就用,需要针对团队的习惯和项目的要求进行修改。

流程规范

流程规范的问题涉及到开发迭代的流程,需求变更的流程,代码修改的流程,代码提交的流程,打包测试,发布上线的流程。
这些问题都需要提前做一个框架性的约定,而且在开发过程中需要不断地完善改进。

关于代码提交的流程,可以参考Git 使用规范流程

开发规约要容易实施

制定规范是为了保证出品的质量最大限度不受低级错误影响,在这个话题下,我特意强调了容易实施这几个关键字。为什么要做这个强调呢?如果大家有使用或者查看过各种代码规范或者开发规范的话,不难发现,有相当多的条条框框可以运用到开发过程中。但是结合实际的团队状况来看的话,由于大家对规范的看法不同或者出于个人开发习惯的不同,在一些议题上大家是很难达成一致的。举个栗子,编辑器和 IDE 的统一,除了 iOS 开发大家必须要用 Xcode 别无选择之外,几乎任何平台或者语言的开发可用的编辑器和 IDE 都有浩如烟海的可选项。在我们现在的条件下不可能要求大家能够使用统一的 IDE,即便这有很多好处,比如,可以避免不同编辑器之间由于设定不同为编辑过的文件添加奇怪的属性带来的问题,或者对某些配置文件或者 UI 文件的修改时,不同编辑器会添加不同风格的配置导致混乱。如果我们强制推行这样的方案,会造成很大的迁移成本,有人惯用 eclipse 系列的编辑器,快捷键和各种 panel 的位置都已经十分熟悉了,这时候一下子叫他迁移到 Intellij 系列,熟悉起来还是需要一定的时间,这样就会影响到开发的效率。另一个问题是,我们也无法保证新加入的团队成员能够熟悉某周 IDE,每次有人加入团队可能都会产生一次额外的学习成本。类似这种规范,对于任务紧张而且人数不多的团队我认为不是一个很可行的方案。

从上面的例子可以看出,并不是所有的方案都能契合自己团队的实际情况,那么有哪些规范是所谓容易实施的呢?

根据我个人的经验来看的话呢,这样的方案有几个特点:

  • 足够简单,容易记忆
    越简单的方法越容易记忆,形成长期记忆后就会变成习惯,容易保证措施有效地贯彻落实。同时也方便形成经验,在日后的项目上方也可以及时想到,实施。
  • 操作便利,步骤简单
    在操作上要保证步骤尽可能的少,一方面可以保证第一条中说到的优势,另一方面可以保证流程的稳定性,不易出错。
  • 脚本固化,IDE 无关
    在第二步的基础上,借助构建脚本或者运维脚本将流程固化下来,实现自动化。注意:这种自动化流程需要与 IDE 解耦(只依赖命令行工具),不要依赖特定的开发工具(比如 Intellij 系列提供的代码检查功能)以实现普适性,在同一项目中零成本复用。
  • 流程整合,异常报错
    更进一步,我们可以将上述的自动化过程整合进入构建或者提交流程,在构建流程中完成对代码的合规审查,通过对不符合出口标准的代码抛异常报错来防止不合格代码流入代码库或者进入编译打包的过程。

说了这么多,举个实际的例子。最常用到的就是 git 的 hook 功能。最理想的做法是在 gitlab 或者其他 git 仓库的服务端来布置 pre-receive hook 脚本,在脚本中集成代码审查的流程即可,当有不合格代码提交到服务器中的时候,该脚本会把这个无法通过审查的提交直接拒绝掉。这样,我们就实现了一个足够简单无需开发者本地操作,使用脚本将规范的审核自动化,并集成到代码提交流程中将不合格代码屏蔽在仓库之外的代码规约过程。

0x06 一些好用的开发工具推荐

在这里也分享一下我平时经常使用的一些工具,和原因,个人感觉对效率提升还是十分有效的。

  • 开发机:Mac 电脑 + macOS
    原生类 Unix 环境,自带 bash,使用 brew 包管理可以安装绝大多数 Linux 平台上的命令行工具,对开发十分友好。

  • 编辑器: VSCode
    之所以推荐一款编辑器,是因为我认为开发中仅仅有 IDE 是不够的,IDE 提供了很多高级功能不假,但是文本操作和对各种格式文件的兼容未必都做得很好。使用 VSCode 提供的灵活的光标移动能力可以提高文本处理的效率,比如批量处理文本的任务,还有文本编辑器一般不会对文件格式有苛刻的要求,遇到想要查看的文件,直接丢到编辑器就可以打开查看了。

  • 终端:iTerm2 + zsh + oh-my-zsh
    iTerm2 是一个很经典的 macOS 终端代替品,实现了很多方便的操作和功能,这里不细说,有兴趣可以查看你应该知道的 iTerm2 使用方法–MAC终端工具zsh 是一个 bash 代替品,oh-my-zsh 是一套 zsh 配置文件集合,可以帮你省去复杂的 zsh 配置过程,开箱即用,同样不展开,参见zsh教程

  • Paste 一个剪贴板工具,可以方便的记录和使用剪贴历史,相当于为剪贴板提供了一个置换空间Paste

参考

从客户端的角度设计后端的接口
亿级APP支付宝在移动端的高可用技术实践
你应该知道的 iTerm2 使用方法–MAC终端工具
zsh教程
Git 使用规范流程