11
This commit is contained in:
144
.qoder/quests/module-dependency-analysis.md
Normal file
144
.qoder/quests/module-dependency-analysis.md
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
# 模块依赖分析:EventCommunicationService 与 EventBuilderImpl 关系
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
本文档旨在分析 Vue Desktop 项目中 [EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 与 [EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 的关系,明确它们各自的职责以及是否需要同时存在这两个组件。
|
||||||
|
|
||||||
|
## 系统架构概览
|
||||||
|
|
||||||
|
Vue Desktop 使用分层的事件管理系统:
|
||||||
|
|
||||||
|
1. 内部事件总线 ([EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95)) - 处理组件间的直接通信
|
||||||
|
2. 应用间通信服务 ([EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638)) - 处理跨应用/模块的复杂消息传递
|
||||||
|
|
||||||
|
## 模块详细分析
|
||||||
|
|
||||||
|
### EventBuilderImpl 分析
|
||||||
|
|
||||||
|
[EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 是一个通用的事件管理器实现,提供了基础的发布/订阅模式功能:
|
||||||
|
|
||||||
|
#### 主要职责
|
||||||
|
|
||||||
|
- 提供简单的事件监听(addEventListener)和触发(notifyEvent)机制
|
||||||
|
- 支持一次性事件监听(once选项)
|
||||||
|
- 支持立即执行(immediate选项)
|
||||||
|
- 实现 [IEventBuilder](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\IEventBuilder.ts#L1-L28) 接口
|
||||||
|
|
||||||
|
#### 特点
|
||||||
|
|
||||||
|
- 轻量级,适用于组件内部通信
|
||||||
|
- 不涉及消息队列、优先级、过期时间等复杂概念
|
||||||
|
- 基于回调函数直接调用
|
||||||
|
|
||||||
|
### EventCommunicationService 分析
|
||||||
|
|
||||||
|
[EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 是一个高级消息通信系统,用于处理复杂的跨应用通信场景:
|
||||||
|
|
||||||
|
#### 主要职责
|
||||||
|
|
||||||
|
- 管理应用间的事件订阅和消息传递
|
||||||
|
- 实现消息优先级、过期时间、重试机制等功能
|
||||||
|
- 提供频道管理和权限控制
|
||||||
|
- 支持广播和点对点消息
|
||||||
|
- 维护消息历史和统计数据
|
||||||
|
|
||||||
|
#### 特点
|
||||||
|
|
||||||
|
- 功能丰富,支持复杂的消息路由和处理
|
||||||
|
- 异步处理消息队列
|
||||||
|
- 提供消息持久化和统计功能
|
||||||
|
- 支持权限验证和消息过滤
|
||||||
|
|
||||||
|
## 依赖关系分析
|
||||||
|
|
||||||
|
### 架构层级
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[SystemServiceIntegration] --> B[EventCommunicationService]
|
||||||
|
A --> C[WindowService]
|
||||||
|
A --> D[ResourceService]
|
||||||
|
|
||||||
|
B --> E[IEventBuilder]
|
||||||
|
C --> E
|
||||||
|
|
||||||
|
F[EventBuilderImpl] -.-> E
|
||||||
|
```
|
||||||
|
|
||||||
|
### 依赖说明
|
||||||
|
|
||||||
|
1. [EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 依赖 [IEventBuilder](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\IEventBuilder.ts#L1-L28) 接口,但不直接依赖具体实现
|
||||||
|
2. [EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 是 [IEventBuilder](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\IEventBuilder.ts#L1-L28) 的具体实现之一
|
||||||
|
3. [SystemServiceIntegration](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\SystemServiceIntegration.ts#L36-L597) 同时使用 [EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 和其他服务,并传入 [EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 实例
|
||||||
|
|
||||||
|
## 是否需要 EventBuilderImpl?
|
||||||
|
|
||||||
|
### 结论
|
||||||
|
|
||||||
|
**是的,项目仍然需要 [EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95)**。
|
||||||
|
|
||||||
|
### 原因分析
|
||||||
|
|
||||||
|
1. **职责分离**:
|
||||||
|
- [EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 处理组件内简单事件通信
|
||||||
|
- [EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 处理跨应用复杂消息传递
|
||||||
|
|
||||||
|
2. **性能考虑**:
|
||||||
|
- 内部组件通信不需要 [EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 的复杂特性
|
||||||
|
- [EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 提供轻量级解决方案
|
||||||
|
|
||||||
|
3. **架构清晰性**:
|
||||||
|
- 保持两种不同层次的事件通信机制有助于维护架构清晰性
|
||||||
|
- 避免将所有事件都通过复杂的消息系统传递
|
||||||
|
|
||||||
|
## 正确的类型使用
|
||||||
|
|
||||||
|
### EventCommunicationService 中的类型
|
||||||
|
|
||||||
|
在 [EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 构造函数中,应该使用接口而不是具体实现:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
constructor(eventBus: IEventBuilder<any>)
|
||||||
|
```
|
||||||
|
|
||||||
|
### SystemServiceIntegration 中的类型
|
||||||
|
|
||||||
|
在 [SystemServiceIntegration](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\SystemServiceIntegration.ts#L36-L597) 中,需要创建 [EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 实例并将其注入到依赖它的服务中:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
private eventBus: IEventBuilder<any>
|
||||||
|
|
||||||
|
constructor(config: SystemServiceConfig = {}) {
|
||||||
|
// 使用具体实现创建实例
|
||||||
|
this.eventBus = new EventBuilderImpl<any>()
|
||||||
|
|
||||||
|
// 注入到依赖的服务中
|
||||||
|
// EventCommunicationService 需要 IEventBuilder 接口
|
||||||
|
// WindowService 也需要 IEventBuilder 接口
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 推荐实践
|
||||||
|
|
||||||
|
### 类型声明建议
|
||||||
|
|
||||||
|
对于 [EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 和其他服务:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 接受接口而非具体实现
|
||||||
|
constructor(eventBus: IEventBuilder<any>)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 实例化建议
|
||||||
|
|
||||||
|
在 [SystemServiceIntegration](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\SystemServiceIntegration.ts#L36-L597) 中:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 创建具体实例
|
||||||
|
private eventBus: IEventBuilder<any>
|
||||||
|
this.eventBus = new EventBuilderImpl<any>()
|
||||||
|
```
|
||||||
|
|
||||||
|
## 总结
|
||||||
|
|
||||||
|
[EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 和 [EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 在系统中有不同的职责,两者都是必要的。[EventBuilderImpl](file://c:\Users\98354\Desktop\develop\vue-desktop\src\events\impl\EventBuilderImpl.ts#L7-L95) 提供基础事件机制,[EventCommunicationService](file://c:\Users\98354\Desktop\develop\vue-desktop\src\services\EventCommunicationService.ts#L95-L638) 提供高级消息通信功能。在类型使用上,应遵循依赖倒置原则,服务依赖接口而非具体实现。
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { IDestroyable } from '@/core/common/types/IDestroyable.ts'
|
import type { IDestroyable } from '@/common/types/IDestroyable'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 事件定义
|
* 事件定义
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
import type { IEventBuilder } from '@/events/IEventBuilder'
|
import type { IEventBuilder, IEventMap } from '@/events/IEventBuilder'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
import type { WindowState } from './WindowService'
|
||||||
|
import type { ResourceType } from './ResourceService'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息类型枚举
|
* 消息类型枚举
|
||||||
@@ -90,6 +92,51 @@ export interface EventStatistics {
|
|||||||
channelUsage: Map<string, number>
|
channelUsage: Map<string, number>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 窗体数据更新参数
|
||||||
|
*/
|
||||||
|
export interface WindowFormDataUpdateParams {
|
||||||
|
/** 窗口id */
|
||||||
|
id: string
|
||||||
|
/** 窗口状态 */
|
||||||
|
state: WindowState
|
||||||
|
/** 窗口宽度 */
|
||||||
|
width: number
|
||||||
|
/** 窗口高度 */
|
||||||
|
height: number
|
||||||
|
/** 窗口x坐标(左上角) */
|
||||||
|
x: number
|
||||||
|
/** 窗口y坐标(左上角) */
|
||||||
|
y: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件通信服务事件接口
|
||||||
|
*/
|
||||||
|
export interface EventCommunicationEvents extends IEventMap {
|
||||||
|
// 系统就绪事件
|
||||||
|
onSystemReady: (data: { timestamp: Date; services: string[] }) => void
|
||||||
|
|
||||||
|
// 窗体相关事件
|
||||||
|
onWindowStateChanged: (windowId: string, newState: string, oldState: string) => void
|
||||||
|
onWindowFormDataUpdate: (data: WindowFormDataUpdateParams) => void
|
||||||
|
onWindowFormResizeStart: (windowId: string) => void
|
||||||
|
onWindowFormResizing: (windowId: string, width: number, height: number) => void
|
||||||
|
onWindowFormResizeEnd: (windowId: string) => void
|
||||||
|
onWindowClose: (windowId: string) => void
|
||||||
|
|
||||||
|
// 应用生命周期事件
|
||||||
|
onAppLifecycle: (data: { appId: string; event: string; timestamp: Date }) => void
|
||||||
|
|
||||||
|
// 资源相关事件
|
||||||
|
onResourceQuotaExceeded: (appId: string, resourceType: ResourceType) => void
|
||||||
|
onPerformanceAlert: (data: { type: 'memory' | 'cpu'; usage: number; limit: number }) => void
|
||||||
|
|
||||||
|
// 消息处理事件
|
||||||
|
onMessageProcessed: (message: EventMessage) => void
|
||||||
|
onMessageFailed: (message: EventMessage, error: any) => void
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 事件通信服务类
|
* 事件通信服务类
|
||||||
*/
|
*/
|
||||||
@@ -108,9 +155,9 @@ export class EventCommunicationService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
private processingInterval: number | null = null
|
private processingInterval: number | null = null
|
||||||
private eventBus: IEventBuilder<any>
|
private eventBus: IEventBuilder<EventCommunicationEvents>
|
||||||
|
|
||||||
constructor(eventBus: IEventBuilder<any>) {
|
constructor(eventBus: IEventBuilder<EventCommunicationEvents>) {
|
||||||
this.eventBus = eventBus
|
this.eventBus = eventBus
|
||||||
this.initializeDefaultChannels()
|
this.initializeDefaultChannels()
|
||||||
this.startMessageProcessing()
|
this.startMessageProcessing()
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl'
|
import { EventBuilderImpl } from '@/events/impl/EventBuilderImpl'
|
||||||
import type { IEventBuilder } from '@/events/IEventBuilder'
|
import type { IEventBuilder } from '@/events/IEventBuilder'
|
||||||
|
import type { EventCommunicationEvents, WindowFormDataUpdateParams } from './EventCommunicationService'
|
||||||
|
import type { ResourceType } from './ResourceService'
|
||||||
|
|
||||||
// 导入所有服务
|
// 导入所有服务
|
||||||
import { WindowService } from './WindowService'
|
import { WindowService } from './WindowService'
|
||||||
@@ -11,21 +13,6 @@ import { ApplicationLifecycleManager } from './ApplicationLifecycleManager'
|
|||||||
import { externalAppDiscovery } from './ExternalAppDiscovery'
|
import { externalAppDiscovery } from './ExternalAppDiscovery'
|
||||||
import type { TWindowFormState } from '@/ui/types/WindowFormTypes'
|
import type { TWindowFormState } from '@/ui/types/WindowFormTypes'
|
||||||
|
|
||||||
export interface IWindowFormDataUpdateParams {
|
|
||||||
/** 窗口id */
|
|
||||||
id: string
|
|
||||||
/** 窗口状态 */
|
|
||||||
state: TWindowFormState
|
|
||||||
/** 窗口宽度 */
|
|
||||||
width: number
|
|
||||||
/** 窗口高度 */
|
|
||||||
height: number
|
|
||||||
/** 窗口x坐标(左上角) */
|
|
||||||
x: number
|
|
||||||
/** 窗口y坐标(左上角) */
|
|
||||||
y: number
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统服务配置接口
|
* 系统服务配置接口
|
||||||
*/
|
*/
|
||||||
@@ -83,7 +70,7 @@ export class SystemServiceIntegration {
|
|||||||
private startTime: Date
|
private startTime: Date
|
||||||
|
|
||||||
// 核心服务实例
|
// 核心服务实例
|
||||||
private eventBus: IEventBuilder<any>
|
private eventBus: IEventBuilder<EventCommunicationEvents>
|
||||||
private windowService!: WindowService
|
private windowService!: WindowService
|
||||||
private resourceService!: ResourceService
|
private resourceService!: ResourceService
|
||||||
private eventService!: EventCommunicationService
|
private eventService!: EventCommunicationService
|
||||||
@@ -127,7 +114,7 @@ export class SystemServiceIntegration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.startTime = new Date()
|
this.startTime = new Date()
|
||||||
this.eventBus = new EventBuilderImpl<any>()
|
this.eventBus = new EventBuilderImpl<EventCommunicationEvents>()
|
||||||
|
|
||||||
this.setupGlobalErrorHandling()
|
this.setupGlobalErrorHandling()
|
||||||
}
|
}
|
||||||
@@ -388,7 +375,7 @@ export class SystemServiceIntegration {
|
|||||||
|
|
||||||
// 监听窗体状态变化(来自 WindowService 的 onStateChange 事件)
|
// 监听窗体状态变化(来自 WindowService 的 onStateChange 事件)
|
||||||
this.eventBus.addEventListener(
|
this.eventBus.addEventListener(
|
||||||
'onStateChange',
|
'onWindowStateChanged',
|
||||||
(windowId: string, newState: string, oldState: string) => {
|
(windowId: string, newState: string, oldState: string) => {
|
||||||
console.log(
|
console.log(
|
||||||
`[SystemIntegration] 接收到窗体状态变化事件: ${windowId} ${oldState} -> ${newState}`,
|
`[SystemIntegration] 接收到窗体状态变化事件: ${windowId} ${oldState} -> ${newState}`,
|
||||||
@@ -403,7 +390,7 @@ export class SystemServiceIntegration {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 监听窗体关闭事件,自动停止对应的应用
|
// 监听窗体关闭事件,自动停止对应的应用
|
||||||
this.eventBus.addEventListener('onClose', async (windowId: string) => {
|
this.eventBus.addEventListener('onWindowClose', async (windowId: string) => {
|
||||||
console.log(`[SystemIntegration] 接收到窗体关闭事件: ${windowId}`)
|
console.log(`[SystemIntegration] 接收到窗体关闭事件: ${windowId}`)
|
||||||
// 查找对应的应用
|
// 查找对应的应用
|
||||||
const runningApps = this.lifecycleManager.getRunningApps()
|
const runningApps = this.lifecycleManager.getRunningApps()
|
||||||
@@ -423,7 +410,7 @@ export class SystemServiceIntegration {
|
|||||||
// 监听窗体数据更新事件
|
// 监听窗体数据更新事件
|
||||||
this.eventBus.addEventListener(
|
this.eventBus.addEventListener(
|
||||||
'onWindowFormDataUpdate',
|
'onWindowFormDataUpdate',
|
||||||
(data: IWindowFormDataUpdateParams) => {
|
(data: WindowFormDataUpdateParams) => {
|
||||||
console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data)
|
console.log(`[SystemIntegration] 接收到窗体数据更新事件:`, data)
|
||||||
// 只有在有订阅者时才发送消息
|
// 只有在有订阅者时才发送消息
|
||||||
if (this.eventService.getChannelSubscriberCount('window-form-data-update') > 0) {
|
if (this.eventService.getChannelSubscriberCount('window-form-data-update') > 0) {
|
||||||
@@ -436,7 +423,7 @@ export class SystemServiceIntegration {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 监听窗体调整尺寸开始事件
|
// 监听窗体调整尺寸开始事件
|
||||||
this.eventBus.addEventListener('onResizeStart', (windowId: string) => {
|
this.eventBus.addEventListener('onWindowFormResizeStart', (windowId: string) => {
|
||||||
console.log(`[SystemIntegration] 接收到窗体调整尺寸开始事件: ${windowId}`)
|
console.log(`[SystemIntegration] 接收到窗体调整尺寸开始事件: ${windowId}`)
|
||||||
// 只有在有订阅者时才发送消息
|
// 只有在有订阅者时才发送消息
|
||||||
if (this.eventService.getChannelSubscriberCount('window-form-resize-start') > 0) {
|
if (this.eventService.getChannelSubscriberCount('window-form-resize-start') > 0) {
|
||||||
@@ -448,7 +435,7 @@ export class SystemServiceIntegration {
|
|||||||
|
|
||||||
// 监听窗体调整尺寸过程中事件
|
// 监听窗体调整尺寸过程中事件
|
||||||
this.eventBus.addEventListener(
|
this.eventBus.addEventListener(
|
||||||
'onResizing',
|
'onWindowFormResizing',
|
||||||
(windowId: string, width: number, height: number) => {
|
(windowId: string, width: number, height: number) => {
|
||||||
console.log(`[SystemIntegration] 接收到窗体调整尺寸过程中事件: ${windowId}`, {
|
console.log(`[SystemIntegration] 接收到窗体调整尺寸过程中事件: ${windowId}`, {
|
||||||
width,
|
width,
|
||||||
@@ -468,7 +455,7 @@ export class SystemServiceIntegration {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 监听窗体调整尺寸结束事件
|
// 监听窗体调整尺寸结束事件
|
||||||
this.eventBus.addEventListener('onResizeEnd', (windowId: string) => {
|
this.eventBus.addEventListener('onWindowFormResizeEnd', (windowId: string) => {
|
||||||
console.log(`[SystemIntegration] 接收到窗体调整尺寸结束事件: ${windowId}`)
|
console.log(`[SystemIntegration] 接收到窗体调整尺寸结束事件: ${windowId}`)
|
||||||
// 只有在有订阅者时才发送消息
|
// 只有在有订阅者时才发送消息
|
||||||
if (this.eventService.getChannelSubscriberCount('window-form-resize-end') > 0) {
|
if (this.eventService.getChannelSubscriberCount('window-form-resize-end') > 0) {
|
||||||
@@ -481,7 +468,7 @@ export class SystemServiceIntegration {
|
|||||||
// 监听资源配额超出
|
// 监听资源配额超出
|
||||||
this.eventBus.addEventListener(
|
this.eventBus.addEventListener(
|
||||||
'onResourceQuotaExceeded',
|
'onResourceQuotaExceeded',
|
||||||
(appId: string, resourceType: string) => {
|
(appId: string, resourceType: ResourceType) => {
|
||||||
console.log(`[SystemIntegration] 接收到资源配额超出事件: ${appId} - ${resourceType}`)
|
console.log(`[SystemIntegration] 接收到资源配额超出事件: ${appId} - ${resourceType}`)
|
||||||
this.eventService.sendMessage('system', 'resource-quota-exceeded', {
|
this.eventService.sendMessage('system', 'resource-quota-exceeded', {
|
||||||
appId,
|
appId,
|
||||||
|
|||||||
Reference in New Issue
Block a user