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

举报
孙小北 发表于 2022/04/29 23:51:15 2022/04/29
【摘要】 什么是内幕交易(Insider Trading)定义:模块之间互相引用,私下直接进行大量的数据访问和交换影响:增大模块间的耦合,容易导致循环依赖,加快架构腐化,甚至会朝着大泥球式的架构发展,严重影响可维护性改进目标:消除模块间不合理的依赖关系(特别是循环依赖),将私下的数据访问和交换放到明面上,使模块间解耦,提高可维护性方法:搬移函数、搬移字段、隐藏委托关系、以委托取代子类/超类 案例——...

什么是内幕交易(Insider Trading)

  • 定义:模块之间互相引用,私下直接进行大量的数据访问和交换
  • 影响:增大模块间的耦合,容易导致循环依赖,加快架构腐化,甚至会朝着大泥球式的架构发展,严重影响可维护性
  • 改进目标:消除模块间不合理的依赖关系(特别是循环依赖),将私下的数据访问和交换放到明面上,使模块间解耦,提高可维护性
  • 方法:搬移函数、搬移字段、隐藏委托关系、以委托取代子类/超类

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

代码背景

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

  • 添加学生信息

  • 添加课程信息

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

  • 学生选课信息查询

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

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

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

  • CourseSelectionSystemApi包含了对外提供的接口

image-20220429202532634.png

症状/问题

  • 不合理的继承体系常会造成“密谋”,子类直接操作父类中的属性、字段等,加重了两个模块之间的耦合
  • CourseSelectionSystemApi中封装的是对外暴露的接口,而CourseSelectionManager负责的是内部数据的操作和管理,二者不在一个层次,不应该直接通过继承来实现数据的访问和传递。

重构目标

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

重构手法

  • 以委托取代子类/超类
  • 注:继承是最常见的关系之一,这里提出的问题和重构手法,仅针对的是业务上不合理的继承关系

image-20220429202722565.png

症状/问题

  • 模块间私下、频繁的数据交换,会导致循环依赖的产生,使软件可维护性变差,架构迅速腐化,最终演变为大泥球架构
  • CourseManager中引入了student包下的Student对象,StudentManager中引入了course包下的Course对象,产生了包级别的循环依赖
  • CourseManage方法里直接引入了StudentManager对象,而StudentManager也直接引入了CourseManager,两个类之间循环依赖

重构目标

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

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

image-20220429203156279.png

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

  • 通过图形化展示内幕交易引发的循环依赖:
    ①为类图,可以看到Course和Student都分别与StudentManager、CourseManager有组合关系
    ②为package图,可以看到Course和Student在不同的package下,package间存在循环依赖
    ③IDEA自带的依赖关系矩阵,出现在对角线右上角的元素,即为不合理的反向依赖

image-20220429203253786.png

改进路线

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

image-20220429203345141.png

  • 通过隐藏委托关系,将内部的manager隐藏起来,不对api层体现
    image-20220429203359807.png

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

image-20220429203440265.png

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

image-20220429211638703.png

重构对比

image-20220429211729403.png

重构前

  • course和student模块依赖关系混乱
  • 依赖矩阵可直观看出存在不合理的反向依赖

重构后

  • course和student模块解耦,无反向依赖
  • 依赖矩阵分析依赖关系正常

相关技巧(识别工具)

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

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

总结

image-20220429211950949.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。