091956-Game模块奖励类型处理逻辑统一优化.md 5.9 KB

Game模块奖励类型处理逻辑统一优化

时间: 2025年06月09日 19:56
任务类型: 代码重构
状态: 已完成

任务描述

Game模块中存在多处$rewardType类型判断的重复性硬编码,用于处理奖励描述等工作,不利于维护。需要进行统一处理,消除重复代码,提升代码维护性。

问题分析

发现的问题

  1. 奖励类型判断重复:在多个类中都有相似的switch语句来处理不同奖励类型
  2. 目标名称获取重复getTargetName方法在多个类中重复实现
  3. 奖励描述生成重复:格式化奖励显示的逻辑分散在各个地方
  4. 皮肤名称硬编码:皮肤相关的名称和验证逻辑重复出现,且存在捏造的名称

涉及的文件

  • app/Module/Game/Models/GameRewardGroup.php
  • app/Module/Game/Models/GameRewardItem.php
  • app/Module/Game/AdminControllers/Actions/RandomRewardAction.php
  • app/Module/Game/AdminControllers/LazyRenderable/RandomRewardResultLazyRenderable.php
  • app/Module/Game/AdminControllers/GameRewardGroupController.php
  • app/Module/Game/AdminControllers/GameRewardItemController.php
  • app/Module/Game/Services/RewardGroupService.php

解决方案

1. 创建统一的奖励类型描述器

1.1 RewardTypeDescriptor服务类

文件: app/Module/Game/Services/RewardTypeDescriptor.php

主要功能:

  • 统一处理所有奖励类型的名称获取
  • 统一处理目标名称的获取逻辑
  • 统一处理奖励描述的格式化
  • 支持从DTO和Model两种数据源获取信息

核心方法:

// 获取奖励目标名称
public static function getTargetName(int $rewardType, int $targetId, int $param1 = 0, int $param2 = 0): string

// 从RewardItemDto获取目标名称
public static function getTargetNameFromDto(RewardItemDto $item): string

// 从GameRewardItem模型获取目标名称
public static function getTargetNameFromModel(GameRewardItem $item): string

// 格式化奖励项显示
public static function formatRewardDisplay(int $rewardType, int $targetId, int $quantity, int $param1 = 0, int $param2 = 0, bool $withBadge = true): string

// 格式化数量文本(支持随机数量)
public static function formatQuantityText(GameRewardItem $item): string

1.2 扩展REWARD_TYPE枚举

文件: app/Module/Game/Enums/REWARD_TYPE.php

新增功能:

// 获取奖励类型的详细信息
public static function getTypeInfo(int $type): array

提供每种奖励类型的详细描述信息,包括:

  • 名称和描述
  • 目标字段含义
  • 参数字段含义

2. 重构现有代码

2.1 模型层重构

  • GameRewardGroup: 删除重复的getTargetNameformatQuantityText方法,使用统一描述器
  • GameRewardItem: 简化getTargetName方法,直接调用描述器

2.2 AdminController重构

  • RandomRewardAction: 简化formatRewardItems方法,删除重复的getTargetName方法
  • RandomRewardResultLazyRenderable: 使用统一描述器替换重复逻辑
  • GameRewardGroupController: 使用统一描述器处理奖励显示
  • GameRewardItemController: 简化目标名称显示逻辑

2.3 服务层重构

  • RewardGroupService: 删除大量重复的if-else判断,使用统一描述器

3. 修复皮肤名称问题

3.1 问题发现

原代码中存在硬编码的皮肤名称:

  • "春日皮肤"
  • "夏日皮肤"
  • "秋日皮肤"

这些名称是捏造的,不符合SKIN枚举的实际定义。

3.2 解决方案

修改皮肤名称获取逻辑,使用SKIN枚举的正确方法:

修改前:

return [
    1 => '默认皮肤',
    2 => '春日皮肤',
    3 => '夏日皮肤',
    4 => '秋日皮肤',
];

修改后:

return \App\Module\Game\Enums\SKIN::getValueDescription();

这样会根据SKIN枚举中的注释自动生成正确的皮肤名称:

  • SKIN1 (1) => "默认皮肤"
  • SKIN2 (2) => "皮肤2"
  • SKIN3 (3) => "皮肤3"
  • SKIN4 (4) => "皮肤4"

实现效果

1. 代码简化

  • 删除了9个文件中的重复代码
  • 消除了约200行重复的switch语句和if-else判断
  • 统一了奖励类型处理标准

2. 维护性提升

  • 新增奖励类型时,只需在RewardTypeDescriptor中添加一个case
  • 奖励显示逻辑统一,修改时只需改一处
  • 消除了硬编码,提升了代码的可维护性

3. 一致性保证

  • 所有奖励显示都使用相同的格式化逻辑
  • 皮肤名称使用枚举定义,避免捏造名称
  • 统一的错误处理和异常捕获

4. 性能优化

  • 减少了重复的数据库查询
  • 统一的缓存策略(如需要)
  • 更高效的代码执行路径

技术细节

1. 设计模式

  • 策略模式: 不同奖励类型使用不同的处理策略
  • 工厂模式: 统一创建奖励描述对象
  • 单一职责原则: 每个方法只负责一种功能

2. 兼容性

  • 保持了原有的API接口不变
  • 向后兼容现有的调用方式
  • 渐进式重构,不影响现有功能

3. 扩展性

  • 新增奖励类型时扩展简单
  • 支持复杂的奖励描述逻辑
  • 预留了参数扩展空间

测试验证

1. 功能测试

  • 验证所有奖励类型的名称获取正确
  • 验证奖励显示格式化正常
  • 验证皮肤名称使用枚举定义

2. 兼容性测试

  • 确保现有功能不受影响
  • 验证后台管理页面显示正常
  • 确认API返回数据格式一致

总结

本次重构成功解决了Game模块中奖励类型处理的重复性硬编码问题:

  1. 创建了统一的RewardTypeDescriptor,集中处理所有奖励类型相关逻辑
  2. 重构了9个相关文件,消除了大量重复代码
  3. 修复了皮肤名称问题,使用枚举定义而非捏造名称
  4. 提升了代码维护性,新增奖励类型时只需修改一处
  5. 保持了向后兼容性,不影响现有功能

这次重构为后续的功能开发和维护奠定了良好的基础,体现了"DRY(Don't Repeat Yourself)"原则的重要性。