整体架构
- 状态层:负责存储应用的所有状态数据。将不同业务模块的状态进行分类管理,例如用户相关状态、订单相关状态等,每个分类作为一个状态集合。
- 变更层:定义状态变更的规则和方法。所有对状态的修改都必须通过变更层的方法进行,以保证状态变化的可追溯性和一致性。
- 监听层:用于监听状态的变化,并通知相关的UI组件进行更新。采用观察者模式,各个UI组件可以注册监听特定状态的变化。
- 调度层:协调状态层、变更层和监听层之间的交互。接收来自UI或其他业务逻辑的状态变更请求,调用变更层方法修改状态,并触发监听层通知UI更新。
关键模块设计思路
- 状态模块:采用类的形式封装状态数据,使用私有变量存储状态,提供公共的访问和修改方法(通过变更层方法间接修改)。例如:
class UserState {
String _username;
int _userLevel;
String get username => _username;
int get userLevel => _userLevel;
// 不直接暴露修改方法,由变更层处理
}
- 变更模块:针对每个状态集合定义一系列的变更方法。这些方法接收必要的参数,对状态进行修改,并记录变更日志(用于调试和状态回溯)。例如:
class UserStateMutations {
static void updateUsername(UserState state, String newUsername) {
state._username = newUsername;
// 记录变更日志
}
}
- 监听模块:创建一个
Listener
类,包含一个回调函数列表。当状态变化时,遍历回调列表并执行相应的回调函数通知UI。例如:
class Listener {
List<Function> _callbacks = [];
void addCallback(Function callback) {
_callbacks.add(callback);
}
void notify() {
_callbacks.forEach((callback) => callback());
}
}
- 调度模块:作为整个状态管理机制的核心,接收状态变更请求,调用变更模块方法修改状态,然后通知监听模块更新UI。例如:
class Dispatcher {
static void dispatch(String mutationType, dynamic payload) {
switch (mutationType) {
case 'updateUsername':
UserStateMutations.updateUsername(UserState(), payload);
break;
}
// 通知监听模块
Listener().notify();
}
}
保证状态更新一致性
- 单一数据源:确保所有状态数据都集中存储在状态层,避免状态数据分散在多个地方导致不一致。
- 原子操作:在变更层,将每个状态变更操作设计为原子操作,要么全部成功,要么全部失败,防止部分状态更新导致不一致。
- 变更日志:记录所有状态变更的详细信息,在出现不一致问题时,可以通过回溯日志找到问题发生的原因。
性能优化
- 细粒度更新:在监听层,让UI组件可以注册监听特定状态的变化,而不是整个状态树的变化。这样只有相关的UI组件会被更新,减少不必要的重绘。
- 批量更新:在调度层,对于短时间内多次状态变更请求,可以进行合并处理,减少不必要的UI更新次数。
- 缓存机制:对于一些不经常变化且计算复杂的状态数据,可以采用缓存机制,避免重复计算。