做技术分成好几个层次:
- 第一层:把功能做出来,不用考虑代码质量。
- 第二层:把功能做稳定,不会有太多的bug。
- 第三层:把功能做得快,能够快速响应需求。
如果是从零开始做项目,迫于经验不足和时间紧迫,都会经历从第一层慢慢向上的过程。遗憾的是,做到第三层是很难的,但不管怎样,追求的过程是充满挑战的,也是受益无穷的。
评价一下我们现在的项目,还应留在第一层。为了能够达到第三层,我和同事们一起想了一些方法和步骤。
ARC
ARC全名Automatic Reference Counting,是苹果公司在WWDC2011上就推出来的一项技术,只在减少程序员的工作,不用再去手动管理内存(典型的费力不讨好),而是由编译器采用智能算法,在编译的时候自动插入内存管理代码。ARC目前已经广泛的被绝大部分开发者所接受,因为它带来了开发效率的提升。我们目前的代码还没有采用ARC,这个改一下不是什么难事,具体做法可参考官方文档。
Xib,StoryBoard
Xib、StoryBoard和纯代码到底哪个好,一直被程序员们争个不休。但不可否认的是,苹果公司每次更新XCode,界面工具都会不断被优化以方便开发。尤其是分辨率越来越多以后,一些特性如AutoLayout,最佳使用场景就是界面工具,手写AutoLayout是很复杂的。所以我推荐用Xib乃至StoryBoard,但是并不反对用纯代码,因为有些复杂的UI更适合用代码写。三者可以和平共处,并不是非此即彼的关系。
代码规范
这是老生常谈,不多说了,大家都懂的。前些天草拟了一份规范。
模块化
一个软件,尤其是大中型的软件,肯定有很多相对独立的功能。模块化相当于对大系统进行降维,使开发大系统像开发小功能一样容易。而且,有些模块可以被复用,能提升开发的效率和质量。
我们现在的代码虽然是按照业务功能分开写的,但并没有严格的分开。比如登录相关的逻辑就散布在程序的多个地方,如果把登录做成一个模块,对外提供一组接口,登录逻辑要改就很方便,不用在多个地方改。分模块的要义是抽象出一组接口,模块间的通信只依赖于接口。模块的最终形式是.a文件。
API包装层
在很多公司,前后台不属于同一个部门。后开负责开发基本的API,而前台对于返回的数据进行处理。这种处理有时候是很复杂的,因为后台不关心具体前端需求(或者它要为多平台提供支持),所以提供的数据往往是非常原始的。这样就有三种做法:
- 前台在请求的地方单独处理。
- 前台有专门的网络层处理。
- 后台提供一层包装API,将数据进行预处理。
目前我们用的是第一种做法,最好的还是第三种做法。
控件
控件的作用是封装通用的UI组件,写iOS代码大部分时间都是在写UI,所以控件可以大大提高开发速度和质量。
网上有很多开源的组件,我们可以参考,但一定要看明白,不能拿来就用,不然风险太大。向UITableView的刷新、RichLabel等等,都需要控件化。
业务逻辑与视图分离
目前的代码是不分离的,一股脑儿写在ViewController里面。后果就是无法进行单元测试、并且维护性差。分层就可以解决这一问题,业界已经有很多方法:
MVVM
更轻量的 View Controllers
使用 VIPER 构建 iOS 应用
网络层封装
无论是ASI还是AFNetWork,都已经提供了一套基本的Http框架,我们要做的是在此基础上进行一层包装,调用者只需要了解包装层的接口,这样以后替换类库都不会有问题。
数据层封装
把数据层抽象出来,这样代用存储代码就会变得很简单。而且数据层扩展各种存储类型,对业务层代码不需要太大的改动。
动画框架
手势返回是必须要做的。
至于动画框架还没想清楚,因为动画变化多端,所以对框架的通用性就有很高的要求。如果太通用,就和系统API没什么差别了。
这是Facebook推出的POP动画框架,值得参考一下。
Bean规范化
Bean是程序中最基本的对象。没有业务相关的方法,只有属性和存储方法。每个Bean一个文件,目前是所有Bean在一个文件中,不容易查看。
基类
无基类,不框架。基类会随着项目的发展不断演进,基类可以让问哦们少些很多很多的代码。
工具类
代码规范里也提到,工具类的使用有两种误区:
- Util方法没有单独写在一个文件里面,不具备重用性。
- 有一个超级Util类,写了一堆不太相关的方法。
能用Category尽量用Category,对于Util,也要按功能进行区分。
分享框架
分享不是一件特别困难的事,所以最好自己做。用第三方定制UI也是很难实现的,还不如自己做。
上文提出的种种,都是我们要做的,如果按理想情况做完的话,我们就能达到本文开头所说的第三层境界了。但是过程肯定不轻松,也许会在某一点上失败,但是前进的过程又是充满诱惑的,所以加油吧!