Day932.5个步骤,高效推动组件化架构重构 -系统重构实战

news2024/11/23 22:46:00

5个步骤,高效推动组件化架构重构

Hi,我是阿昌,今天学习记录都是关于5个步骤,高效推动组件化架构重构的内容。

项目的架构设计是一回事,代码落地又是另外一回事,很多架构设计最终都只是落在了 PPT 上

  • 一方面可能是因为后续架构腐化了,缺少守护

  • 另一方面是实际落地到代码的改造环节,它的复杂度比纸上画图高得多

重构的改造流程分为了 5 个步骤,安全、高效地进行规模化架构重构落地,并通过自动化手段来守护。

在这里插入图片描述

如上图所示,这 5 个步骤分别是设计、守护、解耦、移动和验收。


一、设计,识别内聚的组件

在如何进行组件化分析和设计?中对组件的类型进行了划分,也对 Sharing 进行了一次全景的组件梳理,把组件分成了业务组件功能组件技术组件这三类。

在这里插入图片描述

参考 UI 上的设计来划分业务组件,通常产品在设计时,都会将相对内聚的功能组织在一个页面上,便于用户使用

所以可以从页面入手,接着逐步分析这个页面所依赖的类,将这些类划分到统一的业务组件中。

功能组件通常的特点就是被多个业务组件复用,所以根据代码的依赖情况,就能判断被多处引用的功能,是否属于功能组件。

分析出被业务组件依赖的关键入口类,同时找到该类依赖的相关类,将这些类划分到统一的功能组件中。

对于技术组件,大部分的应用可能都会使用第三方提供的框架。

如果项目有自己开发的相关技术组件,可以参考功能组件的识别方式进行分析,但是需要注意技术组件与具体的业务无关,可以将其用在多个应用上。

最后需要注意,通常在第一步可能会把一些类错误划分到某些组件中,不过在后续的解除依赖中,仍然可以继续重新调整一些类的划分。


二、守护,增加自动化测试

由于在第三步需要对代码做重构调整,虽然这个过程会借助 IDE 进行安全重构,但由于代码的调整会比较大,所以在动代码之前,需要增加基本的自动化测试,以此保证重构不破坏原有的功能。

那么需要补充哪些自动化测试呢?

这个步骤有两种类型的自动化测试要补充,第一种是架构守护的自动化测试,参考运用自动化工具诊断分析Sharing项目中使用 ArchUnit 为 Sharing 覆盖架构守护测试的做法。第二种是功能的自动化测试。我们如何提升遗留系统代码的可测试性讲测试策略时,曾经给出了针对遗留系统覆盖自动化测试的策略,那就是首先考虑覆盖中大型的测试,然后进行代码重构,重构完成后再及时补充中小型的测试。


这样做有两方面原因:

  • 一是因为还未重构的遗留系统可测性很低,覆盖小型自动化测试的成本太高
  • 二来是重构后代码内部的结构会有所调整,如果先覆盖小型测试,后续的测试代码也要相应再次调整

所以一般来说,守护测试都是中大型的 UI 自动化测试,因为重构并不会改变用户对软件的使用流程。

至于如何覆盖中大型的自动化测试,参考自动化测试的内容。


三、解耦,解除异常依赖

针对 Sharing 的工程,已经按照新的包结构组织了代码。

在这里插入图片描述
但是如果要通过 Modularize 把这些代码移动到独立的模块,IDE 就会提示警告。

在这里插入图片描述

这里主要的问题就是要移动的代码依赖目前工程中的代码,只要这个依赖没有解除,就无法进行第四步的移动工作。

那么怎么来解除依赖呢?

下面四种常用的解除依赖方式,分别是类下沉、依赖接口、事件总线和路由。


1、类下沉

类下沉指的是将依赖的类移动到公共的功能组件或者技术组件中。

这个解除依赖的手法适用于业务组件依赖的类属于公共的组件。

操作步骤也比较简单,分别是:

  • 将具体类移动到适当的公共组件中。
  • 调用组件增加对该公共组件的依赖。

