refactor(service): 统一Service缓存为VO对象并优化关联实体处理
重构Service类实现,将QueryService泛型参数调整为VO类型,确保缓存VO对象而非实体。优化关联实体处理逻辑,减少重复代码。修改findById方法返回VO对象,新增getById方法获取实体。更新相关调用点以适配新接口。 调整WebSocket处理、控制器及Service实现,确保数据类型一致性。完善文档记录重构过程及发现的问题。为后续优化提供基础架构支持。
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
# Service类结构模式分析报告
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本报告是"实体-VO转换机制与缓存策略任务拆分"子任务1的延伸分析,旨在详细分析Contract-Manager项目中Service类的实现模式,特别是QueryService接口泛型参数的使用情况,为将Server模块Service缓存从实体对象调整为VO对象提供具体的修改依据。
|
||||
|
||||
## 2. Service类实现模式分析
|
||||
|
||||
通过对Server模块中Service类的分析,发现了两种主要的实现模式:
|
||||
|
||||
### 2.1 模式一:正确实现模式(VO优先)
|
||||
|
||||
这种模式下,Service类实现QueryService接口时使用VO类型作为泛型参数,符合项目设计理念。
|
||||
|
||||
**示例代码:**
|
||||
|
||||
```java
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "inventory")
|
||||
public class InventoryService
|
||||
implements IEntityService<Inventory>, QueryService<InventoryVo>, VoableService<Inventory, InventoryVo> {
|
||||
// Service方法实现
|
||||
}
|
||||
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "function")
|
||||
public class FunctionService implements IEntityService<Function>, QueryService<FunctionVo>, VoableService<Function, FunctionVo> {
|
||||
@Cacheable(key = "#p0")
|
||||
public FunctionVo findById(Integer id) {
|
||||
return repository.findById(id).map(Function::toVo).orElse(null);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**特点:**
|
||||
1. QueryService接口使用VO类型作为泛型参数
|
||||
2. findById等缓存方法返回VO对象
|
||||
3. findAll方法通常使用map(Entity::toVo)转换为VO对象
|
||||
4. 缓存的是VO对象,符合设计要求
|
||||
|
||||
**采用此模式的Service类:**
|
||||
- InventoryService
|
||||
- ProjectQuotationService
|
||||
- FunctionService
|
||||
- DepartmentService
|
||||
- BankService
|
||||
- ContractBidVendorService
|
||||
- ProjectIndustryService
|
||||
- ProjectBidService
|
||||
- ProjectFundPlanService
|
||||
- InventoryHistoryPriceService
|
||||
- ProjectTypeService
|
||||
- PermissionService
|
||||
- ProjectCostItemService
|
||||
- EmployeeRoleService
|
||||
- CustomerSatisfactionSurveyService
|
||||
|
||||
### 2.2 模式二:错误实现模式(实体优先)
|
||||
|
||||
这种模式下,Service类实现QueryService接口时使用实体类型作为泛型参数,不符合项目设计理念。
|
||||
|
||||
**示例代码:**
|
||||
|
||||
```java
|
||||
@Service
|
||||
@CacheConfig(cacheNames = "company")
|
||||
public class CompanyService extends EntityService<Company, Integer>
|
||||
implements IEntityService<Company>, QueryService<Company>, VoableService<Company, CompanyVo> {
|
||||
// Service方法实现
|
||||
}
|
||||
|
||||
@Service
|
||||
public class CompanyBlackReasonService implements IEntityService<CompanyBlackReason>, QueryService<CompanyBlackReason>,
|
||||
VoableService<CompanyBlackReason, CompanyBlackReasonVo> {
|
||||
// Service方法实现
|
||||
}
|
||||
```
|
||||
|
||||
**特点:**
|
||||
1. QueryService接口使用实体类型作为泛型参数
|
||||
2. findById等缓存方法返回实体对象
|
||||
3. 缓存的是实体对象,不符合设计要求
|
||||
4. 虽然同时实现了VoableService接口,但转换逻辑与缓存逻辑分离
|
||||
|
||||
**采用此模式的Service类:**
|
||||
- CompanyService
|
||||
- CompanyBlackReasonService
|
||||
- ContractPayPlanService
|
||||
- CompanyOldNameService
|
||||
- CompanyCustomerEntityService
|
||||
- ContractCatalogService
|
||||
- CompanyInvoiceInfoService
|
||||
- CompanyExtendInfoService
|
||||
|
||||
## 3. WebSocketServerCallbackManager分析
|
||||
|
||||
WebSocketServerCallbackManager类负责处理客户端与服务器之间的WebSocket通信,包括对查询服务的调用处理:
|
||||
|
||||
```java
|
||||
private Object invokerFindByIdMethod(Object service, JsonNode argumentsNode) {
|
||||
JsonNode paramsNode = argumentsNode.get(0);
|
||||
if (service instanceof IEntityService<?> entityService) {
|
||||
Integer id = paramsNode.asInt();
|
||||
return entityService.getById(id);
|
||||
}
|
||||
// 其他实现...
|
||||
}
|
||||
|
||||
private Object invokerFindAllMethod(Object service, JsonNode argumentsNode) throws JsonProcessingException {
|
||||
JsonNode paramsNode = argumentsNode.get(0);
|
||||
JsonNode pageableNode = argumentsNode.get(1);
|
||||
PageArgument pageArgument = objectMapper.treeToValue(pageableNode, PageArgument.class);
|
||||
QueryService<?> entityService = (QueryService<?>) service;
|
||||
Page<?> page = entityService.findAll(paramsNode, pageArgument.toPageable());
|
||||
return PageContent.of(page.map(entity -> {
|
||||
if (entity instanceof Voable<?>) {
|
||||
return ((Voable<?>) entity).toVo();
|
||||
}
|
||||
return entity;
|
||||
}));
|
||||
}
|
||||
```
|
||||
|
||||
**关键点:**
|
||||
1. invokerFindByIdMethod直接返回实体对象,没有进行VO转换
|
||||
2. invokerFindAllMethod在返回前会尝试将实体转换为VO
|
||||
3. 这种不一致的处理方式可能导致客户端接收的数据类型不一致
|
||||
|
||||
## 4. 缓存策略分析
|
||||
|
||||
### 4.1 正确的缓存策略(模式一)
|
||||
|
||||
```java
|
||||
@Cacheable(key = "#p0")
|
||||
public FunctionVo findById(Integer id) {
|
||||
return repository.findById(id).map(Function::toVo).orElse(null);
|
||||
}
|
||||
```
|
||||
|
||||
**特点:**
|
||||
1. 缓存方法直接返回VO对象
|
||||
2. 在缓存方法内部完成实体到VO的转换
|
||||
3. 缓存的是VO对象,符合设计要求
|
||||
|
||||
### 4.2 错误的缓存策略(模式二)
|
||||
|
||||
```java
|
||||
@Cacheable(key = "#id")
|
||||
public Contract findById(Integer id) {
|
||||
// 直接返回实体对象
|
||||
}
|
||||
```
|
||||
|
||||
**特点:**
|
||||
1. 缓存方法返回实体对象
|
||||
2. 缓存的是实体对象,不符合设计要求
|
||||
3. 客户端可能需要额外的转换步骤
|
||||
|
||||
## 5. 需要修改的Service类清单
|
||||
|
||||
基于以上分析,以下是需要修改的Service类清单:
|
||||
|
||||
| Service类名 | 问题 | 修改建议 |
|
||||
|------------|------|---------|
|
||||
| CompanyService | QueryService使用实体类型 | 将QueryService<Company>改为QueryService<CompanyVo> |
|
||||
| CompanyBlackReasonService | QueryService使用实体类型 | 将QueryService<CompanyBlackReason>改为QueryService<CompanyBlackReasonVo> |
|
||||
| ContractPayPlanService | QueryService使用实体类型 | 将QueryService<ContractPayPlan>改为QueryService<ContractPayPlanVo> |
|
||||
| CompanyOldNameService | QueryService使用实体类型 | 将QueryService<CompanyOldName>改为QueryService<CompanyOldNameVo> |
|
||||
| CompanyCustomerEntityService | QueryService使用实体类型 | 将QueryService<CompanyCustomerEntity>改为QueryService<CompanyCustomerEntityVo> |
|
||||
| ContractCatalogService | QueryService使用实体类型 | 将QueryService<ContractCatalog>改为QueryService<ContractCatalogVo> |
|
||||
| CompanyInvoiceInfoService | QueryService使用实体类型 | 将QueryService<CompanyInvoiceInfo>改为QueryService<CompanyInvoiceInfoVo> |
|
||||
| CompanyExtendInfoService | QueryService使用实体类型 | 将QueryService<CompanyExtendInfo>改为QueryService<CompanyExtendInfoVo> |
|
||||
|
||||
## 6. 结论
|
||||
|
||||
通过对Service类实现模式的详细分析,我们明确了需要修改的Service类清单和具体的修改建议。这些修改将有助于统一Service类的实现模式,确保缓存的是VO对象而不是实体对象,从而提高系统的一致性和性能。
|
||||
|
||||
本报告为后续的子任务提供了具体的修改依据,帮助确定具体的实现方案和步骤。
|
||||
Reference in New Issue
Block a user