store基类通过私有状态+只读访问器+受保护钩子实现安全继承,统一update入口、订阅机制和类型约束,使子类专注业务逻辑而非状态管理细节。

访问器属性(getter/setter)本身不直接“被继承”,但它们定义在原型链上的行为,配合受保护的内部状态和合理的访问控制,能让子类安全复用、扩展数据流逻辑。设计高内聚的公共流式 Store 基类,关键不在“继承访问器”,而在**把状态管理契约前置、把副作用收敛、把变更通知机制统一暴露**。
明确状态边界与只读契约
Store 的核心是状态(state)及其响应性。避免让子类直接操作原始数据字段,而是通过受保护的私有字段 + 公共访问器封装:
- 用 private #state 存储原始状态对象,确保外部和子类无法绕过逻辑篡改
- 提供 public get state() 只读访问器,返回结构化克隆或不可变视图(如 Proxy 包裹的冻结对象)
- 禁止子类重写
state访问器;若需定制行为,应覆盖受保护的_getStateSnapshot()钩子方法
将变更逻辑抽象为可复用的流式动作
Store 的“流式”体现在状态更新可组合、可监听、可撤销。基类应提供统一的变更入口,而非暴露 setter:
- 定义 protected update(updater: (draft: Draft
) => void) 方法,内部使用 Immer 或类似机制执行不可变更新 - 所有子类调用
this.update(...)触发变更,基类自动触发notify()和onUpdate()钩子 - 子类可重写
onUpdate(prev, next)实现日志、持久化、联动等副作用,但不干扰主流程
统一订阅与派发机制
高内聚要求状态变更的“发布-订阅”完全由基类托管,子类只负责注册监听器,不自行维护事件列表:
- 基类内置 protected listeners: Set
,提供 subscribe(fn)和unsubscribe(fn)公共方法 -
notify()在基类中实现:遍历 listeners 并异步派发最新state快照(避免同步递归调用风险) - 子类无需知道通知细节,只需调用
this.subscribe(...)即可接入整个流式生命周期
支持类型安全的派生与扩展
在 TypeScript 环境下,利用泛型 + 抽象方法强制子类明确其状态结构与初始化逻辑:
- 声明 abstract class Store
,要求子类实现 protected abstract getInitialState(): T - 构造函数中调用该方法并初始化
#state,确保每个派生 Store 都有确定的类型起点 - 搭配
as const或readonly修饰符约束 action 类型,使dispatch(action)的类型推导自然收敛










