# 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, QueryService, VoableService { // Service方法实现 } @Service @CacheConfig(cacheNames = "function") public class FunctionService implements IEntityService, QueryService, VoableService { @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 implements IEntityService, QueryService, VoableService { // Service方法实现 } @Service public class CompanyBlackReasonService implements IEntityService, QueryService, VoableService { // 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改为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对象而不是实体对象,从而提高系统的一致性和性能。 本报告为后续的子任务提供了具体的修改依据,帮助确定具体的实现方案和步骤。