thingsboard-client-demo/MULTI_PLATFORM_ARCHITECTURE.md

280 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 多平台机巢状态机架构说明
## 架构概述
本系统采用**策略模式 + 工厂模式**实现多平台支持允许DJI、AUTEL、YUNEEC等不同无人机平台共存并独立运行。
## 核心设计
### 1. 平台类型枚举 (PlatformType)
```
- DJI (大疆)
- AUTEL (道通)
- YUNEEC (昊翔)
```
### 2. 平台策略接口
#### AirportPlatformStrategy
定义机巢平台需要实现的所有Guard、Action和Listener
- Guards: CanOnlineGuard, CanOfflineGuard, IsDebugModeGuard等
- Actions: OnlineAction, OfflineAction, OpenDebugModeAction等
- Listener: 状态变化监听器
#### CoverPlatformStrategy
定义舱门平台需要实现的所有Guard、Action和Listener
- Guards: CanOpenGuard, CanCloseGuard, IsOpenedGuard等
- Actions: OpenAction, CloseAction, OpenedAction等
- Listener: 状态变化监听器
### 3. 平台策略工厂 (PlatformStrategyFactory)
**核心功能:**
- 根据机巢SN从数据库查询平台类型
- 返回对应平台的策略实现
- 自动注册所有平台策略实现
**关键方法:**
```java
AirportPlatformStrategy getAirportStrategy(String airportSn)
CoverPlatformStrategy getCoverStrategy(String airportSn)
PlatformType getPlatformType(String airportSn)
```
### 4. 数据库映射 (AirportPlatformRepository)
**存储结构:**
```
机巢SN -> 平台类型
airport-001 -> DJI
airport-002 -> AUTEL
airport-003 -> DJI
airport-004 -> YUNEEC
```
**说明:** 当前使用内存Map模拟数据库实际使用时替换为真实数据库查询。
### 5. 默认Listener实现
#### DefaultAirportListener
提供机巢状态变化的基础监听功能:
- 状态进入/退出日志
- 状态转换日志
- 事件未接受日志
- 状态机启动/停止日志
#### DefaultCoverListener
提供舱门状态变化的基础监听功能(同上)
**特点:** 各平台可以继承默认Listener并定制自己的逻辑。
## 目录结构
```
com.tuoheng.status.machine
├── platform
│ ├── PlatformType.java # 平台类型枚举
│ ├── strategy # 策略接口
│ │ ├── PlatformAction.java
│ │ ├── PlatformGuard.java
│ │ ├── PlatformListener.java
│ │ ├── AirportPlatformStrategy.java
│ │ └── CoverPlatformStrategy.java
│ ├── factory
│ │ └── PlatformStrategyFactory.java # 平台策略工厂
│ ├── repository
│ │ └── AirportPlatformRepository.java # 数据库映射
│ └── impl # 平台实现
│ └── dji # DJI平台实现
│ ├── DjiAirportPlatformStrategy.java
│ ├── DjiCoverPlatformStrategy.java
│ ├── action
│ │ ├── airport # 机巢Action
│ │ │ ├── DjiOnlineAction.java
│ │ │ ├── DjiOfflineAction.java
│ │ │ ├── DjiOpenDebugModeAction.java
│ │ │ ├── DjiCloseDebugModeAction.java
│ │ │ ├── DjiRebootAction.java
│ │ │ └── DjiRebootCompletedAction.java
│ │ └── cover # 舱门Action
│ │ ├── DjiOpenCoverAction.java
│ │ ├── DjiCoverOpenedAction.java
│ │ ├── DjiCloseCoverAction.java
│ │ ├── DjiCoverClosedAction.java
│ │ ├── DjiCoverErrorAction.java
│ │ └── DjiCoverResetAction.java
│ └── guard
│ ├── airport # 机巢Guard
│ │ ├── DjiCanOnlineGuard.java
│ │ ├── DjiCanOfflineGuard.java
│ │ ├── DjiIsDebugModeGuard.java
│ │ ├── DjiIsNotDebugModeGuard.java
│ │ ├── DjiCanCloseDebugModeGuard.java
│ │ └── DjiIsRebootCompletedGuard.java
│ └── cover # 舱门Guard
│ ├── DjiCanOpenCoverGuard.java
│ ├── DjiCanCloseCoverGuard.java
│ ├── DjiIsCoverOpenedGuard.java
│ └── DjiIsCoverClosedGuard.java
├── listener
│ ├── DefaultAirportListener.java # 默认机巢监听器
│ └── DefaultCoverListener.java # 默认舱门监听器
├── config
│ ├── AirportMachineConfig.java # 机巢状态机配置(多平台)
│ └── CoverMachineConfig.java # 舱门状态机配置(多平台)
├── service
│ ├── AirportMachineService.java # 机巢状态机服务
│ └── CoverMachineService.java # 舱门状态机服务
├── manager
│ └── AirportSystemManager.java # 系统管理器(协调器)
└── demo
├── AirportSystemDemo.java # 单平台演示
└── MultiPlatformDemo.java # 多平台演示
```
## 工作流程
### 1. 状态机创建流程
```
用户调用 -> AirportSystemManager.airportOnline(airportSn)
AirportMachineService.sendEvent(airportSn, AIRPORT_ONLINE)
AirportMachineService.getOrCreateStateMachine(airportSn)
AirportMachineConfig.stateMachineFactory.getStateMachine(airportSn)
PlatformStrategyFactory.getAirportStrategy(airportSn)
AirportPlatformRepository.getPlatformType(airportSn) # 查询数据库
返回对应平台的Strategy (如: DjiAirportPlatformStrategy)
使用Strategy中的Guard、Action、Listener构建状态机
状态机创建完成并启动
```
### 2. 事件处理流程
```
事件触发 -> StateMachine.sendEvent(event)
检查Guard条件 (如: DjiCanOnlineGuard.evaluate())
Guard通过 -> 执行Action (如: DjiOnlineAction.execute())
状态转换
触发Listener回调 (如: DefaultAirportListener.stateChanged())
```
## 如何添加新平台
### 步骤1: 在PlatformType中添加新平台
```java
public enum PlatformType {
DJI("DJI", "大疆"),
AUTEL("AUTEL", "道通"),
YUNEEC("YUNEEC", "昊翔"),
NEW_PLATFORM("NEW", "新平台"); // 添加这行
}
```
### 步骤2: 创建平台实现目录
```
platform/impl/newplatform/
├── NewPlatformAirportStrategy.java
├── NewPlatformCoverStrategy.java
├── action/
│ ├── airport/
│ └── cover/
└── guard/
├── airport/
└── cover/
```
### 步骤3: 实现AirportPlatformStrategy接口
```java
@Component
public class NewPlatformAirportStrategy implements AirportPlatformStrategy {
@Override
public PlatformType getPlatformType() {
return PlatformType.NEW_PLATFORM;
}
// 实现所有Guard、Action、Listener的getter方法
}
```
### 步骤4: 实现CoverPlatformStrategy接口
```java
@Component
public class NewPlatformCoverStrategy implements CoverPlatformStrategy {
@Override
public PlatformType getPlatformType() {
return PlatformType.NEW_PLATFORM;
}
// 实现所有Guard、Action、Listener的getter方法
}
```
### 步骤5: 实现所有Guard和Action
参考DJI平台的实现创建对应的Guard和Action类。
### 步骤6: 在数据库中配置映射关系
```java
repository.savePlatformMapping("airport-005", PlatformType.NEW_PLATFORM);
```
### 步骤7: 测试
```java
systemManager.airportOnline("airport-005");
```
## 运行演示
### 单平台演示
```bash
运行: AirportSystemDemo.main()
演示内容: DJI平台的完整开舱、关舱、重启流程
```
### 多平台演示
```bash
运行: MultiPlatformDemo.main()
演示内容:
- DJI、AUTEL、YUNEEC三个平台同时运行
- 各平台独立的状态管理
- 动态注册新平台
- 多平台状态汇总
```
## 架构优势
1. **平台隔离**: 各平台的业务逻辑完全独立,互不影响
2. **易于扩展**: 添加新平台只需实现Strategy接口无需修改现有代码
3. **数据库驱动**: 平台映射关系存储在数据库,支持动态配置
4. **多平台并发**: 支持多个平台同时运行,状态机独立管理
5. **默认实现**: 提供默认Listener减少重复代码
6. **类型安全**: 使用枚举和接口保证类型安全
7. **Spring集成**: 利用Spring的依赖注入自动注册所有平台策略
## 注意事项
1. **数据库配置**: 当前使用内存Map模拟生产环境需替换为真实数据库
2. **平台注册**: 所有平台Strategy实现必须标注@Component注解
3. **机巢SN**: 必须在数据库中配置机巢SN到平台类型的映射
4. **Listener定制**: 如需定制Listener继承DefaultListener并覆盖相应方法
5. **线程安全**: Service层使用ConcurrentHashMap保证线程安全
## 未来扩展
1. **平台能力差异**: 可在Strategy中添加能力查询接口
2. **动态配置**: 支持运行时动态修改平台映射关系
3. **平台版本**: 支持同一平台的不同版本如DJI v1, DJI v2
4. **监控告警**: 集成监控系统,实时监控各平台状态
5. **性能优化**: 状态机缓存、懒加载等优化策略