前言
最近面试了很多候选人,发现很多同学在简历上都写得非常厉害,负责架构设计,项目重构之类的。但是问起来,很多人都说不出个所以然来。今天我们不谈架构设计,我们聊一下重构。我面试时候经常会问,你是怎么重构的,从哪些方面入手。大部分的人基本上回答就是换一下网络请求的框架,图片处理的框架,好一些的能够说出一些MVP/MVVM,再好一点的能够说出一些模块化,组件化的东西。给我最大的感觉就是为了重构而重构,或者是无中生有的重构,没有全面的思考过为什么要这样做。我们重构的目的就是为了让项目的可读性,可维护性,扩展性更强。后期其他同学接手,不至于把祖宗都问候一遍。刚好,最近我一直在维护一个2010年到现在的一个项目,谈一谈重构的过程。
1、注释, activity、fragment、类、方法 一定要有注释
每一个页面,类,方法,都要有对应的注释,写明作者是谁,时间,还有是做什么,这样对后面的同学梳理流程的时候,会顺畅很多。毕竟自己觉得自己写的代码很清晰,在其他人眼中就不一定是这样了。
activity:C:Program FilesAndroidAndroid Studiopluginsandroidlib emplatesactivitiesEmptyActivity
ootsrcapp_package
在头部添加
/**
* @Description:
* @Author: huangjialin
* @CreateDate: ${.now?string("yyyy-MM-dd")}
*/
普通类的,可以直接在studio中进行设置 settings -- > File and Code Templates -- >File Header 中添加
/**
* @Description: java类作用描述
* @Author: huangjialin
* @CreateDate: ${DATE} ${TIME}
*/
命名规范,统一,包括资源,java文件,布局,方法名,字段等等
这里推荐使用插件:Alibaba Java Coding Guidelines
要求:
1、(从命名上能够知道这个是activity,fragment还是adapter等等)
2、见其名,能知其意
在我重构的过程中,遇到很多这样的
这是直接从项目中进行截图的,我都不担心会出现什么泄密的情况。这样的命名,就只比使用A,B,C这样的命名好一点而已。好的命名基本上能够知道这个类,页面,方法是干什么的,对后面维护的同学也是非常友好的。
java文件命名,一定要做到见其名,知其意,即使名字长一些也是可以的,比如说aaaActivity ,aaaFragment...,这个aaa基本就是这个文件是做什么的。布局,方法名,字段这些,也是如此,但是命名的同时,也要注意编码规范。
针对于资源的命名,不光要能从名字中知道含义,还需要考虑后期组件化后,可能会产生的资源冲突
这里建议在module的build.gradle中添加
//给 Module 内的资源名增加前缀, 避免资源名冲突
resourcePrefix "${project.name.toLowerCase().replaceAll("-", "_")}_"
这样给资源命名是会提示添加上对应module的前缀了。
3、工具类封装
Log,Toast,SharedPreferences,dialog,animation 等等等等,特别是对于经历过多人维护的项目,很多工具类都有很几套,一人弄一套,所以我们要做的就是统一,一个项目中不要出现多个重复的工具类,否则对于后期维护那是很困难的。
4、第三方jar的统一 如网络,图片等等
比如说我维护的这个项目,2010年写的到现在,光网络请求的就有四个,最早以前就是用HttpURLConnection,然后又有Volley,然后到Okhttp,接着就是Retrofit + okhttp,导致了现在一个很严重的问题,新人维护都不敢乱动,一直堆代码,当然,现在这样的请求是没事,但是如果后期,比如说需要更改域名,加密,在头部添加一些参数,等等等等 ,那倒霉的永远是最后一个接手的人。
当然这里需要注意两个问题
第一:不要一上来就直接全部替换,要循序渐进,直接全部替换,那么风险会非常大,对开发人员,测试人员,压力都会很大。
第二:既然要统一,那么选用个框架比较好?我个人的看法是首先是选择稳定性好的,性能好的,自己擅长的。
5、模块化->组件化,MVP/MVVM
做到这一步,多少对项目有些熟悉了,接下来要先做的是架构的分层还是代码的分离,取决于自身对项目的熟悉程度,如果项目中已经做了模块化,那么需要考虑的是以下几点:
1、此时的模块分离的粒度是否符合当前,可能当时分层的时候是合理的,但是随着业务的增加,是不是存在一些臃肿的代码,需不需要更加细致的分离。这个需要根据项目来决定的。
2、项目越大,那就考虑组件化,组件化是在模块化的基础上弄的,所以一定要先模块化在组件化。
3、组件化需要分层更加细致,比如第三方jar层,公共组件层,组件层,调试层等等,还需要考虑组件间的耦合,通信等,具体的可以专门去学习组件化。
4、插件化,如果做完组件化,在做插件化,那么插件化将会容易很多,同理,需不需要做插件化,根据公司项目来决定。
MVP/MVVM
这个主要是针对于代码的隔离,如果项目中已经使用了mvp,那就接着用mvp,不要因为一些东西出来了,比如现在Google强推一个jetpack,就马上换MVVM,那样风险是非常大的,如果都是allinone在一个activity,那么直接就使用MVVM来进行重构。LiveData + ViewModel优势是很大的。
组件化 + MVP + MVVM可参考:https://www.cnblogs.com/huangjialin/p/13086553.html
6、涉及模式的使用
到这一步,基本对整个项目都是有一个明显的认识了,到这里就要考虑业务了,需要考虑更多的是业务的扩展性好不好,可读性好不好,好不好维护了。在这里我们可以根据自己实际的项目来使用一些设计模式,比如单例,观察者,工厂,Build模式,策略模式 等等
7、网络数据结构重构
这个看公司业务来决定,这个处理的是后端返回的数据结构是否需要统一,这里看公司和前后端的情况来决定。毕竟这个改动,不光是前端改,也需要后端同学改动了,工作量大,风险很高。
8、性能优化:卡顿,内存,启动,布局优化,apk体积
到这一步,重构代码这部分,基本OK了,现在需要考虑的是应用的性能问题了,这里我列出来,我个人觉得从左到右 优先级由高到底 的顺序来处理,具体怎么做,参考这里。
卡顿优化:https://www.cnblogs.com/huangjialin/p/13389421.html
内存优化:https://www.cnblogs.com/huangjialin/p/13327949.html
启动优化:https://www.cnblogs.com/huangjialin/p/13292042.html
布局优化:https://www.cnblogs.com/huangjialin/p/13353541.html
9、文档输出
非常重要!!!非常重要!!!非常重要!!!
这一步没做好,很容易导致前面做的前功尽弃。所以需要一边重构,一边输出文档,后面接手的人,会感谢你的。
10、重构之路,任重而道远,需要定期重构。
除非非常大的重构,否则重构不需要特意排期,只要我们发现某个地方不合理,都可以进行重构,但是需要通知测试人员注意测试。重构之路,任重而道远 !!!!!!!!!!!!!!!!