智汇 IT
城启新篇

代码评审中的架构一致性检查别只盯着命名规范

上周翻一个合并请求。七十多行。改的是优惠券过期提醒。看起来很干净,测试也过了。

但点开 diff,我停住了。促销服务里直接 import 了用户服务的数据库客户端。不是 RPC,不是事件,是 JDBC。那一瞬间,脑子里只有一句话:这玩意儿怎么进来的。

这就是代码评审中的架构一致性检查最尴尬的地方。命名、格式、单测覆盖率,工具都能告诉你。架构一致性?工具经常沉默。人又容易吵起来。

说实话,很多团队把架构评审做成了风格评审。缩进几个空格,变量用驼峰还是下划线,日志有没有打 requestId。这些当然有用。但它们不是架构一致性。

架构一致性检查盯的是边界、方向和所有权。代码写得再漂亮,如果依赖方向反了,后面就是拆不完的雷。

微服务代码评审依赖方向违规示意图
微服务代码评审依赖方向违规示意图

依赖方向乱了 后面全是债

依赖方向乱了 后面全是债
依赖方向乱了 后面全是债

先看依赖方向。别急着夸设计模式。一个类命名成 Strategy,内部却直接 new 了一个具体实现,还连到外部服务,这叫策略模式吗?这叫换皮。

依赖方向有一个硬规则:稳定层不依赖易变层,领域层不依赖基础设施层。说白了,业务规则别去 import 框架的注解、数据库的客户端、消息队列的 SDK。反过来可以。基础设施实现领域接口。领域不知道外面是谁。

麻烦在于,很多代码评审只盯着当前文件。评审人看不到 module 边界。Java 里一个 import,Python 里一个 from,Go 里一个包引用,就把边界打穿了。工具不拦,人也不一定懂。最后 merge 进去。半年后想拆服务,才发现订单模块里塞满了用户表字段。

我见过一个不算复杂的改动。订单服务要展示用户昵称。最省事的办法:订单服务直接 join 用户库。评审时有人说,先上吧,后面再优化。听起来合理。对吧?结果用户服务后来按区域分库。订单查询全挂。不是说分库一定发生,而是这个选择把未来的迁移成本提前锁死了。

代价从来不是当天的构建失败。代价是耦合。是数据所有权模糊。是权限、审计、备份策略互相打架。

分层不是画在PPT上 得落在 import 里

分层不是画在PPT上 得落在 import 里
分层不是画在PPT上 得落在 import 里

分层架构图每个团队都有一张。Controller、Service、Repository,整整齐齐。落到代码里,常见的走样是这样:Controller 里拼业务条件,Service 里写 SQL,Repository 里调外部 API,工具类里藏缓存和事务。

代码评审中的架构一致性检查,得看几个具体信号。

事务边界在哪儿。Controller 开事务,基本是灾难。Repository 开事务,也怪。通常应该在应用服务层,一个用例一个事务。别让数据库连接跨 RPC 调用。

业务规则在哪儿。如果校验逻辑散在 Controller、DTO、前端、数据库约束里,后面改一个规则要翻五个地方。这不是架构一致性,这是架构碎片化。

数据所有权在哪儿。谁写这张表,谁负责这个聚合。别的模块只能读,或者通过接口、事件拿数据。禁止跨模块写表。跨服务写库,更得拦。这里没有模糊空间。

不过话说回来,规则太硬也会出事。小团队就三个人,非要上六边形架构、事件溯源、CQRS,评审会变成表演。我的看法:硬线要少,但硬线必须能自动检查。软线可以讨论,可以欠债,但得记下来。

评审人不是架构警察 但要有几根硬线

评审人不是架构警察 但要有几根硬线
评审人不是架构警察 但要有几根硬线

很多架构一致性讨论最后都变成吵架。一边说你不懂业务速度,一边说你在制造泥球。两边都有道理。问题出在检查方式太靠个人经验。

更可操作的做法:把检查项分成三类。

机器能查的,交给工具。依赖方向、包循环、跨模块 import、禁止直接访问其他服务数据库。这些交给 ArchUnit、dependency-cruiser、import-linter 之类的工具。评审人不用每次当人肉编译器。CI 红了就改。省事。

有明确决策记录的,必须看 ADR,也就是架构决策记录。引入新中间件、新数据库、新通信协议、新共享库。评审时没有记录?打回。不是官僚,是防止三个月后没人知道为什么这么选。

剩下依赖上下文的,评审人得问。要不要复用现有扩展点,还是新开一条链路。异常处理策略是否统一。配置是走 feature flag 还是硬编码。这些没法完全自动化。但别用“我觉得不好”这种话。要落到场景:这个改动三个月后谁维护?如果流量翻十倍,哪一段先崩?

有人会问,这样评审会不会太慢。会。但慢在关键路径上,比快在错误方向上划算。代码评审不是投票。架构一致性也不是追求人人满意。

自动化能拦住一半 剩下靠人吵架

工具能解决很多。真的。包依赖分析、循环检查、API 兼容性、数据库迁移脚本审查,这些已经成熟。问题在于,工具只能定义你告诉它的规则。团队如果没想清楚什么是允许的,工具也帮不了。

所以代码评审中的架构一致性检查,前置动作是写清楚几条不可协商的规则。比如:服务之间不能共享数据库。比如:领域层不能依赖框架注解。比如:跨模块调用必须走公开接口。写少一点,写狠一点。

然后给例外留通道。例外不是后门。例外要有截止日期、负责人、偿还计划。否则所谓技术债,就是一句自我安慰。

最后说个观察。评审里最容易放过的,往往不是复杂设计,而是“就这一次”。就这一次直接查库。就这一次在 Controller 写业务。就这一次绕过扩展点。架构腐蚀很少来自大重构。它来自无数次小方便。

下次评审,别只盯着命名规范。先看依赖方向。再看分层边界。然后问一句:这个改动,把未来的哪条路堵死了?

免责声明:市场有风险,选择需谨慎!此文仅供参考,不作买卖依据。如有侵权请联系删除。
文章名称:代码评审中的架构一致性检查别只盯着命名规范
文章链接:https://www.itcdj.com/news/851.html