由于文件模块依赖了 LogUtils,所以在将文件模块移动到独立的业务组件之前,需要将 LogUtils 及 NetUtil 等类移动到独立的技术组件中。

在这里插入图片描述

在项目中需要注意,对于挪动至功能或者技术组件的代码需要严格审核,避免为了解耦强行将一些属于业务组件的类移动到下层的组件中,导致业务组件在下层组件中产生耦合。


2、依赖接口

依赖接口是指 将原先直接依赖具体的实现,解耦成依赖稳定的抽象接口。

这个解除依赖的手法适用于业务组件之间的依赖。

可以将业务组件的直接依赖重构为依赖抽象的接口,这个接口下沉到基座中,具体的实现还是留在各自的业务组件中,后面是操作步骤。

  1. 提取独立的方法。
  2. 将方法移动到独立的类中。
  3. 提取接口,将调用类调整为调用接口。
  4. 注入具体的实现。

六种遗留系统常用的安全重构手法演示过如何提取接口。

这里结合当时的示例和操作动图,再复习一下。

重构前的代码是这样:

public void show() {
    String url = "http://XXX";
    Bitmap bitmap = new Picasso().load(url);
    showImage(bitmap);
}

操作动图是后面这样。

在这里插入图片描述

重构后的代码是这样。

private IImageLoader imageLoader;
public void show() {
    String url = "http://XXX";
    Bitmap bitmap = imageLoader.getBitmap(url);
    showImage(bitmap);
}

在项目中需要注意保持接口的稳定,如果接口频繁修改,那就意味着所有依赖这个接口的业务组件也要同步修改,这样就和依赖具体的实现没有区别了。


3、事件总线

事件总线指的是 通过进行统一消息管理,发布者发布消息后,接受者可以通过订阅消息来获取数据。这个解除依赖的手法同样适用于业务组件之间有行为或数据监听的场景。例如,当个人中心修改用户信息成功以后,需要在消息模块能同步显示。

这时候建议采用成熟的事件总线管理框架来管理,比如 EventBus,具体的操作步骤是这样:

  1. 定义事件。
  2. 发送者发送对应的事件。
  3. 接受者订阅事件执行相应的逻辑。
  4. 及时移除不需要的事件监听。

结合上面个人中心修改信息同步的例子,我们首先可以定义同步的事件,代码是后面这样。

class UpdateUserInfo{
    private UserInfo userInfo;
    public UpdateUserInfo(UserInfo userInfo) {
        this.userInfo = userInfo;
    }
    public UserInfo getUserInfo() {
        return userInfo;
    }
}

接着,在个人中心修改用户信息成功后发生对应的事件。

EventBus.getDefault().post(new UpdateUserInfo(new UserInfo()));

然后在消息模块中定义事件的接收,并注册相关的监听,同时移除监听。

//注册
EventBus.getDefault().register(this);
//监听
@Subscribe(threadMode = ThreadMode.MAIN)
public void userInfoUpdateEventBus(UserInfo userInfo){
  //刷新相关的数据及页面展示
}
//移除监听
EventBus.getDefault().unregister(this);

事件总线与依赖接口一样,需要保持事件模型的稳定性,如果事件模型被频繁修改,那么所有监听事件的组件也要同步修改。


4、路由

路由是指代通过统一的路由来管理页面的 URL 及页面跳转。这个解除依赖的手法适用于解除业务组件页面的路由跳转这类场景。

目前,可以采用业内成熟的路由框架方案来进行管理,如 ARouter、WMRotuer 等框架。操作步骤是这样:首先我们要在跳转类中定义对应的映射路径。然后,在调用处使用对应的路径进行跳转。

下面来看一个使用 ARouter 定义的页面跳转示例。

//没有使用路由
fragments.add(FileFragment.newInstance());
 
//使用路由

