重构Service类实现,将QueryService泛型参数调整为VO类型,确保缓存VO对象而非实体。优化关联实体处理逻辑,减少重复代码。修改findById方法返回VO对象,新增getById方法获取实体。更新相关调用点以适配新接口。 调整WebSocket处理、控制器及Service实现,确保数据类型一致性。完善文档记录重构过程及发现的问题。为后续优化提供基础架构支持。
6.6 KiB
6.6 KiB
Service类结构模式分析报告
1. 概述
本报告是"实体-VO转换机制与缓存策略任务拆分"子任务1的延伸分析,旨在详细分析Contract-Manager项目中Service类的实现模式,特别是QueryService接口泛型参数的使用情况,为将Server模块Service缓存从实体对象调整为VO对象提供具体的修改依据。
2. Service类实现模式分析
通过对Server模块中Service类的分析,发现了两种主要的实现模式:
2.1 模式一:正确实现模式(VO优先)
这种模式下,Service类实现QueryService接口时使用VO类型作为泛型参数,符合项目设计理念。
示例代码:
@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);
}
}
特点:
- QueryService接口使用VO类型作为泛型参数
- findById等缓存方法返回VO对象
- findAll方法通常使用map(Entity::toVo)转换为VO对象
- 缓存的是VO对象,符合设计要求
采用此模式的Service类:
- InventoryService
- ProjectQuotationService
- FunctionService
- DepartmentService
- BankService
- ContractBidVendorService
- ProjectIndustryService
- ProjectBidService
- ProjectFundPlanService
- InventoryHistoryPriceService
- ProjectTypeService
- PermissionService
- ProjectCostItemService
- EmployeeRoleService
- CustomerSatisfactionSurveyService
2.2 模式二:错误实现模式(实体优先)
这种模式下,Service类实现QueryService接口时使用实体类型作为泛型参数,不符合项目设计理念。
示例代码:
@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方法实现
}
特点:
- QueryService接口使用实体类型作为泛型参数
- findById等缓存方法返回实体对象
- 缓存的是实体对象,不符合设计要求
- 虽然同时实现了VoableService接口,但转换逻辑与缓存逻辑分离
采用此模式的Service类:
- CompanyService
- CompanyBlackReasonService
- ContractPayPlanService
- CompanyOldNameService
- CompanyCustomerEntityService
- ContractCatalogService
- CompanyInvoiceInfoService
- CompanyExtendInfoService
3. WebSocketServerCallbackManager分析
WebSocketServerCallbackManager类负责处理客户端与服务器之间的WebSocket通信,包括对查询服务的调用处理:
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;
}));
}
关键点:
- invokerFindByIdMethod直接返回实体对象,没有进行VO转换
- invokerFindAllMethod在返回前会尝试将实体转换为VO
- 这种不一致的处理方式可能导致客户端接收的数据类型不一致
4. 缓存策略分析
4.1 正确的缓存策略(模式一)
@Cacheable(key = "#p0")
public FunctionVo findById(Integer id) {
return repository.findById(id).map(Function::toVo).orElse(null);
}
特点:
- 缓存方法直接返回VO对象
- 在缓存方法内部完成实体到VO的转换
- 缓存的是VO对象,符合设计要求
4.2 错误的缓存策略(模式二)
@Cacheable(key = "#id")
public Contract findById(Integer id) {
// 直接返回实体对象
}
特点:
- 缓存方法返回实体对象
- 缓存的是实体对象,不符合设计要求
- 客户端可能需要额外的转换步骤
5. 需要修改的Service类清单
基于以上分析,以下是需要修改的Service类清单:
| Service类名 | 问题 | 修改建议 |
|---|---|---|
| CompanyService | QueryService使用实体类型 | 将QueryService改为QueryService |
| CompanyBlackReasonService | QueryService使用实体类型 | 将QueryService改为QueryService |
| ContractPayPlanService | QueryService使用实体类型 | 将QueryService改为QueryService |
| CompanyOldNameService | QueryService使用实体类型 | 将QueryService改为QueryService |
| CompanyCustomerEntityService | QueryService使用实体类型 | 将QueryService改为QueryService |
| ContractCatalogService | QueryService使用实体类型 | 将QueryService改为QueryService |
| CompanyInvoiceInfoService | QueryService使用实体类型 | 将QueryService改为QueryService |
| CompanyExtendInfoService | QueryService使用实体类型 | 将QueryService改为QueryService |
6. 结论
通过对Service类实现模式的详细分析,我们明确了需要修改的Service类清单和具体的修改建议。这些修改将有助于统一Service类的实现模式,确保缓存的是VO对象而不是实体对象,从而提高系统的一致性和性能。
本报告为后续的子任务提供了具体的修改依据,帮助确定具体的实现方案和步骤。