文档章节

Android代码重构总结

叶大侠
 叶大侠
发布于 2017/08/02 22:12
字数 1769
阅读 20
收藏 0

这个总结比较晚了,快相隔一年了,总想挤点什么出来写一下,一方面是避免让自己懒下来,另一方面也是迫使自己复盘,思考这个过程中哪些地方做得还Ok,哪些地方做的不好。

不少公司初期的项目为了快速和低成本开发产品,一开始可能会找外包或者开发能力一般的开发人员来完成,等公司业务上去了,这时候也欠了一屁股的技术债,很幸运,我刚好就当了一回接盘侠。

初接手项目,闻到坏代码的味道,不要急于作出改变,重构是一件需要小心翼翼进行的一件事情,你的每一点改动都会给QA的童鞋带来额外的工作量,尽管你觉得没有问题。所以,第一步要做的就是先把整体的情况先摸个底,先把问题暴露出来,制定好你初步的重构方案。在这个过程中,你可能要先默默的利用空闲时间做好方案,毕竟可能还有很多业务代码要写的,你不得不忍受先在原来的框架上把当前的工作完成。

在我审视整个项目的时候,我发现存在有如下的问题:

  1. 多个已经不在维护的第三方库,尤其是网络库,没有进行二次封装,耦合度非常高;
  2. sdk版本也近一年没有进行更新过;
  3. 一些库使用方法不恰当,可能会带来内存泄漏和组件状态不正确(比如所在的 Activity 已经销毁)导致的崩溃问题;
  4. 有不少重复性很高的代码散落在各处;
  5. 变量名和方法名有些随意,驼峰和下划线风格并存;
  6. 逻辑过于冗长的方法,比如和 H5 页面的协议处理,近 1K 行的 if else
  7. 没有考虑一些边界条件,比如请求失败重试,没有数据的情况;
  8. 存在不少的魔数,往往在一些关键的逻辑里面,涉及到很多状态的变化处理。
  9. 没有懒加载用户还不需要的资源,页面 overdraw 的情况严重等;
  10. 还有一些情况暂时回想不起来,总之情况比较恶劣,骂人的冲动都有。

整理好问题和写好初步的重构方案之后,接下来就可以找你的老大去聊这个事情了,一般来说都会得到支持,这样也可以让上面知道你在埋头苦干的时候是在干嘛,当时的想法是想推翻重建的,做法就是一个新的项目工程和一个旧的并行开发,有新的开发任务就先在旧的工程上开发,然后新的工程就逐步赶上和替代,最后一次性把新的 app 交付给 QA 进行一次从头到尾的测试,当时评估这样应该会比在原来的基础上改耗费的时间要更少一些。但很快发现这样做行不通,一方面需求在不断变化,引起的变化两边工程都要改动;另外在开发进度上会和 iOS 端很难同步。所以很快不得改变了思路,整合新旧的代码,然后在同一条工程线上进行重构,这样一来,必然就多了很多整合的工作,重构变成了一个抽丝剥茧的过程,没那么痛快了,但好处就是每一步做的工作,都可以被看见。

既然是想改善代码,那肯定要先阻断烂代码再被添加进来,因此,第一件事要先建立起代码的相关规范,有可能的话,要尽可能加入 Code Review 这一流程来驱动规范的落实。重构的思路是从底层往高层,从变化少到变化频繁,比如底层的网络请求、图片缓存处理,这是变化少的部分,而页面和相关逻辑就是变化频繁的部分,从底层到高层好理解,从变化少到变化多则是对应经常变化的需求,或许在下个版本你就可以顺便把它重新做一遍,原来的代码彻底删除掉了。这里分享一部分具体的做法,可能对你有启发:

  1. 在改写网络层的时候,这次通过策略模式来分离了网络请求过程和数据解析过程,这样不管以后是用 okhttp 还是 volley ,是 Json 还是 Protocol Buffers 结构的数据,喜欢用 gson 还是 fastjson , 都只需要修改少量的代码,而且对上层调用没有任何影响。另外,由于新和旧的网络库不一样,为了减少 jar 包的数量,决定对旧的接口进行完全的兼容,但底层用的还是新的网络库。改写这一层后,对于新的代码就用新的接口,以前的就可以等待合适的时机再进行替换了。
  2. 这个 app 很多混合开发的地方,很多 H5 页面的点击需要调用起原生的方法,由于自定义的跳转协议数量非常多,原来的处理方法已经超过近 1K 行的代码,这样必然导致阅读和修改困难的问题,这里我采用了大家熟悉的状态模式把相关职责分散到不同的类里面了。
  3. 很多页面都有相似的过程,比如从从数据加载到加载失败处理,刷新和加载更多等,这些可以通过模板方法把相关的逻辑封装到基类里面,然后让子类去实现变化的部分,比如不同的视图和数据的绑定,可以大大减少代码量。

