OTAKU / 宣言

第一章 — 硬核心,软边缘

OTAKU 宣言

OTAKU 是一个首字母缩写,每一个字母都是一条约束。四十条规则让它可度量;一个指标决定一个方法是否复杂到不该存在。

这套哲学有坚硬的核心和柔软的边缘。核心——五个支柱及其可度量的阈值——不可谈判。边缘——语言、框架、风格、工具——自由。

五个支柱的顺序是有意的。纪律在先,因为没有它其余都无法存活;契约在最后,因为它是外部世界唯一能看到的东西。

O

自律

对自己严格。

限制是通往自由的唯一道路。复杂度、规模和命名都靠度量,而不是争论。

T

组合的工具

像 Unix 一样组合。

小而清晰的输入输出部件。应用是一条数据管道,副作用留在边缘。

A

装甲核心

保护业务核心。

依赖只向内。实体与用例永远不知道框架的名字。

K

让基础设施保持沉默

基础设施只是细节。

持久化像内存集合一样工作。失败是显式的,状态默认不可变。

U

通用语言与契约

说用户的语言。

把通用语言写进设计先行的契约。原始类型被包装;每个公有方法都有契约。

核心指标

圈复杂度——Thomas J. McCabe 提出的方法独立路径数——是这套哲学的主要仪器。圈复杂度超过 5 的方法必须被拒绝,无论它看起来多易读。五条路径已经是读者必须同时持有的五种推理。

纪律部分的其余内容都是压低这个数字的手段:一层缩进、不用 ELSE、不用 switch/case、卫语句、抽取。这个指标在本书的每种语言里都可度量,每个生态都有报告它的工具。

四十条规则

每条规则都有可度量的阈值。拿不准时,选择更严格的选项。

40 条规则 · 7 组 · 5 个支柱

O复杂度

  1. 每个方法的圈复杂度不得超过 5。
  2. 每个方法最多一层缩进。
  3. 不要使用 ELSE 关键字(使用卫语句或提前返回)。
  4. 不要使用 switch/case(使用多态、match 表达式或策略模式)。
  5. 避免魔法数字和魔法字符串(使用常量或枚举)。

O规模

  1. 每个类最多 50 行(仅类体中的代码)。
  2. 每个方法最多 20 行(仅可执行代码)。
  3. 每个命名空间或包最多 10 个类。
  4. 类中不得有超过两个实例变量。
  5. 方法最多两个参数。
  6. 构造函数最多两个参数。
  7. 接口最多两个方法。

O命名

  1. 不要缩写,使用完整、描述性的名称。
  2. 布尔方法以 is、has、can 或 should 开头。
  3. 方法名以动词开头。
  4. 常量使用 UPPER_SNAKE_CASE。
  5. 属性和方法使用 camelCase。

T模块化

  1. 一等集合:将数组包装在专用类中。
  2. 每行一个点;为可读性避免方法链。
  3. 禁止静态方法,工厂和纯函数除外。
  4. 命令与查询分离:有返回值的方法不得有副作用。
  5. 尽可能使用纯函数:相同输入产生相同输出,无副作用。
  6. 不得使用全局状态或单例;显式注入依赖。
  7. 偏好小而专注的函数;一个方法做多件事时就抽取。

A保护

  1. 不要 getter、setter 或公有属性;使用方法表达行为。
  2. 属性默认私有;仅框架继承时使用 protected。
  3. 类默认 final;通过接口进行扩展。
  4. 除框架基类外禁止继承;优先使用组合。
  5. 在边界处(构造函数和公有方法)验证所有输入。
  6. 快速失败:一旦违反前置条件就抛出异常。
  7. 不要修改输入参数;将其视为不可变。

K副作用与失败

  1. 优先不可变:只读属性,返回新实例。
  2. 返回集合的方法应返回空集合,绝不返回 null。
  3. 可能失败的方法返回 Result/Either 或抛出异常;绝不返回 null。
  4. 显式优于隐式:不得有隐藏依赖、魔术方法或隐式转换。
  5. 绝不将基础设施细节(SQL、HTTP、文件路径)泄漏到领域层。

U契约

  1. 将所有原始类型和字符串包装为值对象。
  2. 除显式序列化方法外,不得使用泛型类型(mixed、array、object)。
  3. 每个公有方法都必须在接口中声明。
  4. 注释解释原因,属于契约,而非实现。

支柱如何相互支撑

纪律使组合成为可能:300 行的类无法替换。组合使核心可防卫:单体无法隐藏依赖。受保护的核心让基础设施真正可选。契约是这一切能从外部验证的唯一原因。

去掉一根支柱,其余就沦为仪式。保留五根,系统会变得无聊——就像桥梁的无聊。