自动化依赖分析

依赖分析以后,你的架构还好吗?前端

在过去的几周里,我一直在作一些重构相关的工做,也尝试着去作这方面的自动化。因而乎,就有了上一篇文章:《重构的自动化》。在这个过程当中,有一个环节能反应出架构是否有良好的设计,那就是依赖。java

640?wx_fmt=jpeg

依赖的类型

对于一个系统来讲,它存在下述的一些依赖类型:webpack

  • 类、包依赖git

  • 第三方依赖github

  • 服务间依赖web

按《架构金字塔》一文所说,它们各属于不一样层级。设定好它们间的组织方式,决定了整个系统架构的良好性。数据库

  • 类、包依赖。经过职责来聚合服务,单一化类的职责。后端

  • 第三方依赖。经过 Adapter 模式封装三方依赖,隔离外部依赖的变化;还能够经过 Facde 模式来简化 API 的调用。网络

  • 服务间依赖。相似于第三方依赖,只是在接口统一不变时,是 Proxy 模式架构

在架构的维度里,咱们经过 MVC 架构、Clean Architecture 等不一样的方式,进行分层架构的设计,以经过明确地职责划分、隔离关注点,来下降系统的维护成本。若是水平维度不能解决问题,那么就采用水平 + 垂直化的方式来解决。在依赖维度里,咱们经过度量来观察设计的合理性。

类包依赖:依赖关系可视化

对于类和包的依赖来讲,一个有效的解决方案是:对于依赖关系的可视化。以下图(由 tequila + graphviz 生成):

640?wx_fmt=png

在图中,咱们能够看出类间的依赖关系,从而进一步分析他们的引用问题。虽然,对于采用分层架构的应用来讲,这样的问题并不容易出现。可是,咱们仍在必定的范围内,看到了 service 间的相互调用。

因而,在参考了公司大佬的开源依赖分析项目:

  • 基于 Antlr 进行 Java 依赖分析 https://github.com/XuefengWu/dependence_java

  • 基于 Doxygen 进行多种语言的依赖分析 https://github.com/newlee/tequila

随之然后,我便也着手作了一个相关的 Java 依赖分析工具:https://github.com/phodal/coca 。固然在那以前,我已经有了一个 TypeScript 的版本:https://github.com/phodal/dilay ,只不过目的不同,个人初衷是用于作架构守护。

对于这样的一个工具说,咱们所要做的事情也不复杂:

  • 编写特定语言的抽象语法树(AST)和 parser

  • 构建出每一个类包含的全部声明,生成对应的映射

  • 识别出依赖相关的 method、type、class、constant 的使用

  • 生成对应的调用关系

  • 可视化调用关系

一旦出现服务间的双向/循环引用,咱们须要着力于关注如何去掉这种错误的引用。去掉的方式有多种多样,诸如于:合并包/服务、提取共用部分。

第三方:包大小可视化

包大小,在出现性能或者网络问题以前,并不会成为咱们关注的焦点。可一旦包的大小超过了预期,咱们开始分析其中的缘由。可视化,依然是解决这一类问题的最有效方式。

对于诸如 JavaScript/TypeScript 这一类的静态语言来讲,它们引用包的方式与其它语言有很大的差距。前端领域的引用方式,多数以源码的方式,而诸如 Java 则是以 jar 包的方式。因而,前端应用在构建的时候,前端能够经过摇树优化来减小包大小。可是哪怕如此,必定数量的软件包只能引用所有的代码,这种模式一般出如今前端 UI 库中,如 Ant Design。

对于这些问题来讲,前端有一个解决方案:webpack-bundle-analyzer,它能够直接可视化软件包的大小:'

640?wx_fmt=png'

固然了,对于后端来讲,这也不是问题。只是对于我来讲,我仍然在考虑是否有必要去作这样的事。不过呢,若是你引用了一个本身内部的软件包,那么咱们有必要写一个软件来作这样的优化:

  1. 构建时识别软件引用的类与方法

  2. 依赖识别的类,将软件包不须要的部分自动去除

  3. 从新打包依赖软件包

  4. 构建整个应用

O 了。

服务间:API 规范化与服务间依赖

不过,这个故事还涉及到一个 API 规范化的问题。因此在那以前,咱们须要:

  1. 经过扫描代码来寻找对外暴露的 API。生成对应的 API 与参数关系列表

有了这个基本的的结果后,断定每一个 API 的设计是否合理。与此同时,咱们还能够:*经过调用关系,找到 API 对应的数据库表,生成相应的 Schema。*

随后,再:

  1. 扫描调用的 API。生成调用服务的关系图

  2. 分析服务调用关系,及其调用是否合理。

它能够固定做为咱们测试的一部分。

第三方依赖:依赖功能分析

TBD

这部分的内容,主要指的是依赖间的功能重复,如各种 Util,像 FileUtils,TimeUtils 诸如此类。'

结论

你呢,有什么建议?