项目的改造——RemoveButterKnife插件代码的重构

前言

这篇文章记述了我的插件RemoveButterKnife的代码改进过程以及思路,关于插件,各位可以看RemoveButterKnife代码库,关于文章,可以看RemoveButterKnife从构思到实现

原因

近期想给原来的插件RemoveButterKnife加入一些新的功能,发现以前的代码没有使用任何的设计模式,全部功能都写在一起,对于新功能的添加来说十分糟糕。趁此机会重构了一下代码,在此记录过程。

具体步骤

插件主要分为三个部分
1. 主插件入口部分
2. 代码寻找/处理部分
3. 代码生成部分

1. 主插件入口部分

我们首先看第一部分,主入口部分,这部分内容主要代码如下

这部分主要是获取一些需要处理的上下文变量以及下发操作给删除操作,不需要进行处理

2. 代码寻找/处理部分

第二部分,也是我们的主要逻辑所在的部分,主要代码逻辑如下
1.寻找import相关代码,并把行号存入列表
2.寻找Api调用代码,存入行号
3.寻找bind相关代码,存入行号,分离id和name以及type,分别存入对应集合
4.删除上述生成的行号集合对应代码
5.将生成findview的指令下发给代码生成类
通过上述逻辑,我们可以看到,1-3步是逻辑不相关部分,没有前后顺序,也没有相互依赖。
那么,我们就可以通过责任链的模式来对1-3步进行拆分。

首先,我们创建一个BaseChain作为基类

BaseChain主要分为三个部分
1.成员部分
2.处理逻辑部分
3.设置子链部分
代码如下

然后继续创建子Chain类

1.寻找import相关代码,并把行号存入列表
2.寻找Api调用代码,存入行号
3.寻找bind相关代码,存入行号,分离id和name以及type,分别存入对应集合
我们这里拿寻找import相关代码,并把行号存入列表来举例

有了对应的子类,我们还需要加上junit测试,例如

这时候我们发现,在这几个子类的测试中,每次都需要初始化一些集合,每个都写十分麻烦,于是我们将其抽出来成为基类,代码如下

这样,我们的测试类直接继承这个基类就可以省下一些代码量了。

删除对应行代码

此部分主要是调用idea的api进行处理,所以我们这里不做过多修改,把方法保留在action里即可。

3生成findViewByid部分

生成代码的逻辑是寻找到文本的特定位置然后依据上述找到的id,name等,进行语句的插入
这一部分前期只负责生成findViewById语句,所以做成单个工具类没有问题。
但是随着项目的扩展,我们还会生成更多种类的代码,例如onclick对应的代码序列等,这时我们就需要对其进行重构。

分析行为

该部分的主要操作是寻找代码指定部分,并使用信息生成代码

1.拆分行为

我们可以拆分为两个步骤
1.寻找特定部分
2.按照分类生成代码
生成代码部分可以分为基础行为和特定行为,基础行为是指生成代码的api调用,特定行为是指生成的代码根据种类不同而不同

2.拆分方案

根据上述分析,我们可以使用策略模式进行优化,每一种生成代码都有对应的策略,我们使用的时候只需要根据类别使用不同的策略类来生成即可
首先,我们建立接口GenCodeStrategy

然后,让我们建立一个Context类,GenCodeContext

再来看看我们其中一个策略类,ActivityStrategy

最后,我们要在原来直接写代码生成的文件FindViewByIdWriter中使用我们的策略模式

对比

我们可以从重构前/后的目录结构来对比重构的效果
重构之前

重构之后

可能会有人问了,重构后感觉复杂了很多,但是从逻辑的维度上来说,一个熟悉设计模式的程序员可以很快/方便的阅读重构后的代码,而重构前的代码虽然看起来文件少,但是所有逻辑都在一个文件中,往往会让人无法阅读/理解

u3coding
A software developer

Leave a Comment

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.