持续重构
在这一年的开发过程中,从什么都没有到现在的稳定迭代,其中经历了多次的重构工作,这里来聊聊其中的一些看法。
我们的模块,从开始的刚好能够满足需求,到后面能够胜任各种要求,再到最后,简单的调用就可以完美的胜任工作。这是持续根据实际情况思考,经过多次重构而得到的结果。
为什么要重构
从出发点来看:
- 功能缺陷,已经很难修复或者修复导致代码更加混乱,希望通过重构能够彻底的解决问题
- 功能越来越复杂,代码越来越多,导致维护成本非常大
从最终点来看:
- 统一结构,将类似的东西统一,模块化,避免重复代码和相同的bug
- 细分功能,将一个复杂的功能细分,减少开发的复杂度,增加复用性
- 最终的目的都是为了使用者更加简单可靠
最佳时机
这里我把重构最适合的时机概括为两种:
- 功能爆炸期,当功能复杂化,代码单纯的大量叠加时,必然形成很多复杂逻辑,并且冗余的代码
- 类爆炸期,当类似的功能经过一定的归类,导致每种类型的子类型随着项目进行而急剧增加的时候
以我们的项目经验来看,在前几期的时候,由于时间紧张,功能的大量累加,导致一个复杂点的页面就有上千行的代码,此时每次改动都会花费大量时间,而且有部分bug不能从根本上解决。这时候我们开始了第一次的大规模重构,主要包含以下几点:
- 提出组件化框架,拆分页面代码,并把之前的一些功能用组件化改写
- 统一相似组件,把视觉相似的组件进行统一化,并且对代码结构进行重新归类
- 归纳部分相似功能,比如导航栏、页面头部的交互变化,网络层重新整理
经过这次的整理拆分后,已经是一个比较同一的整体了,能够很好的复用和修改。
但是经过部多个版本之后,又出现了新的问题。每次对页面和功能的特例化,导致相同资源的组件或者功能越来越多,导致每次使用的时候都不太清楚用哪个组件比较好。而且每个组件的接口也有略微的差异,并不能无缝的切换。以及一些原来就存在的,还没有经过拆分的功能。
这次主要做的主要是统一化工作,比如最简单的点赞按钮,在很多地方使用,同时因为历史原因,很多图标并不是同一个资源,逻辑规则也并不统一,接口也不统一。经过对整个项目的观察,发现其实目前项目中点赞按钮只有大小两种样式,那么使用抽象工厂的方式进行归纳,对外暴露的只有一个类型,那么这样使用者就不需要知道其中具体有几个组件了。
public class PraiseButton {
+ (instanceType)buttonWithStyle:style;
}
private class _SmallPraiseButton: PraiseButton;
private class _BigPraiseButton: PraiseButton;
而其他组件和功能对同一个资源的描述目前也是比较分散,今后也会按照这样的方式,按照资源类型进行归类与统一。
重构目的
目前来说两次重构的目的是:
- 第一次
拆分功能,让每个模块尽可能的简单,可复用;减少复杂度,减少隐藏的bug;能够给团队其他成员使用。
- 第二次
合并和归纳功能;统一合并相同资源、功能的接口;减少对外暴露的实现细节;让使用者面对的只有一个对象,使用更加简单;减少理解沟通成本。
犹如读书时候老师说的一件事,刚开始读书的时候,书是薄的;读的久了,书就变厚了;当你已经精通书中所有,书又变薄了。