一个创业产品的iOS客户端架构到底怎么做呢?现下最有活力的图片社交软件Nice的技术负责人刘诗彬将为我们解答创业产品如何实现iOS客户端架构。
分享人:刘诗彬,毕业于北京邮电大学电子信息科学与技术专业。曾在创业公司工作2年,12年加入新浪微博,资深iOS工程师,作为核心团队成员参与了微博iOS客户端的重构和发展。2014年加入Nice图片社交app,担任iOS技术负责人。
万事开头难,当你开始着手设计并实现iOS客户端架构的时候,很可能会出现暂时无从下手的情况。
那么,一个创业产品的iOS客户端架构到底怎么做呢?现下最有活力的图片社交软件Nice的技术负责人刘诗彬将为我们解答创业产品如何实现iOS客户端架构。
01、创业项目的特点和问题
作为创业产品,不管从产品、技术、团队、节奏还是业务特点等都与相对成熟的大产品有有很大的区别。首先分析一下创业公司做产品的一些特点:
1.团队不够成熟
成熟的产品团队会有一套共同的做事方式,新人会慢慢被同化,而创业公司很多时候都是在较短时间的把大家召集在一起,团队需要融合到一起,所以找到适合的共同做事方式是非常重要的。
2.基础建设不够完善
作为一个新的产品,有很多基础工作,从技术框架,协作方式甚至到代码风格也需要逐渐建立起来的,为了支撑产品健康发展的基础建设是很重要的。
3.产品不够稳定
作为一个创新产品,在产品迭代过程中可能有各种的创新和尝试,反映到技术实现上就是经常会有各种的需要变更,代码可能会需要经常重构,为了能比较好的适应产品的节奏,在架构和具体实现设计上需要慎重考虑。
技术团队需要能很好的支持这些变化和调整,做到最高的效率和效果,否则很容易在这个过程中欠下很多债,最后会慢慢累积到拖整个产品的后腿。
4.迭代速度快
大家都能看到现在市场的节奏,创业就是在和时间赛跑,快速的迭代是基本的原则。
从微博的一个半月一个版本到现在的一到两周一个版本,不同的情况需要不同的做事方式,设计一个支持快速变化的框架来协调好不同优先级的事情是很重要的。
02、基于创业特点的技术框架设计和分析
针对前面提到的特点,我们慢慢总结出一些方案来适应,总体来讲就是:
1.技术核心
团队是做事的根本,保证团队对基本技术思想和方案的共同认识非常重要。在快速变化的产品节奏中,如果团队有高度的默契,往往能专注在业务本身,做到事半功倍。如果不能统一大家的认识,沟通会遇到不少问题,项目可能越来越繁杂,各个模块会越来越难以维护,最后会浪费很多时间在不必要的管理上。
2.可扩展性
创业产品初期大多还是以需求为核心的项目,在设计实现方案时需要把为适应产品需求的扩展性放在较高的位置,要有适应环境和需求变化的能力。
3.集成性
创业产品一般都有一个确定的产品核心价值,核心体验是一个产品成功的关键,在考虑扩展性同时不能脱离这个产品核心,怎么围绕核心产品功能来协调各模块的实现也很重要。要把各模块能有效的结合起来,发挥最好的产品效果。
4.可成长性
各部分能独立成长优化,适应产品的快速发展。
到具体方案实现上总结为以下几个方面:
1.层次化
最开始接手的时候我们的项目没有模块的和模型的概念,各种基础功能可能混杂在各种具体业务里,业务调整和扩展非常困难,例如没有数据模型,不能统一解析。第三方服务没有统一,各个地方各自实现。账户信息没有统一管理,状态很难同步。在把能独立和抽象的逻辑各自整理后,按照不同的特点我们把项目总结为三层:
技术基础:这一层是与业务无关的支撑一个项目开发的基础,虽然不涉及到具体业务,但是他决定了项目的基础技术指标。
业务支持:这一层实现了最基础的业务逻辑,一般一个项目的最核心的功能不会改变,这一层的实现基本体现了项目最基本的核心逻辑,实现相对也比较稳定。
具体业务:这是真正的各种具体功能,基于下面的基础,在实现具体业务时能专注于具体功能的开发,根据产品功能的划分,实现上也能再具体化分为各个模块。
不同的层次有不同的特点,基础要求稳定高效可扩展,具体业务要求用户体验和开发效率,根据不同的特点在实现上就可以对症下药,设计不同的方案。只要定义好各个层次之间和模块之间的接口就能很方便的进行协同开发。按照不同的特点,团队分工合作上也可以更合理的协调不同的资源。
2.模块化
其次是根据刚才的分层,我们同时已经把项目分为了各个模块,根据特点各个层次的模块也有不同的设计思想。
首先,定义好大的框架,在创业阶段,框架可能只需要满足简单清晰,高效和快速,但是保留足够的扩展性。只要保证好确定的接口,基础框架还可以独立进行优化和调整。
然后是对业务模块的划分,不同的业务模块可能也有不同的特点,比如有的注重效率有的注重交互的体验,有的注重扩展性。很多时候我们讨论的设计模式可能都属于这一层,类似MVC,MVP,MVVM,其实我觉得不同的模块不一定要完全统一,适合最重要。
在我们的项目中,大部分业务逻辑本身内容都没有很大变化,但是交互和UI会经常有较大调整,所以我们把各模块的接口交互和数据处理等确定逻辑抽象出来,提供出特定的接口,我们称之为“Engine”,UI则专门拿出来作为适配,只要满足固定的接口就能和对Engine对接,协调和组织的的工作则放在Controller,逐渐形成了Controller-Engine-Model-View的模型。
最后是具体业务的实现细节,一般前面两个层次是需要相对稳定的,由于涉及到团队合作,在具体细节上可能就很难保证统一了,具体情况具体分析是这一层的方法,至少可以把差异性和风险都控制在很具体的点上。
3.插件化
为了做到前面所提的适应性和扩展性,很多时候我们会用到插件化的设计。
以微博发布系统基本结构为例,首先发布内容这个基本功能本身基本不会有大的变化,所以抽象出了负责管理数据和逻辑流程的发布队列和负责交互和UI框架的发布器容器。
但是,随着业务的发展和各种产品层面的调整发布的内容和形式常常会有较大的变化,为了使各种逻辑更加清晰,每种内容可以独立成一个子模块,他们自己可能有自己的交互、UI和数据等逻辑。
03、实践经验重点总结
接口设计
为了把这些模块比较方便的结合在一起,便抽象出一个通用接口与发布器交互,这样不管单独模块怎么调整一般都不会影响整体的逻辑。也可以做到方便的扩展和业务调整。
涉及到模块间和模块内结合需要用到对应的接口形式。
接口形式有很多种,经常会有不少人习惯性选择某种特定形式,但是其实并没有那么合适。其实每种形式都有自己的特点,需要针对实际情况选择,这往往是需要注意的。
在实际开发过程中我们还是会经常遇到之前的设计或者实现不能满足最新的需求,这时候就需要涉及到重构。怎么在保证产品节奏的同时做到及时的做好合适重构是经常遇到的冲突。
何时重构
我们经常可能会因为自己的感觉来觉得那些实现不爽就想要重构,其实重构之前还是应该多做好准备。重构要满足三个条件:实现新需求时;修复bug时;有足够时间来优化。那么何时要避免重构呢?没有产品生命里的模块,时间不能保证的时候,没有较为明确的预期时,都是要尽量避免重构的。
在实际项目中不只是代码逻辑,整个流程需要很多基础设施来保障,我总结为三部分:
首先是业务流程 从产品需求提出到评审开发,再到测试回归最后检验产品效果,整个流程需要有比较清楚的流程控制来保障高效的执行。
然后到具体的开发中其实有很多东西可以用来提高效率,开源工具,自动化脚本,基础工具等等。
基础设施建设
1.业务流程管理
除了代码实现外开发流程中还会涉及到很多必要流程,打包分发测试,Crash和性能收集分析等。
上面是我们用到过的一些流程管理工具:
Wiki:https://www.atlassian.com/software/confluence
Trello:https://trello.com
JIRA:https://www.atlassian.com/software/jira
Tower:https://tower.im
我们使用Wiki来管理产品文档,技术规划,项目排期等文档,能比较方便的跟踪和多人协作。
Trello能很方便的跟踪工作流程和任务协作以及时间计划。
JIRA是也是任务跟踪,但是一般大家都用来作为bug管理,因为他的责任跟踪和流程管理非常明确。
以前是试用过Tower,是国产的一个协作和任务管理工具,前面三个功能他都有,但是可能没有每个专业的那么细化。
各种工具都有优缺点,选择一个适合的工具能保证流程的控制和效率。
2.代码和实现
在开发过程中只要留心会有很多细节可以优化,甚至能极大的提高质量和效率。比如现在在ARC环境下其实经常有人会忽略内存管理的问题,通过一些简单的代码就能帮助发现可能的内存泄露。
很多代码逻辑可以抽象出来实现自动处理,往往能极大的优化成本和性能,比如我们结合项目实际和各种开源项目实现的自动解析和序列化数据。
随着项目快速的发展和变化,项目很容易变得臃肿,中间可能有很多无用的资源和逻辑,通过一些简单的脚本就能发现项目里的无用资源和逻辑。最近我们通过脚本检查和整理项目让安装包减少了十几M。
Crash统计分析,BUG修复,动态配置等都有很多成熟的解决方案,也可以根据项目实际自己优化。
3.辅助工具
除了代码外还有很多事情可以提高工作效率,有不少现成的工具能使用,如果需要也可以开发适合自己的辅助工具。
在我们的项目中,节奏非常快,经常会有各种尝试demo或者需求需要测试review。
之前的打包测试的效率非常低,首先是开发需要花很多精力在打包上,然后需要用各种方式把安装包分发给不同的人,然后还要跟踪反馈。
所以我们开发了一套自动化打包平台省去打包和分发跟踪的成本。包括Xcode套件里有很多功能和工具能帮助发现解决问题和提高效率,善于使用会受益无穷。其他类似Charles,Sketch等工具也是应用广泛。