guarding-architecture

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Guarding architecture

架构防护

REQUIRED BACKGROUND: the
principal-engineering
skill.
必备背景知识:
principal-engineering
技能。

Overview

概述

Structural invariants are load-bearing contracts, not style preferences: violating one surfaces as a class of bugs, not a single defect. Core principle: an invariant that matters gets a name, a written rationale, and a mechanical guard; a principle without a guard is a wish.
结构不变量是支撑系统的契约,而非风格偏好:违反结构不变量会引发一类bug,而非单个缺陷。核心原则:重要的不变量必须有名称、书面依据和机械防护机制;没有防护的原则只是空想。

The pattern

模式步骤

  1. Name the invariants. Numbered and citable ("Law 3"), each with a Statement (technology-neutral, meant to outlast any framework), a Rationale, and Implications. The rationale is a concrete failure narrative: the class of bugs that appears when this is violated, told from an incident, not an abstraction. A rule whose rationale nobody can state is a rule nobody will defend.
  2. Split the stable from the volatile. The principles document changes rarely and names no classes; its current realization (the canonical owners, the guards, the reference designs) lives in a companion that changes with the code. When the two disagree, the principle governs and the realization document is what gets corrected. This is what keeps principle documents from filling with stale class names.
  3. Enforce mechanically. Every enforceable invariant gets an architecture test that fails the build: dependency directions, package boundaries, layering rules, forbidden imports. What cannot be build-enforced becomes a named review check with the invariant cited. An invariant enforced by memory is enforced until the person who remembers it is on holiday.
  4. Violations mean redesign, never justification. A design that violates a named invariant is wrong by construction: redesign it, do not argue the exception into the spec. Watering the contract down to match nonconforming code is the banned move; the violation gets recorded and the code gets fixed (the same rule the technical-writer plugin applies to normative documents).
  5. Specs show conformance. A design that touches guarded ground names the invariants it touches and shows, per invariant, how it upholds each. This makes architecture review objective: the reviewer checks claims against named laws instead of debating taste.
  6. Exceptions are amendments. A genuine exception proposes an edit to the principle, naming the rule it bends and the boundary of the bend; silent exceptions are how a law becomes a suggestion. One undocumented exception is precedent for every future one.
  1. 为不变量命名:为每个不变量编号并可引用(如“法则3”),包含声明(技术中立,不受框架更迭影响)、依据和影响。依据需是具体的失败案例:即违反该不变量时会出现的bug类型,基于实际事件而非抽象描述。无法说明依据的规则,没人会去维护。
  2. 分离稳定与可变内容:原则文档极少变更,且不提及具体类;其当前实现(规范所有者、防护机制、参考设计)存于随代码更新的配套文档中。当两者不一致时,以原则为准,修正实现文档。这能避免原则文档中充斥过时的类名。
  3. 机械强制执行:每个可强制执行的不变量都需添加架构测试,若违反则构建失败:包括依赖方向、包边界、分层规则、禁用导入等。无法通过构建强制执行的不变量,需作为具名评审检查项,并引用该不变量。仅靠记忆执行的不变量,只会在记得它的人在岗时才被遵守。
  4. 违规意味着重新设计,而非找借口:违反具名不变量的设计从本质上就是错误的:应重新设计,而非将特例纳入规范。禁止为了适配不符合规范的代码而弱化契约;需记录违规情况并修正代码(这与技术文档插件对规范性文档的要求一致)。
  5. 设计文档需展示合规性:涉及受防护领域的设计,需指明所涉及的不变量,并针对每个不变量说明如何遵守。这让架构评审更客观:评审者只需对照具名法则检查声明,而非争论个人偏好。
  6. 例外情况需作为修订项:真正的例外情况需提出对原则的修改建议,说明所违背的规则及例外的适用范围;未记录的例外会让法则沦为建议。一次未记录的例外,会成为未来所有例外的先例。

Common invariant classes

常见不变量类别

Instances worth guarding in most systems, as examples rather than mandates: one canonical owner per concern (see
keeping-one-source-of-truth
); dependency direction (the domain never imports the delivery mechanism); critical-path isolation (no I/O, no slow or optional dependency on the hot path); fail-closed boundaries (a gate that cannot evaluate must deny, see
handling-failures
); and migration immutability (see the hard rules).
多数系统中值得防护的实例(仅作示例而非强制要求):每个关注点对应唯一规范所有者(见
keeping-one-source-of-truth
);依赖方向(领域层从不导入交付机制);关键路径隔离(热路径中无I/O、无缓慢或可选依赖);故障关闭边界(无法评估的网关必须拒绝请求,见
handling-failures
);迁移不变性(参见硬规则)。

Common mistakes

常见误区

  • A principles document full of class names. That is the realization document wearing the wrong title; split them.
  • Adding the import "for now". Boundaries die by single convenient imports, each locally reasonable; the guard exists precisely because the violation is always locally reasonable.
  • An invariant asserted in review but absent from the build. It will be enforced exactly as often as the right reviewer is present.
  • Justifying a violation by the cost of conforming. The cost argument may be right, but its correct form is an amendment to the principle, decided by the owner, recorded (via
    recording-decisions
    where installed), never a quiet exception in one spec.
  • Principles written as taste ("prefer small modules") instead of contracts ("module X never imports module Y"). A contract can fail a build; taste can only fail a mood.
  • 原则文档中充斥类名。这是把实现文档错当成了原则文档;需将两者分离。
  • “暂时”添加导入。边界往往因一个个看似合理的便捷导入而被破坏;防护机制的存在正是因为违规行为在局部看来总是合理的。
  • 仅在评审中提及不变量,但未添加到构建检查中。只有当合适的评审者在场时,它才会被执行。
  • 以合规成本为由为违规行为辩解。成本论证可能合理,但正确的方式是提出原则修订建议,由所有者决策并记录(若已安装
    recording-decisions
    则通过该工具记录),绝不能在单个设计文档中悄悄例外。
  • 原则写成偏好表述(如“偏好小模块”)而非契约(如“模块X从不导入模块Y”)。契约可导致构建失败;偏好只能影响心情。