8.4 KiB
8.4 KiB
Contract-Manager 项目 Service 层合规性分析报告
概述
本报告对 Contract-Manager 项目中 client\src\main\java\com\ecep\contract\service 目录下的 Service 实现进行分析,评估它们是否符合 docs\task\service_layer_rules.md 文档中定义的规则和最佳实践。
合规性评估
1. 基础架构
1.1 继承体系
- 符合: 大多数业务 Service 都继承自泛型抽象类
QueryService<T extends IdentityEntity, TV extends IdentityViewModel<T>>- 例如:
CompanyFileTypeService,ContractService,CompanyService,ProjectService,VendorService
- 例如:
- 不符合:
SysConfService没有继承QueryService,而是直接实现了自己的异步调用方法
1.2 核心接口实现
- 符合: 继承
QueryService的 Service 间接实现了IEntityService<T>和ViewModelService<T, TV>接口
2. 缓存管理
2.1 缓存注解使用
- 符合: 许多 Service 使用了
@CacheConfig和相关缓存注解@CacheConfig(cacheNames = "缓存名称"):ContractFileTypeService,ProjectFileTypeService,ContractService,CompanyService,SysConfService@Cacheable: 用于findById,findAll,findByCode等查询方法@CachePut/@CacheEvict: 用于save,delete等修改方法@Caching: 用于组合多个缓存操作
- 不符合: 部分 Service 未使用缓存注解
VendorService,ProjectService没有配置缓存
2.2 缓存键规则
- 符合: 缓存键的使用基本符合规则
#p0: 用于方法参数,如@Cacheable(key = "#p0")'all': 用于所有数据,如@Cacheable(key = "'all'")- 组合键: 如
@Cacheable(key = "'code-'+#p0")
3. 数据操作模式
3.1 基础 CRUD 操作
- 符合: 所有继承
QueryService的 Service 都获得了基础 CRUD 操作findById(Integer id): 根据 ID 查询单条数据save(T entity): 保存实体delete(T entity): 删除实体findAll(): 查询所有数据findAll(Map<String, Object> params, Pageable pageable): 带参数和分页的查询
3.2 异步操作
- 符合: 大多数 Service 使用
QueryService提供的异步机制- 通过
async(String method, Object... params)方法实现异步调用 - 返回
CompletableFuture<JsonNode>对象
- 通过
- 不符合:
SysConfService实现了自己的异步方法,如asyncFindById,asyncFindAll
3.3 业务查询方法
- 符合: 业务 Service 通常添加特定的查询方法
findByCode(String code):ContractService,CompanyService,ProjectServicefindByName(String name):ContractService,CompanyService,ProjectServicefindAllByName(String name):CompanyService
3.4 参数构建
- 符合: 普遍使用
ParamUtils工具类构建查询参数ParamUtils.builder().equals("字段名", 值).build()ParamUtils.equal("字段名", 值)
4. 国际化支持
4.1 多语言查询
- 符合: 文件类型相关 Service 提供了基于 Locale 的查询方法
findAll(Locale locale):ContractFileTypeService,ProjectFileTypeService,CompanyFileTypeService,CompanyCustomerFileTypeService- 通过
locale.toLanguageTag()转换为语言标签进行查询 - 返回结果通常转换为 Map,方便按类型查找
- 不适用: 对于不需要国际化的业务 Service,没有提供这些方法
4.2 辅助方法
- 符合: 文件类型相关 Service 实现了辅助方法
findOneByLang(Locale locale, String key, Object value): 私有辅助方法findByLocaleAndValue(Locale locale, String string): 按语言和值查询findByLocaleAndType(Locale locale, EnumType type): 按语言和枚举类型查询
- 不适用: 对于不需要国际化的业务 Service,没有提供这些方法
5. 类型转换
5.1 StringConverter 实现
- 符合: 实体类型 Service 实现了
getStringConverter()方法- 返回
StringConverter<T>实例 - 创建专门的 Converter 类,如
ContractFileTypeStringConverter,ProjectFileTypeStringConverter
- 返回
- 不符合: 业务对象 Service 如
ContractService,CompanyService,VendorService,ProjectService没有实现getStringConverter()方法
6. 业务特性
6.1 文件路径管理
- 符合: 部分 Service 管理文件路径
getBasePath()方法:ContractService,CompanyService,VendorService,ProjectService- 通过
SysConfService获取配置的基础路径 - 路径存储为
File对象
6.2 业务验证
- 符合: 包含业务特定的验证逻辑
verifyEnterpriseStatus(CompanyVo company, LocalDate verifyDate, MessageHolder holder):CompanyServiceverify(ContractVo contract, MessageHolder holder):VendorService- 使用
MessageHolder存储验证结果和错误信息
6.3 Spring Bean 获取
- 符合: 使用
SpringApp.getBean(ServiceClass.class)获取其他 Service 实例- 例如
VendorService中获取SysConfService,ProjectService中获取ProjectSaleTypeService
- 例如
7. 代码规范
7.1 类命名
- 符合: 服务类名以
Service结尾ContractService,CompanyService,ProjectService等- 实现类直接使用业务名称+Service,无 I 前缀
7.2 注释规范
- 部分符合: 大部分类和方法有 Javadoc 注释
- 例如
ContractService.getBasePath()方法有清晰的注释
- 例如
- 不符合: 部分方法缺少注释
- 例如
VendorService.findByCompany()方法没有注释 - 许多未实现的方法只有 TODO 注释
- 例如
7.3 异常处理
- 符合: 使用
RuntimeException包装异常- 异常消息清晰描述错误情况
- 不符合:
SysConfService中有些异常处理直接打印堆栈,没有抛出自定义异常
8. 特定业务 Service 模式
8.1 实体类型 Service
- 符合: 如
ContractFileTypeService,ProjectFileTypeService等- 管理枚举类型的本地化数据
- 提供缓存管理
- 实现 StringConverter
- 提供基于 Locale 的查询方法
8.2 业务对象 Service
- 符合: 如
ContractService,CompanyService,ProjectService等- 管理核心业务实体
- 实现特定的业务逻辑
- 处理文件和路径
- 提供业务验证
8.3 关联关系管理
- 符合: Service 之间通过依赖注入或
SpringApp.getBean()进行协作- 处理实体之间的关联关系
9. 特殊实现模式
9.1 自定义 BeanName
- 符合: 部分 Service 重写
getBeanName()方法- 例如
CompanyService指定 WebSocket 通信的 Bean 名称
- 例如
9.2 未实现方法
- 符合: 使用
throw new UnsupportedOperationException("Unimplemented method 'methodName'")标记未实现的方法- 例如
CompanyService.merge(),VendorService.getVendorApprovedListTemplate()等
- 例如
9.3 分页查询
- 符合: 大量使用
Pageable.ofSize(1)进行单条记录的精确查询- 使用
stream().findFirst().orElse(null)提取结果 - 例如
ProjectService.findByName(),ProjectService.findByCode()
- 使用
不符合规范的 Service 列表
| Service 类名 | 不符合项 | 建议改进 |
|---|---|---|
SysConfService |
未继承 QueryService,实现了自己的异步方法 |
重构为继承 QueryService,使用标准的异步方法 |
VendorService |
未使用缓存注解 | 添加 @CacheConfig 和相关缓存注解 |
ProjectService |
未使用缓存注解 | 添加 @CacheConfig 和相关缓存注解 |
| 业务对象 Service | 没有实现 getStringConverter() 方法 |
如果需要类型转换,实现该方法 |
| 多个 Service | 部分方法缺少注释 | 完善 Javadoc 注释 |
SysConfService |
异常处理不统一 | 统一使用 RuntimeException 包装异常 |
总结
Contract-Manager 项目的 Service 层实现整体上符合 service_layer_rules.md 文档中定义的规则和最佳实践。大多数 Service 遵循了基础架构、缓存管理、数据操作模式等规范,特别是实体类型 Service 的实现非常一致。
主要的改进点包括:
- 统一 Service 的继承体系,确保所有 Service 都继承自
QueryService - 为所有 Service 添加适当的缓存管理
- 完善方法注释,提高代码可读性
- 统一异常处理机制
- 根据业务需求,为需要类型转换的 Service 实现
getStringConverter()方法
通过这些改进,可以进一步提高项目的代码一致性、可维护性和性能。