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

本文详细介绍了如何通过识别内聚包、解除异常依赖、移动代码和资源以及进行功能验证,来重构mobile应用中的library和file模块。通过安全重构手法,如提取方法参数、抽取接口和依赖注入,实现了模块的解耦。同时,通过录制的视频展示了重构过程,并提供了代码演示和GitHub链接以供参考。最后,文中指出了重构后存在的问题,为后续的依赖注入优化埋下伏笔。
摘要由CSDN通过智能技术生成

前言

 

移动应用遗留系统重构(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
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值