Three-Tier Specificity Separation
∀ 通用结构 / ∃! 静态特异 / λ 动态输入——复杂性守恒。
$$\text{Behavior}(x) \equiv \text{Type}(x)$$
任何行为差异必须编码为类型差异。如果两个值有不同行为但相同类型,则类型系统存在缺陷。
推论:字符串不是接口,值不承载语义,类型系统是行为的最终裁判。
$$\sum_{i=1}^{3} C(\text{Tier}_i) = \text{const}$$
领域固有复杂性不因抽象而消失,只在层级间转移。框架的价值在于将复杂性向上汇聚到三阶,使一阶用户感知到的复杂性最小化。
$$f: A \to B \succ f: A \rightharpoonup B$$
框架中的每个函数都应是全函数。偏函数意味着:和类型缺少变体、可选字段本应必选、意图表达不完备。
$$\text{Tier}_3 : \forall x \in \mathcal{D}.\ P(x) \quad \text{(对领域中所有实体成立的命题——绝对通用性)}$$
$$\text{Tier}_2 : \exists! x \in \mathcal{D}.\ \text{Static}(x) \quad \text{(特定实体的编译期可定义构造——绝对静态特异性)}$$
$$\text{Tier}_1 : \lambda t.\ \text{Dynamic}(t) \quad \text{(仅运行时可表达的动态行为——绝对动态特异性)}$$
| 层级 |
量词 |
时态 |
产物 |
| $\text{Tier}_3$ |
$\forall$ |
永恒——对所有实体成立 |
接口定义、路由算法、生命周期管理 |
| $\text{Tier}_2$ |
$\exists!$ |
编译期——特定实体的静态构造 |
适配器实现、拓扑声明、配置定义 |
| $\text{Tier}_1$ |
$\lambda$ |
运行时——仅运行时可确定 |
凭证值、实体选择、请求参数 |
$$\text{Tier}_3 \xrightarrow{★\ \text{接口}} \text{Tier}_2 \xrightarrow{\text{标记类型}} \text{Tier}_1$$
二阶只通过框架定义的 ★ 接口与三阶交互。一阶只通过标记类型与二阶交互。三阶定义通用结构,二阶注入静态特异性,一阶提供动态输入。
对任何节点 $x$,其特异性 $\sigma(x)$ 属于封闭集合:
| 记号 |
定义 |
数学约束 |
| ★ |
真特异 |
$\exists! f \in \text{Tier}_2 : \text{inject}(f)$ — 必须由二阶注入 |
| ● |
可默认 |
$\exists d \in \text{Tier}_3.\ \forall f \in \text{Tier}_2.\ f \overset{?}{=} d$ — 有默认值,可覆盖 |
| ○ |
已封闭 |
$\text{Tier}_3 \vdash \text{sealed}(x)$ — 框架已定义,用户只使用 |
| ◆ |
不透明 |
$\text{Tier}_3 \vdash \text{opaque}(x)$ — 框架内部,用户不可见 |
$$|★| \leq |●| + |○| \implies \text{框架吸收了足够的复杂性}$$
如果用户必须自己填充(★)的部分多于框架已封闭(○)和可默认(●)的部分之和,框架没有完成它的使命。
$$|{x : \sigma(x) = ◆ \wedge \text{visible}(x)}| = 0 \implies \text{无封装泄露}$$
内部实现(◆)对外可见 = 封装泄露。
$$|★| \to \min$$
在保持框架功能完备的前提下,最小化用户必须注入的真特异性数量。
领域复杂性是常量。框架的工作不是"消除"复杂性,而是将它从一阶用户可见的表面向上转移到三阶框架的内部。
$$C_{\text{user}} + C_{\text{framework}} = C_{\text{domain}}$$
$$\text{目标}: C_{\text{user}} \to \min \implies C_{\text{framework}} \to \max$$
| 症状 |
根因 |
| 用户需要理解框架内部才能使用 |
$C_{\text{user}} \approx C_{\text{domain}}$——框架没有吸收复杂性 |
| 框架简单但用户代码膨胀 |
复杂性被推给了用户(框架偷懒) |
| 框架 API 有大量可选参数 |
复杂性停在三阶表面,未被封装到内部 |
Tier 3(框架): 吸收了大部分复杂性 → 内部复杂但外部简洁
Tier 2(适配器): 填充 ★ 特异性 → 工作量与领域特异性成正比
Tier 1(用户): 只提供运行时决策 → 感知最小复杂性
$$\text{WrongTier}(x) :\iff \text{tier}(x) \ne \text{natural_tier}(x)$$
类型在错误的抽象层级 = 必须修正的严重问题。
| 违规 |
描述 |
修正方向 |
| 一阶逻辑出现在三阶 |
框架包含具体业务逻辑 |
提取为 ★ 扩展点 |
| 三阶实现暴露在一阶 |
内部类型出现在公开 API |
封装为 ◆ 不透明 |
| 二阶硬编码在三阶 |
框架内置特定实现 |
泛化为 ★ 或 ● 接口 |
| 运行时值用于编译期决策 |
动态数据驱动类型选择 |
提升为泛型参数或关联类型 |
$$\text{物理路径}(x) \cong \text{逻辑路径}(x)$$
文件目录结构必须与类型代数层级一致——路径即文档。
$$\text{项目} > \text{文件夹} > \text{文件} > \text{类型} > \text{函数} > \text{变量}$$
每一层命名必须准确反映语义,不得矛盾或模糊。
- 物理路径:文件目录归属正确,禁止跨领域污染
- 语义预期:路径 + 文件名应能解释代码用途
- 实现细节:仅在路径正确时评审逻辑