移动应用遗留系统重构(7)- 解耦重构演示篇(一)

前言

 

移动应用遗留系统重构(5)- 重构方法篇中我们分享了重构流程,主要为4个操作步骤。

  1. 识别一个内聚的包

  2. 解除该包的异常依赖

  3. 移动该包对应的代码及资源到新的模块

  4. 包解耦验收

 

移动应用遗留系统重构(6)- 测试篇中我们为CloudDisk补充了一组基本的冒烟测试。有了基本的测试守护后,本篇我们将挑选library(基础组件库)及file(文件业务模块)2个包进行重构演示。文章中包含操作的流程,同时录制了视频。

 

library模块重构代码演示视频:mp.weixin.qq.com/s/C0nQRbgmp…

 

file模块重构代码演示视频:mp.weixin.qq.com/s/xbAIu6bWS…

 

安全重构演示

 

library包重构

 

  1. 依赖分析

     

图片

 

通过分析我们发现library包存在对上层模块的反向依赖,该依赖为异常依赖,须要解除。

 

  1. 安全重构

 

重构前代码:

public class HttpUtils {    public static void post(String url) {        //发送http post请求,需要用到userId做标识        String params = UserController.userId;    }    public static void get(String url) {        //发送http get请求,需要用到userId做标识        String params = UserController.userId;    }}
 

重构手法:提取方法参数

 

图片

 

重构后代码:

public class HttpUtils {    public static void post(String url, String userId) {        //发送http post请求,需要用到userId做标识        String params = userId;    }    public static void get(String url, String userId) {        //发送http get请求,需要用到userId做标识        String params = userId;    }}
 
  1. 代码移动

 

代码移动至独立的library,加上对应的Gradle依赖:

 

图片

 

移动后模块结构如下:

 

图片

 

  1. 功能验证

 

执行冒烟测试,验证功能

 

./gradlew app:testDebug --tests SmokeTesting
 

图片

 

代码演示:mp.weixin.qq.com/s/C0nQRbgmp…

 

具体的代码:github链接

https://github.com/junbin1011/CloudDisk/commit/852463774f69142cb2ecb2b20cc581da6e1f3db7

 

file包重构

 

  1. 依赖分析

     

图片

 

通过分析我们发现file包存在横向bundle模块的依赖,该依赖为异常依赖,须要解除。

 

  1. 安全重构

 

重构前代码:

public class FileController {    public List<FileInfo> getFileList() {        return new ArrayList<>();    }
    public FileInfo upload(String path) {        //上传文件        LogUtils.log("upload file");        HttpUtils.post("http://file", UserController.userId);        return new FileInfo();    }
    public FileInfo download(String url) {        //下载文件        if (!UserController.isLogin) {            return null;        }        return new FileInfo();    }}
 

重构手法:

 

2.1 抽取getUserId、isLogin方法

 

图片

图片

 

重构后代码如下:

public class FileController {    public List<FileInfo> getFileList() {        return new ArrayList<>();    }
    public FileInfo upload(String path) {        //上传文件        LogUtils.log("upload file");        HttpUtils.post("http://file", getUserId());        return new FileInfo();    }
    public FileInfo download(String url) {        //下载文件        if (!isLogin()) {            return null;        }        return new FileInfo();    }
    private String getUserId() {        return UserController.userId;    }
    private boolean isLogin() {        return UserController.isLogin;    }}

 

2.2 抽取代理类,UserState

 

图片

图片

 

重构后代码如下:

public class FileController {    private final UserState userState = new UserState();
    public List<FileInfo> getFileList() {        return new ArrayList<>();    }
    public FileInfo upload(String path) {        //上传文件        LogUtils.log("upload file");        HttpUtils.post("http://file", userState.getUserId());        return new FileInfo();    }
    public FileInfo download(String url) {        //下载文件        if (!userState.isLogin()) {            return null;        }        return new FileInfo();    }}
 

 

2.3 抽取接口

 

图片

图片

 

重构后代码如下:

public class FileController {    private final UserState userState = new UserStateImpl();
    public List<FileInfo> getFileList() {        return new ArrayList<>();    }
    public FileInfo upload(String path) {        //上传文件        LogUtils.log("upload file");        HttpUtils.post("http://file", userState.getUserId());        return new FileInfo();    }
    public FileInfo download(String url) {        //下载文件        if (!userState.isLogin()) {            return null;        }        return new FileInfo();    }}
 

 

2.4 提取构造函数,依赖接口注入

 

图片

图片

 

重构后代码如下:

public class FileController {    private final UserState userState;
    public FileController(UserState userState) {        this.userState = userState;    }
    public List<FileInfo> getFileList() {        return new ArrayList<>();    }
    public FileInfo upload(String path) {        //上传文件        LogUtils.log("upload file");        HttpUtils.post("http://file", userState.getUserId());        return new FileInfo();    }
    public FileInfo download(String url) {        //下载文件        if (!userState.isLogin()) {            return null;        }        return new FileInfo();    }}
 

同样FileFragment我也也做相同的构造及接口注入。

 

  1. 代码移动

     

同样使用moduraize进行移动,代码移动至独立的fileBundle,加上对应的Gradle依赖:

 

图片

 

移动后模块结构如下:

 

图片

 

  1. 功能验证

 

执行冒烟测试,验证功能

  •  
./gradlew app:testDebug --tests SmokeTesting
 

图片

每一小步重构时都可以频繁运行测试,提前发现问题

 

代码演示:mp.weixin.qq.com/s/xbAIu6bWS…

 

具体的代码:github链接

https://github.com/junbin1011/CloudDisk/commit/b69bbc8e7d5d83b0c542ada06d7157a6fb997682

 

总结

 

本篇我们按着重构的4个步骤,借助IDE的安全重构,小步的重构了library和file2个包。虽然依赖解除了,代码也移动到独立的模块里面。但是我们还是发现了一些问题。

  1. UserState接口的层层注入,我们需要手工维护了好多构造方法及对应的注入

  2. App依赖了fileBundle的Fragment,UI跳转上存在编译的依赖

 

下一篇,单体移动应用“模块化”演进之旅(8)- 依赖注入篇,我们将分享常见的注入方式及业内优秀的实践,并对DiskCloud继续进行改造优化。

 

CloudDisk示例代码

 

CloudDisk

https://github.com/junbin1011/CloudDisk

 

系列链接

 

移动应用遗留系统重构(1)- 开篇

 

移动应用遗留系统重构(2)- 架构篇

 

移动应用遗留系统重构(3)- 示例篇

 

移动应用遗留系统重构(4)- 分析篇

 

移动应用遗留系统重构(5)- 重构方法篇

 

移动应用遗留系统重构(6)- 测试篇

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值