26日1738-FertilizerHandler优化.md 5.9 KB

FertilizerHandler优化

任务时间: 2025年05月26日 17:38
任务类型: 代码优化
涉及模块: AppGame, Farm, GameItems

任务需求

按照PesticideHandler模式优化FertilizerHandler:先验证再执行操作,创建必要的Validation和Validator类,在事务外进行验证。

核心思路

  • 验证逻辑分离:将所有验证逻辑从Handler和Logic层移到专门的Validation和Validator类中
  • 事务外验证:在事务开始前完成所有验证,减少事务时间
  • 防错误机制:Logic层保留基本检查,避免意外执行
  • 复用现有组件:使用已有的LandOwnershipValidator和ItemOwnershipValidator

实施内容

1. 创建FertilizerValidation类

文件: app/Module/Farm/Validations/FertilizerValidation.php

功能:

  • 统一验证逻辑的入口点
  • 定义验证规则和属性
  • 存储验证结果供后续使用

验证规则:

  • 用户ID、土地ID、物品ID必填且为正整数
  • 土地归属验证(LandOwnershipValidator)
  • 物品拥有验证(ItemOwnershipValidator)
  • 肥料类型验证(FertilizerItemValidator)
  • 使用条件验证(FertilizerUsageValidator)

2. 创建FertilizerItemValidator类

文件: app/Module/Farm/Validators/FertilizerItemValidator.php

功能:

  • 验证物品是否为有效的肥料
  • 获取肥料的crop_growth_time属性
  • 设置验证对象的属性供后续使用

验证逻辑:

// 检查物品是否存在
$item = Item::find($value);

// 获取肥料属性
$cropGrowthTime = ItemService::getItemNumericAttribute($value, 'crop_growth_time', 0);

// 验证是否为有效肥料(crop_growth_time > 0)
if ($cropGrowthTime <= 0) {
    return false;
}

3. 创建FertilizerUsageValidator类

文件: app/Module/Farm/Validators/FertilizerUsageValidator.php

功能:

  • 验证土地状态是否允许使用肥料
  • 验证作物生长阶段是否允许使用肥料
  • 验证是否已经使用过肥料

验证逻辑:

// 检查土地状态是否为种植中
if ($land->status !== LAND_STATUS::PLANTING->valueInt()) {
    return false;
}

// 检查作物生长阶段
if (!GROWTH_STAGE::canUseFertilizer($crop->growth_stage)) {
    return false;
}

// 检查是否已经使用过肥料
if ($crop->fertilized) {
    return false;
}

4. 更新FertilizerHandler

文件: app/Module/AppGame/Handler/Land/FertilizerHandler.php

主要变更:

  • 移除所有验证逻辑
  • 使用FertilizerValidation进行统一验证
  • 在事务中使用验证结果的数据,避免重复查询

关键代码:

// 使用FertilizerValidation进行数据验证
$validation = new FertilizerValidation();
if (!$validation->validate($validationData)) {
    throw new LogicException($validation->getErrors());
}

// 从验证结果中获取数据,避免重复查询
$cropGrowthTime = $validation->crop_growth_time;

// 在事务中执行操作
DB::beginTransaction();
$result = CropService::useFertilizer($userId, $landId, $cropGrowthTime);

5. 优化CropLogic::useFertilizer

文件: app/Module/Farm/Logics/CropLogic.php

主要变更:

  • 移除所有验证逻辑
  • 保留防错误机制:基本存在性检查
  • 使用警告日志记录异常状态但继续执行

关键代码:

// 防错误机制:基本状态检查,避免意外执行
if ($land->status !== LAND_STATUS::PLANTING->valueInt()) {
    Log::warning('土地状态异常,但继续执行施肥', [
        'land_id' => $landId,
        'expected_status' => LAND_STATUS::PLANTING->valueInt(),
        'actual_status' => $land->status
    ]);
}

if ($crop->fertilized) {
    Log::warning('作物已施肥,但继续执行', [
        'crop_id' => $crop->id,
        'fertilized' => $crop->fertilized
    ]);
}

优化效果

1. 验证逻辑分离

  • 统一验证:所有验证逻辑集中在Validation和Validator中
  • 可复用性:Validator可以在其他地方复用
  • 易于测试:验证逻辑独立,便于单元测试

2. 事务优化

  • 事务外验证:所有验证在事务外完成,减少事务时间
  • 避免重复查询:验证结果中的对象可以直接使用
  • 提高性能:减少数据库查询和事务锁定时间

3. 错误处理改进

  • 防错误机制:Logic层保留基本检查,避免意外执行
  • 详细日志:记录异常状态但继续执行,便于问题排查
  • 优雅降级:即使验证有遗漏,系统也能正常运行

4. 代码质量提升

  • 职责分离:Handler负责流程控制,Validator负责验证,Logic负责业务逻辑
  • 可维护性:代码结构清晰,易于维护和扩展
  • 一致性:与PesticideHandler保持一致的架构模式

技术细节

Validator继承关系

  • 使用 UCore\Validator 作为基类
  • 实现 validate(mixed $value, array $data): bool 方法
  • 通过 $this->args 获取参数配置
  • 通过 $this->validation 设置验证结果

验证规则配置

[
    'land_id', LandOwnershipValidator::class, 'args' => ['user_id', 'land'],
    'msg' => '土地不存在或不属于当前用户'
],
[
    'item_id', FertilizerItemValidator::class, 'args' => ['fertilizer_item', 'crop_growth_time'],
    'msg' => '该物品不是有效的肥料'
]

完成状态

  • 创建 FertilizerValidation 统一验证类
  • 创建 FertilizerItemValidator 肥料物品验证器
  • 创建 FertilizerUsageValidator 肥料使用验证器
  • 更新 FertilizerHandler 使用新的验证模式
  • 优化 CropLogic::useFertilizer 移除验证逻辑,保留防错误机制
  • 代码提交和推送

总结

本次优化成功实现了FertilizerHandler的验证逻辑分离,提高了代码的可维护性和性能。通过在事务外进行验证,减少了事务时间;通过防错误机制,确保了系统的稳定性。整体架构与PesticideHandler保持一致,提高了代码的一致性。