文档章节

Android代码重构总结

叶大侠
 叶大侠
发布于 2017/08/02 22:12
字数 1769
阅读 14
收藏 0
点赞 0
评论 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 的性能也得到了不少的提升。总结一下,重构是一件春天播种,秋天收获的事情,要有耐心;正确的方法很重要,循序渐进可能比推翻重来更科学。

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

© 著作权归作者所有

共有 人打赏支持
叶大侠

叶大侠

粉丝 56
博文 44
码字总数 67312
作品 5
广州
程序员
Airbnb: React Native 从选择到放弃

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

banxi ⋅ 前天 ⋅ 0

Android Studio 3.2新功能特性

android studio3.2预览版本已经发布了,下面这些功能在最新的版本已经提供,但可能尚未在测试版本中发布渠道中提供。 什么是新的助理 Android Studio 3.2有一个新的Assistant面板,可以通知您...

我就是马云飞 ⋅ 06/14 ⋅ 0

我的Android重构之旅:框架篇

在我这几年的学习和成长中,慢慢的意识到搭建一个优秀的 Android 开发框架是一件非常困难以及痛苦的事情,它不仅需要满足不断增长的业务需求,还要保证框架自身的整洁与扩展性,这让事情变得...

codeGoogle ⋅ 06/13 ⋅ 0

集成开发工具 Android Studio 3.2 Canary 13 发布

Android Studio 3.2 Canary 13 已经发布在 Canary 和 Dev 频道。 Android Studio 是一个 Android 集成开发工具,基于 IntelliJ IDEA,类似 Eclipse ADT,Android Studio 提供了集成的 Androi...

雨田桑 ⋅ 05/01 ⋅ 0

我的Android重构之旅:架构篇

EF A舞蹈服 去年10月底来到了新公司,刚开始接手 Android 项目时,发现该项目真的是一团遭,项目开发上没有任何架构可言,开发人员连简单的 MVC、MVP 都不了解,Activity 及其臃肿,业务边界...

codeGoogle ⋅ 05/31 ⋅ 0

Android Studio 3.2 Canary 发布,新增大量实用功能

在今天的 Google 2018 I/O 大会上,释出了 Android Studio 3.2 的最新预览版,并带来了一系列的新功能,如支持 Android P 开发预览版、新的 Android App Bundle,以及 Android Jetpack。官方...

局长 ⋅ 05/09 ⋅ 0

react-native技术的优劣

前言 从2017年初开始到现在,使用React-Native做项目已经一年了。我们做的是一款IM软件,嵌入在一个手机游戏平台的工程内部。之所以要采用react-native(后文简称RN)框架重构它,是因为现在...

codeGoogle ⋅ 04/23 ⋅ 0

Proxy-Go 全平台 SDK 迎来 v4.8 更新!

Proxy-Go 全平台 SDK是proxy使用gombile实现了一份go代码编译为android和ios平台下面可以直接调用的sdk类库, 另外还为linux和windows提供sdk支持,基于这些类库,APP开发者可以轻松的开发出各...

狂奔的蜗牛. ⋅ 05/04 ⋅ 2

仿微博App 才搭了个架子 仅做个人记录

才做了一点点。。。之所以写本文,是因为,架构搭的还算可以,个人记录下,哈哈 lib是我的代码库,micro blog是这个项目的东西 lib没有直接从我的Lib项目拷过来 原因:1.还用不上那么多 2.养成...

qq_36523667 ⋅ 04/18 ⋅ 0

架构组件之--ViewModel

前言:这是自己的的第一篇文章,希望可以把自己所学到的东西都能总结并分享出来,希望可以做好。 一、简介 2017Google I/O大会上google引入了lifeCycle组件,说来惭愧,最近才来使用,这也是...

墨迹_T ⋅ 05/27 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 23分钟前 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

eclipse酷炫大法之设置主题、皮肤

eclipse酷炫大法 目前两款不错的eclipse 1.系统设置 Window->Preferences->General->Appearance 2.Eclipse Marketplace下载【推荐】 Help->Eclipse Marketplace->搜索‘theme’进行安装 比如......

anlve ⋅ 昨天 ⋅ 0

vim编辑模式、vim命令模式、vim实践

vim编辑模式 编辑模式用来输入或修改文本内容,编辑模式除了Esc外其他键几乎都是输入 如何进入编辑模式 一般模式输入以下按键,均可进入编辑模式,左下角提示 insert(中文为插入) 字样 i ...

蛋黄Yolks ⋅ 昨天 ⋅ 0

大数据入门基础:SSH介绍

什么是ssh 简单说,SSH是一种网络协议,用于计算机之间的加密登录。 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码...

董黎明 ⋅ 昨天 ⋅ 0

web3j教程

web3j是一个轻量级、高度模块化、响应式、类型安全的Java和Android类库提供丰富API,用于处理以太坊智能合约及与以太坊网络上的客户端(节点)进行集成。 汇智网最新发布的web3j教程,详细讲解...

汇智网教程 ⋅ 昨天 ⋅ 0

谷歌:安全问题机制并不如你想象中安全

腾讯科技讯 5月25日,如今的你或许已经对许多网站所使用的“安全问题机制”习以为常了,但你真的认为包括“你第一个宠物的名字是什么?”这些问题能够保障你的帐户安全吗? 根据谷歌(微博)安...

问题终结者 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部