如何重构嵌套if-else语句?怪物属性映射场景的可扩展实现问询
优化怪物属性匹配逻辑的方案
问题背景
现有怪物属性与结果的映射表如下:
| Gender | Age | Type | Result |
|---|---|---|---|
| Male | Young | Fire | 1 |
| Male | Old | Ice | 2 |
| Male | Old | Wood | 6 |
| Female | Young | Fire | 4 |
| Female | Old | Ice | 5 |
| Female | Old | Wood | 8 |
| Other | Young | Fire | 7 |
| Other | Old | Ice | 10 |
| Other | Old | Wood | 20 |
需要根据输入的怪物对象获取对应的Result值,但直接编写嵌套if-else会导致代码臃肿、难以维护(示例如下),同时希望实现可扩展性,支持未来新增属性列、调整校验逻辑顺序等需求。
if(monster.Gender == Male && monster.Age == Old) if(monster.Type == Ice) return 2 if(monster.Type == Wood) return 6 if(monster.Gender == Male && monster.Age == Young) etc...
解决方案
1. 复合键映射表(最直接的简化方式)
把怪物的多个属性组合成一个唯一的"复合键",用字典/哈希表存储键与Result的对应关系。比如可以用性别-年龄-类型拼接的字符串,或者语言支持的元组作为键。
示例代码(Python):
# 提前定义好映射关系 result_map = { ("Male", "Young", "Fire"): 1, ("Male", "Old", "Ice"): 2, ("Male", "Old", "Wood"): 6, ("Female", "Young", "Fire"): 4, ("Female", "Old", "Ice"): 5, ("Female", "Old", "Wood"): 8, ("Other", "Young", "Fire"): 7, ("Other", "Old", "Ice"): 10, ("Other", "Old", "Wood"): 20 } def get_monster_result(monster): # 生成当前怪物的复合键 key = (monster.Gender, monster.Age, monster.Type) # 从映射表取结果,无匹配时返回None或自定义默认值 return result_map.get(key, None)
这种方式的好处是代码极简,新增规则只需要往映射表里加条目,调整规则顺序也不需要改逻辑。如果未来新增属性列,只需要扩展复合键的维度即可。
2. 策略模式拆分规则(复杂场景适配)
如果之后需要更复杂的规则(比如属性值范围匹配、多条件优先级调整),可以用策略模式把每个判断逻辑拆成独立模块:
- 定义一个规则接口,包含匹配方法和结果方法
- 每个规则对应一个实现类,封装自己的匹配逻辑和返回结果
- 把所有规则存入列表,遍历找到第一个匹配的规则返回结果
示例代码(Java风格伪代码):
// 规则接口,所有规则都要实现这个接口 interface MonsterRule { boolean match(Monster monster); int getResult(); } // 具体规则示例:Male+Old+Ice的情况 class MaleOldIceRule implements MonsterRule { @Override public boolean match(Monster monster) { return "Male".equals(monster.getGender()) && "Old".equals(monster.getAge()) && "Ice".equals(monster.getType()); } @Override public int getResult() { return 2; } } // 规则管理器,负责存储和匹配规则 class MonsterRuleManager { private List<MonsterRule> rules = new ArrayList<>(); // 添加规则,调整添加顺序就能改变规则优先级 public void addRule(MonsterRule rule) { rules.add(rule); } public int getResult(Monster monster) { for (MonsterRule rule : rules) { if (rule.match(monster)) { return rule.getResult(); } } return -1; // 无匹配时返回默认值 } }
这种方式的优势是每个规则独立,新增规则只需要写新的实现类,调整优先级只需要改变添加规则的顺序,适合规则逻辑复杂、需要动态调整的场景。
3. 配置化驱动(极致扩展性)
把规则和结果存入JSON、YAML这类配置文件里,程序启动时加载配置并构建映射表或规则列表。比如JSON配置示例:
[ {"gender": "Male", "age": "Young", "type": "Fire", "result": 1}, {"gender": "Male", "age": "Old", "type": "Ice", "result": 2}, {"gender": "Male", "age": "Old", "type": "Wood", "result": 6}, {"gender": "Female", "age": "Young", "type": "Fire", "result": 4}, {"gender": "Female", "age": "Old", "type": "Ice", "result": 5}, {"gender": "Female", "age": "Old", "type": "Wood", "result": 8}, {"gender": "Other", "age": "Young", "type": "Fire", "result": 7}, {"gender": "Other", "age": "Old", "type": "Ice", "result": 10}, {"gender": "Other", "age": "Old", "type": "Wood", "result": 20} ]
程序加载配置后,要么转换成复合键映射表,要么动态生成规则对象。这种方式不需要修改代码就能新增或调整规则,适合规则频繁变更的场景。
内容的提问来源于stack exchange,提问作者user19911101
相关产品推荐
相关产品推荐

