初始化仓库:友乐/gameabc 房卡游戏平台脚手架(client + server + docs)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# 01 · 架构总则与分层
|
||||
|
||||
本篇给出七大架构总则,并落到一套**前后端参考分层**上。总则是"为什么这么设计",分层是"具体长什么样"。
|
||||
所有分层里的模块名均为**示例、可自定**,约束的是**层与依赖方向**,不是名字。
|
||||
|
||||
---
|
||||
|
||||
## 1. 七大架构总则
|
||||
|
||||
### 1.1 单一权威数据源(Single Source of Truth)
|
||||
|
||||
同一业务数据**只能有一个计算/写入的地方**,其余模块只读取、不重算。多处并行计算同一结果,必随
|
||||
规则演化而分叉、互相矛盾。
|
||||
|
||||
- 上游**算 + 写 + 校验**,下游**只读 + 消费**。
|
||||
- 需要某数据时,**读权威源**,而不是"顺手再算一遍"。
|
||||
- 详见 [03 篇 · 数据权威](./03-数据权威·错误处理·演进.md)。
|
||||
|
||||
### 1.2 单向依赖,禁止环
|
||||
|
||||
分层之间**自上而下单向依赖**:入口依赖编排、编排依赖领域、领域依赖数据/共享;**反向不依赖**。
|
||||
|
||||
- **稳定依赖原则**:越被依赖的层越应稳定(领域/共享层最稳定,入口层最易变)。
|
||||
- **禁止环形依赖**:A 依赖 B、B 又依赖 A,是"职责没分清"的信号,应抽出共同依赖或调整边界。
|
||||
- 双运行时下尤其致命:环依赖 + 中途 `require` 会在浏览器端崩溃(见 development-guide 的 require 守卫)。
|
||||
|
||||
### 1.3 职责单一、边界清晰
|
||||
|
||||
**一个职能只在一个模块实现**,别的模块需要它就**调用**,不"图方便"复制一份近似逻辑。
|
||||
|
||||
- 判据:写代码前先问"这段逻辑属于谁的职责"。属于别人的,就调用它。
|
||||
- 权威能力不满足时,**在权威模块内扩展**,不要在调用方旁路重写。
|
||||
- 反例:在 A 模块内联 B 模块核心算法的"简化版";同一职能两处并行演化。
|
||||
|
||||
### 1.4 关注点分离(Separation of Concerns)
|
||||
|
||||
把"不同变化原因"的代码分开,让每块**只因一个原因而改**:
|
||||
|
||||
| 分离维度 | 一侧 | 另一侧 |
|
||||
|----------|------|--------|
|
||||
| 决策 vs 机制 | "选哪个"(策略/决策) | "怎么做"(算法/规则/执行) |
|
||||
| 数据 vs 表现 | 状态模型(真相) | 渲染/UI(从数据重建) |
|
||||
| 编排 vs 算法 | 流程编排(controller) | 纯计算(领域算法) |
|
||||
| 输入 vs 逻辑 | 收发包/参数校验 | 业务处理 |
|
||||
|
||||
> 例(决策 vs 机制):自动操作模块只决定"打哪张/是否碰杠胡过",**不实现**胡牌检测/听牌分析;
|
||||
> 后者是领域算法,决策层只**读取其结果**。这既是关注点分离,也是职责边界。
|
||||
|
||||
### 1.5 对扩展开放、对修改封闭(OCP)
|
||||
|
||||
新增一种玩法/规则/策略/牌型,应当是**新增一段代码并注册**,而**不是**去改动已经稳定、已被测试
|
||||
覆盖的核心流程。
|
||||
|
||||
- 手段:**注册表 + 策略**、**管线/中间件**、**工厂**(见 [02 篇](./02-可扩展性与配置化.md))。
|
||||
- 收益:核心不动 → 回归风险小;扩展点清晰 → 新人能照葫芦画瓢。
|
||||
- 例:分级决策框架——核心是"取上下文 → 跑管线 → 选结果",新增高级策略只是**写策略对象 +
|
||||
注册 + 单测**三步,核心零改动。
|
||||
|
||||
### 1.6 配置优先于硬编码
|
||||
|
||||
**会变的、复用的、无语义的**值不写死在逻辑里,外提为常量/配置,用**数据驱动行为**。
|
||||
|
||||
- 分数、阈值、类型字符串、跨模块 key → 常量;成套玩法开关 → 配置对象/规则编码。
|
||||
- 让"改规则"变成"改配置",而不是"改代码 + 重测逻辑"。
|
||||
- 详见 [02 篇 · 配置化与去硬编码](./02-可扩展性与配置化.md)。
|
||||
|
||||
### 1.7 显式失败优于隐式兜底
|
||||
|
||||
关键路径上数据缺失,**优先报错或返回 `null`**,把问题暴露在**离根因最近**的地方;不要用
|
||||
`|| 0`、`|| []`、`|| ''`、双源回退把缺失悄悄填平。
|
||||
|
||||
- 兜底会把 bug 藏进"看似正常"的流程里,等到很远的下游才爆发,极难定位。
|
||||
- 只有**展示层、纯 UI 兼容、非关键日志**字段,才可在明确边界内用安全默认值。
|
||||
- 详见 [03 篇](./03-数据权威·错误处理·演进.md)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 前后端参考分层
|
||||
|
||||
下面是一套**成熟、可直接照搬思路**的分层。层次是稳定的,层内文件如何组织由子游戏自定。
|
||||
|
||||
### 2.1 后端分层(自上而下依赖)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 入口层 Entry 收包薄委托:一操作一入口,只接住并转交 │ 易变
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 收发层 IO 参数校验、响应构建、序列化、差异化广播 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 编排层 Orchestrate 流程编排、状态机推进、跨模块协调(不含算法) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 领域层 Domain 规则/算法权威实现(胡牌/听牌/计分/牌型…) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 数据层 Data 对局状态、状态管理、统一访问层 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 共享层 Shared 前后端逐字相同的纯逻辑与常量 │ 最稳定
|
||||
└─────────────────────────────────────────────┘
|
||||
依赖方向:上层 → 下层(下层绝不反向依赖上层)
|
||||
```
|
||||
|
||||
- **入口层薄**:只做"接住请求 → 委托",不写业务;一操作一入口,不做二次路由。
|
||||
- **领域层是权威**:所有"能不能胡/听什么/怎么算分"的算法只此一份,别层调用。
|
||||
- **数据层是唯一状态落点**:对局状态集中管理,读写走统一访问层,避免散落。
|
||||
- **共享层最底、最稳定**:见 [03 篇 · 数据权威] 与各端 development-guide 的 shared 说明。
|
||||
|
||||
### 2.2 前端分层(自上而下依赖)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 入口层 Entry 平台受限入口:只解包转交,不写业务 │ 易变
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 分发层 Dispatch 唯一收包口,按 rpc 路由到处理器(纯路由表) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 处理层 Controllers 一类消息一处理器:改数据模型 / 触发表现 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 状态层 Model 前端状态真相(界面从它无歧义重建) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 表现层 View/Managers 渲染、动画、音频、资源(从状态派生) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 共享层 Shared 与服务端同源的纯逻辑(只读同步副本) │ 最稳定
|
||||
└─────────────────────────────────────────────┘
|
||||
表现从状态派生:任何时刻重画都能还原正确界面
|
||||
```
|
||||
|
||||
- **入口只转交**:平台受限入口不堆业务,逻辑全在处理层。
|
||||
- **收包分发只分发**:一张 `rpc → 处理器` 路由表,不在分发口写业务。
|
||||
- **数据优先、表现延后**:先落状态模型,再由表现层派生;重连=重画,与正常对局**复用同一重画路径**。
|
||||
|
||||
### 2.3 依赖方向自检
|
||||
|
||||
- 有没有"下层反过来 import/引用上层"?有 → 边界错位,重划。
|
||||
- 有没有"两个模块互相依赖"?有 → 抽公共依赖或合并职责。
|
||||
- 有没有"入口层里写了算法/规则"?有 → 下沉到领域层。
|
||||
- 有没有"表现层里存了业务真相"?有 → 上移到状态层。
|
||||
|
||||
---
|
||||
|
||||
## 3. 本篇小结
|
||||
|
||||
- 七大总则:**SSOT、单向依赖、职责单一、关注点分离、OCP、配置优先、显式失败**。
|
||||
- 后端六层(入口/收发/编排/领域/数据/共享)、前端六层(入口/分发/处理/状态/表现/共享),**依赖单向向下**。
|
||||
- 层是稳定的,层内组织自定;判断对错的尺子始终是**依赖方向**与**职责归属**。
|
||||
|
||||
下一篇 [02-可扩展性与配置化](./02-可扩展性与配置化.md):把 OCP 与"配置优先"落成具体模式与判据。
|
||||
Reference in New Issue
Block a user