还有一些技巧已经回忆不起来了,整个重构过程的彻底完成花了差不多半年的时间,期间经历了好几个版本的迭代。从效果来看,重构后带来的好处是显著的:首先提升了今后的开发效率,拥有了更好的可维护性,其次 bug 的数量和崩溃率也有了大幅度的好转,最后得益于各种库的升级和优化,app 的性能也得到了不少的提升。总结一下,重构是一件春天播种,秋天收获的事情,要有耐心;正确的方法很重要,循序渐进可能比推翻重来更科学。

广告时间:建了个群,和大家业余探讨如何用技术去创收,有兴趣的童鞋可以加一下:

© 著作权归作者所有

共有 人打赏支持
叶大侠

叶大侠

粉丝 57
博文 44
码字总数 67312
作品 5
广州
程序员
关于Android MVP模式的思考

这一周对现有的Android项目进行了框架重构,使用MVP模式来重新构建整个项目和包结构。今天就来总结一下我在这个过程中理解和实践吧。 MVP概述 MVP是指Model,View和Presenter的缩写,是MVC模...

carpediem123
2017/03/12
0
0
无意发现的喜感代码,重构代码!(记录将持续更新)

为了以后方便查看,现在记录将倒序! 最后更新:2012-03-18 5.这些API看来还需要修改,需要我帮忙吗?不过我还不了解View. 来自android-2.3.3/android.view.View类,约3760行处。 /** @hid...

李海珍
2012/03/14
0
1
android记帐本、涂鸦、仿腾讯新闻、仿bilibili、Markdwon便签、资讯APP等源码

Android精选源码 kotlin版仿哔哩哔哩动画Android客户端源码(http://www.apkbus.com/thread-601995-1-1.html) android实现图片涂鸦效果源码(http://www.apkbus.com/thread-601996-1-1.html) ......

逆鳞龙
07/31
0
0
Airbnb: React Native 从选择到放弃

Airbnb 最近在 Medium 上发布了一系列文章详细描述了 Airbnb 与 React Native 从选择到放弃的整个心路历程。 React Native at Airbnb The Technology Building a Cross-Platform Mobile Tea...

banxi
06/20
0
0
使用Kotlin构建MVVM应用程序—提高篇:Dagger-Android

写在前面 提高篇的目的是想着写一些较深入的知识,包含一些源码分析、架构设想、脚手架搭建的东西。 面向的人群是中高级的开发者或者愿意深入了解如何快速构建Kotlin&&MVVM应用的人群。 Dagg...

ditclear
06/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7防火墙firewalld操作

firewalld Linux上新用的防火墙软件,跟iptables差不多的工具。 firewall-cmd 是 firewalld 的字符界面管理工具,firewalld是CentOS7的一大特性,最大的好处有两个:支持动态更新,不用重启服...

dingdayu
今天
1
0
关于组件化的最初步

一个工程可能会有多个版本,有国际版、国内版、还有针对各种不同的渠道化的打包版本、这个属于我们日常经常见到的打包差异化版本需求。 而对于工程的开发,比如以前的公司,分成了有三大块业...

DannyCoder
今天
2
0
Spring的Resttemplate发送带header的post请求

private HttpHeaders getJsonHeader() { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); ......

qiang123
昨天
3
0
Spring Cloud Gateway 之 Only one connection receive subscriber allowed

都说Spring Cloud Gateway好,我也来试试,可是配置了总是报下面这个错误: java.lang.IllegalStateException: Only one connection receive subscriber allowed. 困扰了我几天的问题,原来...

ThinkGem
昨天
27
0
学习设计模式——观察者模式

1. 认识观察者模式 1. 定义:定义对象之间一种一对多的依赖关系,当一个对象状态发生变化时,依赖该对象的其他对象都会得到通知并进行相应的变化。 2. 组织结构: Subject:目标对象类,会被...

江左煤郎
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部