跳到主要内容

如何做架构治理并避免过度设计

问题

随着团队和系统规模增长,如何保持架构一致性、控制技术债和依赖风险,同时避免架构委员会成为交付瓶颈,或者为了未来可能的需求过度设计?

面试速答版

我理解的架构治理不是集中审批,而是把关键约束变成团队默认遵守的 Guardrails

  • 少量稳定原则定义方向,例如单向依赖、契约优先、默认可观测;
  • 领域边界和负责人明确“谁可以依赖谁、谁对演进负责”;
  • 重要且难逆的决策写 ADR,普通可逆选择留给团队;
  • 能自动检查的规则做成适应度函数,进入 Lint、测试和 CI;
  • 技术雷达、依赖生命周期和例外机制管理长期演进;
  • 通过交付流、故障、变更成本和边界违规衡量治理效果。

避免过度设计的原则是:为当前明确约束设计,为可观察的变化保留演进点,不为想象中的规模提前支付全部复杂度。

一、架构治理要解决什么问题

  • 模块边界持续被穿透,修改一个功能影响多个系统;
  • 同类问题出现多套框架、协议和基础组件;
  • 关键决策只存在于少数人的记忆;
  • 依赖升级、下线和安全漏洞无人负责;
  • 团队为了统一而增加大量审批,交付反而更慢;
  • 提前设计了复杂平台,但真实需求和采用率不足。

治理目标不是让所有项目一模一样,而是降低不可控差异高成本决策

二、治理分层

1. 架构原则

原则要少、稳定、能指导取舍,例如:

  • 业务模块只通过公开契约协作;
  • 服务端状态与客户端 UI 状态分离;
  • 外部输入在边界校验;
  • 新能力默认带日志、指标和回滚路径;
  • 优先选择团队能长期维护的简单方案。

“统一使用 React”属于技术标准,不是架构原则;“所有模块低耦合”太空泛,无法指导具体决策。

2. 领域和依赖边界

为模块定义:

  • 业务职责和明确非职责;
  • 公开 API、事件或数据契约;
  • 允许的依赖方向;
  • 数据所有者和变更负责人;
  • 版本兼容与废弃策略。

3. ADR

只记录影响广、难回滚或有重要权衡的决策:

0007-client-data-cache.md
# 客户端服务端状态统一使用 Query Cache

## 状态
Accepted

## 背景
当前三个业务模块分别维护请求、缓存和重试逻辑,行为不一致。

## 决策
新模块统一通过 Data Access 层使用 Query Cache;局部 UI 状态不进入该缓存。

## 备选方案
- 继续由各模块自行实现
- 全部状态统一进入全局 Store

## 后果
- 正向:统一失效、重试和 DevTools
- 负向:需要迁移、培训和 SSR 约束

## 复核条件
当包体积、SSR 或非 React 客户端成为主要约束时重新评估。

ADR 是当时上下文中的决策记录,不是永久命令。被替代时保留历史并链接新 ADR。

4. 适应度函数

可以自动验证的架构约束应进入工具链:

architecture.test.ts
import { describe, expect, it } from 'vitest';
import { collectImports } from './architecture-helpers';

describe('模块依赖边界', () => {
it('领域层不能依赖页面和基础设施实现', async () => {
const imports = await collectImports('src/domain');
const violations = imports.filter(item =>
item.target.includes('/pages/') || item.target.includes('/infrastructure/'),
);

expect(violations).toEqual([]);
});
});

其他适合自动化的约束:

  • 包体积和性能预算;
  • 循环依赖、跨层导入、重复依赖;
  • API Schema 兼容;
  • 安全 Header、许可证和依赖风险;
  • 关键组件无障碍规则;
  • 新模块必须注册负责人和监控。

5. 技术生命周期

技术雷达可分为 Adopt、Trial、Assess、Hold,并回答:

  • 允许使用的范围;
  • 试点负责人和验证指标;
  • 是否允许进入核心链路;
  • 退出或替换条件;
  • 谁负责升级、安全和文档。

三、什么决策需要治理

可以用“影响范围 × 可逆性”判断:

决策影响范围可逆性治理方式
局部工具函数团队自行决定
页面状态库团队评审、参考标准方案
跨团队组件契约ADR + 相关方评审
身份、权限、数据模型架构评审 + 安全评审
全公司构建平台极大PoC、阶段门和退出指标

治理精力应集中在难逆且影响大的决策上。

四、避免架构评审成为瓶颈

  • 提供推荐路径和模板,常规方案自助通过;
  • 只有触发条件出现时才升级评审;
  • 评审关注问题、约束和取舍,不做代码风格争论;
  • 评审者给出时限和明确结论;
  • 可逆方案允许先做小规模实验;
  • 决策记录公开,避免不同团队重复讨论。

五、如何识别过度设计

常见信号:

  • 为没有明确时间和规模的数据预建复杂扩展能力;
  • 没有第二个消费者就抽象成通用平台;
  • 引入的组件比业务核心模块还多;
  • 故障模式、监控和维护人力没有设计;
  • 只讲未来收益,不讲当前迁移和长期运营成本;
  • 方案无法分阶段上线,也没有退出路径。

YAGNI 不等于不做设计

可以保留低成本演进点:

  • 明确接口边界,而不立刻拆成远程服务;
  • 使用可迁移的数据模型,而不提前分库分表;
  • 为第二种实现保留适配器,而不先建设插件平台;
  • 记录规模触发指标,而不按最大想象容量建设。

六、例外机制

架构规则不可能覆盖所有场景。例外申请应包含:

  • 为什么标准方案无法满足;
  • 影响范围和风险;
  • 负责人和截止时间;
  • 监控、回滚和退出方案;
  • 例外是一次性的还是应推动标准演进。

没有到期日的“临时例外”通常会成为永久技术债。

七、如何衡量治理是否有效

正向指标:

  • 跨模块变更影响范围下降;
  • 新成员完成常见任务所需时间缩短;
  • 标准方案采用率和自助完成率提高;
  • 架构相关事故、循环依赖和重复建设减少;
  • 关键依赖升级和漏洞修复时间缩短。

护栏指标:

  • 方案评审等待时间;
  • 例外数量与平均处理时间;
  • 团队对认知负荷和自主性的反馈;
  • 平台维护成本和真实采用率。

如果架构一致性提高但交付等待显著增加,说明治理方式需要调整。


常见面试问题

Q1: 架构委员会是否有必要?

答案:大组织需要跨团队决策机制,但不应审批所有技术选择。它更适合维护原则、处理高影响难逆决策、协调共享能力和演进标准方案。

Q2: ADR 是否所有项目都要写?

答案:不需要。只记录重要、难逆、有争议或需要跨团队理解的决策。记录成本应低于未来重新讨论和误用的成本。

Q3: 如何推动团队遵守架构边界?

答案:先让边界清晰、标准路径易用,再把可验证规则自动化。仅靠文档和人工提醒难以长期维持,处罚也不能替代好工具。

Q4: 如何判断什么时候应该平台化?

答案:至少存在多个稳定消费者、重复问题和共同演进需求,并且维护方、服务等级和迁移成本明确。一个项目的可复用代码不等于平台。

Q5: 简单方案未来不够用怎么办?

答案:定义容量和组织变化的触发指标,保持清晰边界和可迁移数据,达到阈值再演进。可演进的简单设计通常优于一次到位的复杂设计。

Q6: 统一技术栈是否就是架构治理?

答案:只是其中很小一部分。真正治理还包括领域边界、数据所有权、契约、质量属性、生命周期、例外和演进机制。

相关链接