Add a scaffold script that replaces the bq prefix with the new project name.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
bql
2026-10-27 22:46:06 +08:00
commit bc84c95a89
128 changed files with 9700 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
# 常见设计模式及使用
本篇只写这套脚手架里会碰到的三种写法。名称用来对照代码,不展开其他模式。
## 目录
- [依赖注入](#依赖注入)
- [仓储](#仓储)
- [观察者](#观察者)
## 依赖注入
调用方不创建依赖,容器按构造函数传入。`SecurityApplication` 需要仓储和 `TokenStore` 时,只声明参数类型,不写 `new SecurityRepository()`。
依赖倒置、注入方式和 `Singleton`、`Transient`、`@bindAs` 的用法见 [DI是什么](./DI是什么.md)。
## 仓储
仓储把「业务要的数据」和「数据放在哪」分开。
`ISecurityRepository` 声明 `login`,返回 `LoginResult`。用例只调用这个方法,再把 `accessToken` 写入 `TokenStore`。`SecurityRepository` 才知道要访问 `/auth/login`,并把响应收成 `User`。
项目模块只有一个端口 `IProjectRepository`,声明 `list`、`get`、`save`。本地实现走 IndexedDB,远程实现走 `Http`,都实现这个端口。`ProjectApplication` 按 `store` 选择其中一个。
因此 `domain` 不出现 axios 和 IndexedDB,`infra` 不决定登录成功后要做什么。
## 观察者
状态变化后,订阅者自己更新。本仓库有两处。
MobX 的 `observable` 字段变化时,包了 `observer` 的组件重绘。这是页面状态到界面的观察者。
`TokenStore.save` 和 `TokenStore.remove` 调用 `notifyAuthChanged`。`useAuthenticated` 通过 `subscribeAuth` 收到 `AUTH_CHANGED` 后再读一次 `hasSession`。登录态变化时,首页不必自己轮询。