代码重构内幕交易(Insider Trading)

网友投稿 1078 2022-05-30

什么是内幕交易(Insider Trading)

定义:模块之间互相引用,私下直接进行大量的数据访问和交换

影响:增大模块间的耦合,容易导致循环依赖,加快架构腐化,甚至会朝着大泥球式的架构发展,严重影响可维护性

改进目标:消除模块间不合理的依赖关系(特别是循环依赖),将私下的数据访问和交换放到明面上,使模块间解耦,提高可维护性

方法:搬移函数、搬移字段、隐藏委托关系、以委托取代子类/超类

案例——简化的学生选课系统

代码背景

简化的学生选课系统,主要功能包括:

添加学生信息

添加课程信息

添加学生选课信息(课程和学生之间的映射,多对多关系)

学生选课信息查询

维护了单门课程和单个学生的个人信息

两个Manager包含了多个Student和Course对象,负责学生和课程信息的添加、映射关系的创建、以及选课信息的查询,

CourseSelectionManager负责内部Manager的统一创建和管理

CourseSelectionSystemApi包含了对外提供的接口

症状/问题

不合理的继承体系常会造成“密谋”,子类直接操作父类中的属性、字段等,加重了两个模块之间的耦合

CourseSelectionSystemApi中封装的是对外暴露的接口,而CourseSelectionManager负责的是内部数据的操作和管理,二者不在一个层次,不应该直接通过继承来实现数据的访问和传递。

重构目标

消除不合理的继承体系,合理封装属性、字段、方法等,使用委托进行对象间的访问和调用

重构手法

以委托取代子类/超类

注:继承是最常见的关系之一,这里提出的问题和重构手法,仅针对的是业务上不合理的继承关系

症状/问题

模块间私下、频繁的数据交换,会导致循环依赖的产生,使软件可维护性变差,架构迅速腐化,最终演变为大泥球架构

CourseManager中引入了student包下的Student对象,StudentManager中引入了course包下的Course对象,产生了包级别的循环依赖

CourseManage方法里直接引入了StudentManager对象,而StudentManager也直接引入了CourseManager,两个类之间循环依赖

重构目标

解除循环依赖,提升可读、可维护性。通过搬移函数和字段,将属于各自模块的功能搬移到一起,减少私下的数据访问和交换;对于无法避免的依赖,可引入新的模块作为中介,将访问和交换放到明面上。

重构手法: 搬移函数、 搬移字段、 隐藏委托关系

IDEA——Analyze——AnalyzedependencyMatrixScope分析依赖矩阵

通过图形化展示内幕交易引发的循环依赖:

①为类图,可以看到Course和Student都分别与StudentManager、CourseManager有组合关系

②为package图,可以看到Course和Student在不同的package下,package间存在循环依赖

③IDEA自带的依赖关系矩阵,出现在对角线右上角的元素,即为不合理的反向依赖

改进路线

用委托取代子类/父类,消除CourseSelectionSystemApi和CourseSelectionManager之间不合理的继承关系

通过隐藏委托关系,将内部的manager隐藏起来,不对api层体现

通过转换为static(便于搬移)、搬移字段、函数等手法,将各自模块的数据尽可能移动到一起,消除模块间的循环依赖

继续通过搬移字段、搬移函数、转换为instance方法等重构手法,将student、course两个模块共同的行为搬移到新的模块中CourseSelectionManager中,消除潜在的循环依赖风险,且将student和course完全解耦

重构对比

代码重构:内幕交易(Insider Trading)

重构前

course和student模块依赖关系混乱

依赖矩阵可直观看出存在不合理的反向依赖

重构后

course和student模块解耦,无反向依赖

依赖矩阵分析依赖关系正常

相关技巧(识别工具)

IDEA——Analyze——AnalyzedependencyMatrixScope:识别代码中不合理的反向依赖关系(对角线右上角出现数字即表示模块间依赖关系存在问题),可辅助识别内幕交易等代码坏味道

进阶:对于新增或已重构“干净”的架构和分层,可以使用ArchUnit进行架构看护,以UT的形式定义并限制模块间依赖关系,避免不合理的依赖引入,降低内幕交易等由依赖关系导致的坏味道出现的风险

官方文档:https://www.archunit.org/userguide/html/000_Index.html

总结

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SAP Analytics Cloud和SAP Cloud for Customer的集成
下一篇:Java实现Excel转PDF的两种方法总结
相关文章