Manager 模式
为什么需要 Manager
在 AI 小鲸 v2.0 的架构中,我们引入了 Manager 模式来解决组件层日益增长的复杂性问题。Manager 模式的核心理念是:
- 关注点分离:将业务逻辑从 Vue 组件中抽离,组件只负责渲染,Manager 负责业务编排
- 可测试性:Manager 是纯 TypeScript 类,不依赖 Vue 运行时,可以轻松编写单元测试
- 可扩展性:通过依赖注入和面向接口编程,新增功能只需添加新的 Manager,无需修改已有代码
Manager 总览
v2.0 内置了 6 个核心 Manager,各司其职:
| Manager | 职责 | 依赖 |
|---|---|---|
ComponentManager | UI 状态管理 + 事件协调中心 | 无 |
ChatBusinessManager | 消息发送、停止生成、流式处理 | agentModule、sessionModule |
SessionBusinessManager | 会话的创建、读取、更新、删除 | sessionModule、messageModule、agentModule |
ShortcutManager | 快捷指令的注册与管理 | agentModule |
UIStateManager | 选择模式、编辑模式等 UI 状态 | 无 |
ShareBusinessManager | 分享流程编排 | messageModule、sessionModule |
职责说明
- ComponentManager 是整个 Manager 体系的协调中心,负责管理组件级别的 UI 状态(如加载态、错误态),同时作为内部事件总线,协调各 Manager 之间的通信。
- ChatBusinessManager 封装了与 AI 对话相关的所有业务逻辑,包括消息发送、流式响应处理、停止生成等操作。
- SessionBusinessManager 管理会话的完整生命周期,包括会话列表加载、新建会话、切换会话、删除会话等。
- ShortcutManager 负责快捷指令的注册、查询和执行,支持自定义指令扩展。
- UIStateManager 管理与用户交互相关的 UI 状态,如消息选择模式、文本编辑模式等。
- ShareBusinessManager 编排消息分享的完整流程,包括选择消息、生成分享链接、复制内容等。
Manager 创建模式
所有 Manager 都通过依赖注入的方式创建,在组件初始化时由 useChatBootstrap 或手动方式完成实例化:
typescript
import { ComponentManager, ChatBusinessManager, SessionBusinessManager } from '@blueking/ai-blueking';
// 1. 创建无依赖的基础 Manager
const componentManager = new ComponentManager();
// 2. 创建依赖底层模块的业务 Manager
const chatManager = new ChatBusinessManager(
chatHelper.agent, // agentModule - 提供 AI 代理交互能力
chatHelper.session, // sessionModule - 提供会话上下文
chatbotInit // 初始化配置
);
// 3. 创建需要多个模块的 Manager
const sessionManager = new SessionBusinessManager(
chatHelper.session, // sessionModule
chatHelper.message, // messageModule
chatHelper.agent, // agentModule
{
enableChatSession: true // 启用多会话管理
}
);依赖关系图

自定义 Manager 扩展
当内置 Manager 无法满足需求时,你可以创建自定义 Manager 并注册到体系中。
步骤一:定义自定义 Manager
typescript
import { BaseManager } from '@blueking/ai-blueking';
export class AnalyticsManager extends BaseManager {
private trackingId: string;
constructor(trackingId: string) {
super();
this.trackingId = trackingId;
}
// 追踪消息发送事件
trackMessageSent(content: string) {
console.log(`[${this.trackingId}] 消息已发送: ${content.substring(0, 50)}...`);
// 上报到分析平台
}
// 追踪会话切换事件
trackSessionSwitch(sessionCode: string) {
console.log(`[${this.trackingId}] 会话切换: ${sessionCode}`);
}
dispose() {
// 清理资源
}
}步骤二:注册到 ComponentManager
typescript
const analyticsManager = new AnalyticsManager('my-app-001');
// 注册到 ComponentManager,使其参与事件协调
componentManager.register('analytics', analyticsManager);
// 在事件中使用
componentManager.on('send-message', (content: string) => {
analyticsManager.trackMessageSent(content);
});
componentManager.on('session-switch', (code: string) => {
analyticsManager.trackSessionSwitch(code);
});步骤三:在组件中使用
typescript
// 通过 provide/inject 在组件树中共享
provide('analyticsManager', analyticsManager);
// 子组件中获取
const analytics = inject<AnalyticsManager>('analyticsManager');副作用处理原则
Manager 模式的一个核心原则是:所有副作用都由 Manager 处理,组件保持纯渲染。
什么是副作用?
- API 调用(发送消息、加载会话列表等)
- 状态变更(修改全局状态、更新缓存等)
- 浏览器 API 调用(localStorage、clipboard 等)
- 定时器和订阅管理
正确做法
typescript
// ✅ 组件只负责渲染和用户交互转发
const ChatInput = defineComponent({
setup() {
const chatManager = inject<ChatBusinessManager>('chatManager');
const handleSend = (content: string) => {
// 将用户操作委托给 Manager
chatManager.sendMessage(content);
};
return { handleSend };
},
});
// ✅ Manager 处理所有副作用
class ChatBusinessManager {
async sendMessage(content: string) {
// 副作用:更新状态
this.setLoading(true);
try {
// 副作用:API 调用
await this.agentModule.chat(content, this.sessionCode);
// 副作用:触发事件
this.emit('message-sent', content);
} catch (error) {
// 副作用:错误处理
this.handleError(error);
} finally {
this.setLoading(false);
}
}
}错误做法
typescript
// ❌ 不要在组件中直接处理副作用
const ChatInput = defineComponent({
setup() {
const handleSend = async (content: string) => {
// 错误:组件内直接发起 API 调用
const response = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ content }),
});
// 错误:组件内直接操作 DOM / 全局状态
document.title = '新消息...';
};
return { handleSend };
},
});遵循这一原则,可以确保组件的可复用性和可测试性,同时让业务逻辑的维护和调试变得更加简单。