Files
contract-manager/docs/task/server模块service缓存调整为Vo对象/DESIGN_server模块service缓存调整为Vo对象.md
songqq 49413ad473 refactor(service): 统一Service缓存为VO对象并优化关联实体处理
重构Service类实现,将QueryService泛型参数调整为VO类型,确保缓存VO对象而非实体。优化关联实体处理逻辑,减少重复代码。修改findById方法返回VO对象,新增getById方法获取实体。更新相关调用点以适配新接口。

调整WebSocket处理、控制器及Service实现,确保数据类型一致性。完善文档记录重构过程及发现的问题。为后续优化提供基础架构支持。
2025-09-29 19:31:51 +08:00

301 lines
9.8 KiB
Markdown
Raw 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.

# Server模块Service缓存调整为Vo对象设计文档
## 1. 整体架构图
```mermaid
flowchart TD
subgraph 控制器层
Controller[Controller控制器]
end
subgraph 服务层
direction LR
Service1[Service类
实现IEntityService<Model>和QueryService<Vo>]
Service2[Service类
实现IEntityService<Model>和QueryService<Vo>]
Service3[Service类
实现IEntityService<Model>和QueryService<Vo>]
end
subgraph 数据转换层
Mapper[实体-VO转换器
负责双向转换]
end
subgraph 数据访问层
Repository[Repository接口
操作实体类]
end
subgraph 数据层
Database[(数据库)]
end
subgraph 缓存层
RedisCache[Redis缓存
存储VO对象]
end
Controller -->|调用服务方法| Service1
Controller -->|调用服务方法| Service2
Controller -->|调用服务方法| Service3
Service1 -->|转换VO到实体| Mapper
Service2 -->|转换VO到实体| Mapper
Service3 -->|转换VO到实体| Mapper
Mapper -->|转换实体到VO| Service1
Mapper -->|转换实体到VO| Service2
Mapper -->|转换实体到VO| Service3
Service1 -->|CRUD操作| Repository
Service2 -->|CRUD操作| Repository
Service3 -->|CRUD操作| Repository
Repository -->|存取数据| Database
Service1 <-->|缓存VO对象| RedisCache
Service2 <-->|缓存VO对象| RedisCache
Service3 <-->|缓存VO对象| RedisCache
%% 关键修改点
style RedisCache fill:#bbf,stroke:#333,stroke-width:2px
```
## 2. 分层设计和核心组件
### 2.1 控制器层
- **职责**: 处理HTTP请求调用Service层方法返回处理结果
- **影响**: 可能需要调整调用Service层方法的参数和返回值类型
### 2.2 服务层
- **职责**: 实现业务逻辑处理数据转换调用Repository层进行数据操作管理缓存
- **核心组件**: 所有注解了@CacheConfig的Service类
- **修改内容**:
- Service类同时实现IEntityService<Model>和QueryService<Vo>接口
- IEntityService接口泛型保持为实体类Model
- QueryService接口泛型修改为VO类
- 继承 VoableService<M, Vo>接口,实现 updateByVo 方法
- 修改 findById 方法返回VO对象并且使用 @Cacheable(key = "#p0") 注解
- 保留 getById 方法,调用 repository.findById(id) 返回实体对象
### 2.3 数据转换层
- **职责**: 负责实体类和VO类之间的数据转换
- **核心组件**:
- 现有的VoableService接口
- 实体类自带的toVo()方法
- **设计考虑**: 使用实体类自带的toVo()方法进行转换,简化代码结构
### 2.4 数据访问层
- **职责**: 提供对数据库的访问操作
- **核心组件**: Spring Data JPA Repository接口
- **影响**: 基本不受修改影响,仍然操作实体类
### 2.5 缓存层
- **职责**: 存储VO对象提高数据访问性能
- **核心组件**: Redis缓存
- **关键修改**: 确保只缓存VO对象避免代理对象序列化问题
## 3. 模块依赖关系图
```mermaid
flowchart TD
subgraph 接口定义
IEntityService[IEntityService<Model>
定义CRUD操作接口] --> VoableService[VoableService<M, Vo>
定义VO更新方法]
QueryService[QueryService<Vo>
定义查询操作接口]
end
subgraph 服务实现
ServiceImpl[Service实现类
实现IEntityService<Model>、QueryService<Vo>和VoableService]
end
subgraph 数据访问
Repository[Repository接口
操作实体类]
end
subgraph 数据模型
Entity[实体类
持久化对象]
VO[VO类
视图对象]
end
subgraph 缓存
RedisCache[Redis缓存
存储VO对象]
end
IEntityService --> ServiceImpl
QueryService --> ServiceImpl
VoableService --> ServiceImpl
ServiceImpl --> Repository
Repository --> Entity
ServiceImpl --> Entity
ServiceImpl --> VO
ServiceImpl <-->|缓存VO对象| RedisCache
style RedisCache fill:#bbf,stroke:#333,stroke-width:2px
```
## 4. 接口契约定义
### 4.1 IEntityService<Model>接口
```java
public interface IEntityService<Model> {
// 根据ID查询Model对象
Model getById(Integer id);
// 根据查询规范和分页参数查询Model对象列表
Page<Model> findAll(Specification<Model> spec, Pageable pageable);
// 根据搜索文本构建查询规范
Specification<Model> getSpecification(String searchText);
// 搜索Model对象列表默认方法
default List<Model> search(String searchText) {
throw new UnsupportedOperationException();
}
// 删除Model对象
void delete(Model entity);
// 保存Model对象
Model save(Model entity);
}
### 4.2 QueryService<Vo>接口
```java
public interface QueryService<Vo> {
// 根据ID查询Vo对象
Vo findById(Integer id);
// 根据查询参数和分页条件获取Vo对象列表
Page<Vo> findAll(JsonNode paramsNode, Pageable pageable);
// 计数方法
default long count(JsonNode paramsNode) {
return 0;
}
}
```
### 4.3 Service实现类接口契约
对于每个Service实现类需要同时实现IEntityService<Model>和QueryService<Vo>接口:
#### IEntityService<Model>实现方法:
| 方法签名 | 实现逻辑 |
|---------|---------|
| `Model getById(Integer id)` | 1. 调用repository.findById(id)
2. 直接返回实体对象(不做缓存) |
| `Page<Model> findAll(Specification<Model> spec, Pageable pageable)` | 1. 构建查询条件
2. 调用repository.findAll(spec, pageable)
3. 返回包含实体对象的Page |
| `void delete(Model entity)` | 1. 直接调用repository.delete(entity) |
| `Model save(Model entity)` | 1. 直接调用repository.save(entity)
2. 清除相关缓存
3. 返回实体对象 |
#### QueryService<Vo>实现方法:
| 方法签名 | 实现逻辑 |
|---------|---------|
| `Vo findById(Integer id)` | 1. 调用repository.findById(id)
2. 将查询到的实体对象转换为VO对象
3. 使用@Cacheable注解缓存VO对象
4. 返回VO对象 |
| `Page<Vo> findAll(JsonNode paramsNode, Pageable pageable)` | 1. 构建查询条件
2. 调用repository.findAll(spec, pageable)
3. 将查询结果中的每个实体对象转换为VO对象
4. 返回包含VO对象的Page |
## 5. 数据流向图
```mermaid
flowchart TD
subgraph 服务请求处理流程
B[Controller接收请求
调用Service方法] --> C[Service方法处理
接收参数] --> D{检查Redis缓存
中是否存在VO对象}
D -->|存在| D1[直接返回缓存中的VO对象]
D -->|不存在| D2[准备数据操作
调用Repository] --> E[Repository操作数据库
返回Entity结果]
E --> F[Entity转换为VO
准备响应数据]
F --> G[将VO对象存入Redis缓存] --> H[Service返回VO
Controller组装响应]
D1 --> H
end
subgraph 数据转换流程
K[VO对象] -->|属性映射| L[Entity对象
用于数据持久化]
L -->|属性映射| K
end
C -->|查询操作| D
C -->|更新/删除操作| D2
D2 --> L
E --> L
F --> K
style G fill:#bbf,stroke:#333,stroke-width:2px
style D fill:#bbf,stroke:#333,stroke-width:2px
```
## 6. 异常处理策略
1. **转换异常处理**:
- 在实体类和VO类之间进行转换时捕获并处理可能的转换异常
- 提供清晰的错误信息,指明转换失败的原因
2. **数据验证**:
- 在接收VO对象时进行数据验证确保数据的有效性
- 对于无效数据,抛出适当的异常并提供错误信息
3. **事务处理**:
- 保持原有的事务边界,确保数据操作的原子性
- 在事务中包含完整的数据操作和转换过程
4. **缓存异常**:
- 处理可能的缓存操作异常,确保即使缓存失败也不会影响业务逻辑
- 考虑添加缓存回退机制
- 特别处理Redis连接问题和序列化问题确保系统可用性
5. **序列化异常**:
- 处理VO对象序列化失败的情况
- 确保VO类实现Serializable接口避免在VO类中包含不可序列化的引用
6. **WebSocket服务异常处理**:
- 处理WebSocketServerCallbackManager中反射调用IEntityService接口时可能出现的类型转换异常
- 特别关注createNewEntity、findEntityTypeInInterfaces等依赖泛型参数的方法
- 确保WebSocket服务在接口泛型修改后能够正常处理异常情况
- 在invokerFindByIdMethod、invokerFindAllMethod等方法中添加类型安全检查
## 7. 设计原则
1. **最小化修改原则**: 仅修改必要的代码,避免不必要的重构
2. **向后兼容原则**: 尽量保持与原有系统的兼容性特别是对依赖这些Service的组件包括WebSocket服务
3. **数据一致性原则**: 确保实体类和VO类之间的数据转换不会导致数据丢失或不一致
4. **可测试性原则**: 设计支持单元测试和集成测试的代码结构包括WebSocket服务的测试
5. **性能优化原则**: 考虑数据转换可能带来的性能影响,必要时进行优化
6. **代码复用原则**: 尽量复用现有的代码和模式,特别是数据转换相关的代码
7. **序列化安全原则**: 确保所有缓存的VO对象都是可序列化的避免在VO对象中包含循环引用和不可序列化的组件
8. **类型安全原则**: 在WebSocketServerCallbackManager中添加类型安全检查确保能够正确处理从实体类到VO类的泛型变化
9. **服务兼容性原则**: 确保修改后的IEntityService接口能够与WebSocket服务和其他现有服务组件兼容
通过以上设计我们可以系统地完成IEntityService接口泛型的修改任务确保修改后的系统能够正确、高效地运行。