//声明
@Route(path = "/feature/file")
public class FileFragment extends Fragment
//调用
fragments.add((Fragment) ARouter.getInstance().build("/feature/file").navigation();

最后,可以通过运行架构守护用例或者使用 Dependencies 功能,判断是否已经解除了所有的异常依赖。

如果所有的依赖都解除了,接下来进行第 4 步移动时,就不会出现带下划线的提示了。


四、移动,移动代码及资源

完成依赖解耦后,就可以使用 Modularize 来将整个包移动到独立的模块中去。


五、验收:解耦验收

最后一步是对完成解耦的组件进行验收,这里要满足三个基本的验收条件。

  • 编译通过,能够打包出安装包。
  • 架构守护用例执行通过。
  • 验收自动化测试执行通过。

当这三个条件都满足时,可以再进行基本的人工探索性测试,如果没有发现异常,就可以将代码提交入库审核了。


六、总结

组件化架构重构的流程,包含设计、守护、解耦、移动以及验收 5 个步骤。

其中,解耦是整个代码落地的关键步骤,提供了 4 种常用的解除依赖的方法。

下面将这 4 种方法的定义、使用场景及注意事项总结一下。

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/418168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT Graphics View坐标系转换

背景 在做绘图处理时,Scence作为场景,大小是无限的,而View作为一个观察镜头,观察范围是有限的。 那么有限的View观察无限的Scence区域,必然要选定一个观测锚点。 所以View具有一个centerOn(QPointF pos)函数&#xff…

Linux-初学者系列——篇幅1_文件管理命令(持续更新中)

Linux-初学者系列_篇幅1 文件管理命令-目录Linux-初学者系列_篇幅11.创建文件语法:示例:2.创建目录语法:示例:注意:常见错误:3.复制语法:示例:补充:4.移动语法&#xff1…

Vue|数据渲染

Vue 是如何将编译器中的代码转换为页面真实元素的?在Vue 中,自带了模板渲染,而模板的语法也非常简洁易懂。 精彩专栏持续更新↓↓↓ 微信小程序实战开发专栏 一. 数据渲染1.1 条件渲染v-ifv-show1.2 列表渲染v-for1.3 小结一. 数据渲染 1.1 条件渲染 vue条件渲染指…

3. 500 服务器异常 html

目录 1.效果图 2.code 1.效果图 2.code <!DOCTYPE html> <html><head><meta charset="utf-8"><title>500</title><style type="text/css">html,body {margin: 0;padding: 0;height: 100%;min-height: 450px;…

Git --- 常用命令、分支操作、团队协作机制

一、Git 概述 Git 是一个免费的、开源的分布式版本控制系统&#xff0c;可以快速高效地处理从小型到大型的各种项目 Git 易于学习&#xff0c;占地面积小&#xff0c;性能极快。它具有廉价的本地库&#xff0c;方便的暂存区域和多个工作流分支等特性 其性能优于 Subversion、…

多通道振弦传感器无线采集仪与参数配置工具连接

多通道振弦传感器无线采集仪与参数配置工具连接 VS101~VS432 设备配备了专门的参数配置工具 SETP 来完成设备工作参数的查看和修改工作。 连接前的准备工作 &#xff08; 1&#xff09;数据接口与计算机连接 使用标配的通讯线与计算机 RS232 接口连接。 若需基于手机网络发送数…

Java-异常机制

异常机制 正常情况下&#xff0c;程序按照我们希望的样子和步骤去执行&#xff0c;但是&#xff0c;代码就像人生&#xff0c;要是一帆风顺了&#xff0c;就要想想是不是哪里出事了。程序若是有报错还好&#xff0c;就怕没有报错。 实例 public class Test {public static vo…

如何用 YonBuilder 构建线索管理应用

加速企业数智营销&#xff1a;如何用 YonBuilder 构建线索管理应用 如何用 YonBuilder 低代码开发线索管理应用&#xff1f; 线索管理是指通过各种渠道收集、筛选、打分、分配、跟进和培育潜在客户的信息&#xff0c;以便将其转化为成交客户的过程。 通过数智化手段实现良好…

ArcGIS地质图矢量化技巧

01 概述 今天以ArcGIS为例&#xff0c;结合多年的工作经验&#xff0c;来介绍一下地质图矢量化的技巧。 02 底图的配准 不同比例尺的图件&#xff0c;有着不同的配准精度要求&#xff1a; 1&#xff1a;20万的地质图&#xff0c;配准误差不能高于20米&#xff1b; 1:50万…

DFIG控制9: 搭建定子αβ坐标系下的电机模型

DFIG控制9&#xff1a; 搭建定子αβ坐标系下的电机模型。本文基于教程的第9部分&#xff08;终于做完了&#xff09;。主要目的是自己搭建一个DFIG的电机模型&#xff0c;与Simulink库中的模型做个对比。 本文基于教程的第9部分&#xff1a; DFIM Tutorial 9 - Analytical Mod…

Focal Loss论文解读和调参教程

论文&#xff1a;Focal Loss for Dense Object Detection 论文papar地址&#xff1a;ICCV 2017 Open Access Repository 在各个主流深度学习框架里基本都有实现&#xff0c;本文会以mmcv里的focal loss实现为例&#xff08;基于pytorch&#xff09; 简介&#xff1a; 本文是…

1.mybatis-plus入门及使用

1.什么是MybatisPlus MyBatis-Plus 官网 为什么要学MybatisPlus&#xff1f; MybatisPlus可以节省大量时间&#xff0c;所有的CRUD代码都可以自动化完成MyBatis-Plus是一个MyBatis的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效…

Java——数组中出现次数超过一半的数字

题目链接 牛客在线oj题——数组中出现次数超过一半的数字 题目描述 给一个长度为 n 的数组&#xff0c;数组中有一个数字出现的次数超过数组长度的一半&#xff0c;请找出这个数字。 例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次&#xff0c;…

FastDFS与Nginx结合搭建文件服务器,并内网穿透实现公网访问

文章目录前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.1 …

低代码开发重要工具:jvs-flow (流程引擎)2.1.7版本更新内容

流程引擎主要包含了流程定义和编辑、任务分配和处理、流程监控和跟踪、数据模型和存储、条件和规则设置、安全性和权限管理、性能优化以及持续集成和部署等功能&#xff0c;以满足不同业务场景下的需求。 JVS流程引擎从V2版本开始&#xff0c;由flowable切换为 jvs-flow&#…

2023 年 五 大数据恢复软件帮助您找回数据

您是否刚刚丢失了一份需要数天工作才能更换的重要文件&#xff1f;不要恐慌&#xff01;此列表中排名前 10 位的最佳数据恢复软件应用程序可以帮助您找回数据&#xff0c;您甚至可能不必在它们上花任何钱。 五大最佳数据恢复软件工具 以下是我们最喜欢的 10 大数据恢复软件应用…

记录-vue项目中使用PWA

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言&#xff1a; 梳理了一下项目中的PWA的相关用法&#xff0c;下面我会正对vue2和vue3的用法进行一些教程示例&#xff0c;引入离线缓存机制&#xff0c;即使你断网&#xff0c;也能访问页面。一旦用…

动力节点王鹤SpringBoot3笔记——第八章 文章管理模块

目录 第八章 文章管理模块 8.1 配置文件 8.2 视图文件 8.3 Java代码 第八章 文章管理模块 创建新的Spring Boot项目&#xff0c;综合运用视频中的知识点&#xff0c;做一个文章管理的后台应用。 新的Spring Boot项目Lession20-BlogAdmin。Maven构建工具&#xff0c;包…

VxLAN数据中心L2互连(hand-off方式)

用Arista的veos做了个DCI&#xff08;hand-off&#xff09;实验。模拟了VxLAN数据中心hand-off方式做L2互通。 在此分享。 实现思路 分别在DC1、DC2内配置BGP EVPN协议创建VXLAN隧道&#xff0c;实现各数据中心内部VM之间的通信&#xff0c;DC1-BL和DC2-BL通过二层接口方式接…

spring事务(注解 @Transactional )失效场景

目录标题1. 代理不生效1.1 将注解标注在接口方法上1.2 被final、static关键字修饰的类或方法1.3 类方法内部调用示例解决方案&#xff1a;新加一个Service方法1.4 (类本身) 未被spring管理2. 框架或底层不支持的功能2.1 非public修饰的方法2.2 多线程调用举例1举例22.3 数据库本…