> For the complete documentation index, see [llms.txt](https://code-visualization.shawnxie.top/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://code-visualization.shawnxie.top/di-yi-pian-dai-ma-ke-shi-hua-de-mu-biao-yu-bian-jie/what-to-visualize.md).

# 代码可视化到底可视化什么

很多人第一次接触代码可视化，会自然想到类图、调用图、依赖图、控制流图、火焰图。这些图当然重要，但如果只从图表类型出发，很容易陷入一个误区：好像代码可视化就是为代码选择一种图形表达。

更准确的理解应该是：代码可视化可视化的不是代码文本，而是代码背后的事实。这些事实包括结构、关系、行为、演进和组织上下文。图只是表达这些事实的一种方式，查询、报告、矩阵、列表和路径解释也同样属于代码理解系统的一部分。

本章先把“代码里到底有哪些可视化对象”拆开，为后续的程序分析和代码图谱建模打基础。

## 结构：代码由哪些实体组成

结构是代码可视化最基础的一层。没有结构化实体，后续就无法谈调用、依赖、影响面和验证。

常见结构实体包括：

* 仓库、项目、模块、包和目录。
* 文件、类、接口、结构体、枚举。
* 函数、方法、构造函数、匿名函数。
* 字段、变量、常量、参数。
* 注解、装饰器、配置项、路由声明。
* 测试文件、测试用例、测试套件。

这些实体看起来简单，但它们决定了代码系统的基本索引方式。比如一个影响面分析系统要从 Git Diff 定位到“变更了哪个方法”，就必须先知道文件、类、方法的结构边界。一个 Agent 上下文系统要给 AI 提供相关文件，也必须知道哪些文件属于同一模块，哪些方法属于同一调用路径。

结构可视化不一定要画复杂的图。目录树、模块树、符号列表、代码大纲都属于结构表达。它们解决的问题是：这个代码库里有什么。

## 关系：实体之间如何连接

代码真正的复杂性来自关系。一个函数本身可能很短，但它所在的关系网络可能很复杂。

常见关系包括：

* 包含关系：仓库包含模块，模块包含文件，文件包含类，类包含方法。
* 调用关系：方法调用方法，服务调用服务。
* 依赖关系：模块依赖模块，包依赖包，服务依赖数据库、缓存、队列或外部 API。
* 引用关系：变量、函数、类、配置项在哪里被使用。
* 继承和实现关系：类继承类，类实现接口。
* 读写关系：代码读写哪些表、字段、文件、缓存 key 或消息 topic。
* 覆盖关系：测试覆盖哪些类、方法和路径。
* 拥有关系：模块、服务或文件归属哪个团队或 owner。

关系可视化最常见的形式是图。节点代表实体，边代表关系。但实际工程中不能把所有关系都画进一张图。一个有用的视图必须服务一个具体问题：查调用链时看调用关系，治理架构时看依赖关系，做数据安全审查时看数据流关系，做测试选择时看覆盖关系。

关系层解决的问题是：这些代码事实如何互相影响。

## 行为：代码如何执行

结构和关系大多可以从静态代码中提取，但软件系统最终要运行。运行时行为经常和静态结构不完全一致，尤其是在使用框架、依赖注入、动态代理、异步任务和微服务调用的系统中。

行为层关注的是代码在真实执行时发生了什么：

* 请求经过哪些服务和方法。
* 哪些分支被执行，哪些分支从未触达。
* 哪些调用耗时最高。
* 哪些异常路径频繁出现。
* 哪些数据库查询、缓存访问和外部 API 调用出现在关键路径上。
* 哪些测试真正覆盖了某段代码。

行为数据通常来自日志、Trace、Profile、Coverage、APM 和线上指标。它和静态分析互补：静态分析告诉我们“可能发生什么”，动态分析告诉我们“实际发生过什么”。

比如静态调用图可能显示某个方法有多个调用方，但运行时 Trace 可能表明只有其中一条路径是核心流量路径。做性能优化时，静态结构并不能说明热点，Profile 和 Trace 才能提供证据。

行为层解决的问题是：代码在真实系统中如何运行。

## 演进：系统如何变化

代码库不是一次性写完的，它在持续演进。理解当前代码结构还不够，我们还需要理解它为什么变成这样。

演进数据包括：

* Git Diff：一次变更具体改了哪些文件、类和方法。
* Commit：历史上谁在什么时候改了什么。
* PR：变更讨论、Review 意见、测试结果。
* Issue 或缺陷记录：某段代码与哪些问题有关。
* 变更频率：哪些文件或模块长期频繁变动。
* 变更耦合：哪些文件经常一起被修改。
* 测试历史：哪些测试经常失败，哪些变更容易引发回归。

演进数据能揭示静态结构看不出来的风险。一个文件当前复杂度不高，但如果它每周都被多个团队修改，它仍然是协作风险点。两个模块在结构上没有明显依赖，但如果历史上总是一起变更，说明它们可能存在隐性耦合。

在 AI 时代，演进数据也很关键。Agent 不能只看当前文件内容，还应该知道这段代码的历史变更、相关 PR、常见失败测试和代码 owner。否则它很容易做出局部正确、系统不稳的修改。

演进层解决的问题是：系统是如何变化到今天的。

## 组织：谁负责这些代码

软件不是只有代码，还有团队、职责和流程。很多工程问题无法只从语法层面判断。

组织上下文包括：

* 代码 owner。
* 模块负责团队。
* 服务等级和业务优先级。
* 架构边界和分层规则。
* 发布流程和审批要求。
* 关键路径和核心业务域。

比如一个公共鉴权模块和一个后台报表模块，即使代码行数相似，变更风险也完全不同。一个跨团队共享服务，即使调用关系不复杂，也需要更严格的 Review 和测试。

组织信息让代码可视化从“技术结构图”变成“工程决策图”。它能回答：这个改动应该找谁 Review，哪些模块不能直接依赖，哪些服务属于核心链路，哪些代码需要更高验证等级。

## 从可视化对象到代码图谱

当我们把结构、关系、行为、演进和组织信息放在一起时，就可以得到一个代码图谱。

一个简化的代码图谱可以这样理解：

* 节点：文件、类、方法、服务、接口、测试、团队。
* 边：包含、调用、依赖、覆盖、变更、拥有。
* 属性：复杂度、覆盖率、耗时、错误率、变更频率、风险等级。

代码图谱不是为了替代所有工具，而是提供一个统一的事实层。IDE 可以用它导航，CI 可以用它推荐测试，PR Review 可以用它解释影响面，AI Agent 可以用它查询上下文。

这也是本书后续章节的核心：先学习如何从源码和运行时系统中提取事实，再学习如何把这些事实建模成图谱，最后学习如何让人和 AI 使用这些事实。

## 小结

代码可视化真正要表达的是代码系统中的事实，而不只是代码文本。结构告诉我们系统里有什么，关系告诉我们它们如何连接，行为告诉我们运行时发生了什么，演进告诉我们系统如何变化，组织上下文告诉我们这些变化如何影响工程决策。

如果只画图而不理解这些事实，代码可视化很容易变成展示工具。如果能把这些事实结构化、查询化、证据化，它就会成为软件理解系统的基础。
