核心问题

系统是否像一个人设计的?

概念完整性来自《人月神话》里的重要思想。

一个系统可以由很多人实现,但它应该呈现出统一的心智模型。

也就是说:

用户和开发者面对系统时,不应该感觉每个角落都来自不同世界。

如果课程、订单、权限、通知、后台、API 都各自有一套命名、错误、状态和交互方式,系统就会变成拼贴画。

核心句:

概念完整性让系统从“能用”变成“可信赖”。

拼贴系统的坏味道

拼贴系统常见表现:

User / Account / Member 混用
role / permission / access 混用
status: active 到处含义不同
错误码每个模块一套
后台操作有的审计,有的没有
API 有的 REST,有的 RPC,有的随便命名
测试结构各不相同
相同业务规则被不同团队重复实现

每个局部可能都能解释。

但整体没有统一秩序。

这会导致:

  • 新人学得慢
  • review 成本高
  • 需求落点不清
  • 模块间误解多
  • 系统越来越难预测

统一领域语言

概念完整性的第一步是统一语言。

例如要明确:

Account 是系统登录主体。
Profile 是展示资料。
OrganizationMembership 是账号和组织的关系。
Enrollment 是学习关系。
CourseAccessGrant 是课程访问权。
Permission 是动作授权。
Ownership 是资源归属。

如果团队不统一这些词,代码一定会分裂。

例如有人写:

UserRole

有人写:

MemberPermission

有人写:

AccountAccess

最终系统会出现多个相似但不等价的世界。

核心句:

语言不统一,系统不可能统一。

统一错误模型

错误模型是概念完整性的重要部分。

统一错误结构:

{
  "code": "COURSE_ACCESS_DENIED",
  "message": "You cannot access this course.",
  "reason": "account_suspended",
  "requestId": "req_123"
}

比每个模块自创错误格式更可靠。

统一错误模型让:

  • 前端处理一致
  • API 文档一致
  • 客服排查一致
  • 监控聚合一致
  • 测试断言一致

错误是系统如何承认失败。

失败方式不统一,系统品味会立刻下降。

统一权限模型

权限模型如果不统一,会非常危险。

坏状态:

课程模块用 role 判断
组织模块用 permission 判断
后台用 isAdmin 判断
移动端 API 自己查 membership
客服工具绕过所有 policy

这会导致权限边界不可预测。

更好的方向是统一:

canAccessCourse(accountId, courseId)
canEditCourse(accountId, courseId)
canInviteOrganizationMember(accountId, organizationId)
canRefundPayment(accountId, paymentId)

所有入口都通过同一套 policy。

核心句:

权限模型不统一,系统就没有真正的边界。

统一状态机风格

不同业务对象可以有不同状态,但表达方式要统一。

例如:

type CoursePublicationStatus = "draft" | "published" | "archived"
type OrderStatus = "pending" | "paid" | "refunded" | "canceled"
type EnrollmentStatus = "active" | "completed" | "expired"

并且统一:

  • 状态名明确
  • 通过动作函数流转
  • 非法流转抛领域错误
  • 状态变化可审计
  • 测试覆盖合法和非法路径

不要一个模块直接写:

status = "active"

另一个模块写:

activateThing()

第三个模块靠 metadata 判断。

统一 API 风格

API 风格不统一,会让客户端痛苦。

统一内容包括:

  • URL 命名
  • HTTP method
  • pagination
  • filtering
  • error response
  • idempotency
  • authentication
  • rate limit headers
  • requestId

例如:

GET /courses/:courseId
POST /courses/:courseId/publish
POST /orders/:orderId/refund
GET /organizations/:organizationId/members

如果 API 一半是:

/doCoursePublish
/refund-order
/memberList

另一半是 REST,系统就会显得拼贴。

统一后台操作模型

后台是最容易破坏概念完整性的地方。

每个团队都给后台加一个按钮,最后会变成:

有些操作要 reason
有些不用
有些有审计
有些没有
有些能回滚
有些不能
有些显示影响范围
有些直接执行

高风险后台操作应该统一流程:

权限检查
  -> 展示影响范围
  -> reason 必填
  -> 二次确认
  -> 执行
  -> audit log
  -> 可追踪结果

这不仅是伦理,也是美学。

统一流程让系统显得可靠。

Conceptual Lead

概念完整性通常需要有人负责。

不一定是一个独裁架构师,但需要有人维护:

  • 领域语言
  • API 风格
  • 错误模型
  • 权限模型
  • 状态机风格
  • 模块边界
  • 设计原则

如果每个团队各自发明,系统会自然分裂。

概念完整性不是靠文档自动发生的。

它需要持续审美和判断。

核心句:

大系统需要概念守门人。

局部优化 vs 整体完整性

有时局部最优会破坏整体。

例如某团队为了快,绕过统一权限系统:

if (membership.role === "owner") ...

短期快。

长期会让权限规则分裂。

再比如某模块自定义错误格式:

{ "ok": false, "why": "no access" }

局部看省事,整体增加客户端复杂度。

概念完整性要求团队愿意牺牲一点局部自由,换取整体一致。

概念完整性检查清单

看一个系统是否有概念完整性,问:

  1. 核心领域词是否有统一定义?
  2. 相同概念是否只有一个权威名字?
  3. 错误模型是否统一?
  4. 权限判断是否走统一 policy?
  5. 状态机表达方式是否统一?
  6. API 风格是否一致?
  7. 后台高风险操作是否有统一流程?
  8. 新团队加入时,是否能学到一套稳定心智模型?
  9. 是否有人维护整体概念一致性?
  10. 局部优化是否正在破坏整体秩序?

小结

  1. 概念完整性回答“系统是否像一个人设计的”。
  2. 拼贴系统每个局部可能合理,但整体不可预测。
  3. 语言不统一,系统不可能统一。
  4. 错误模型、权限模型、状态机、API、后台流程都需要统一。
  5. 大系统需要概念守门人。
  6. 概念完整性要求牺牲一点局部自由,换取整体秩序。
  7. 优雅系统不是没有复杂性,而是复杂性服从同一个心智模型。