我有这段代码:
public void addSkillXp(SkillType attribute, int value) {
final SkillDatabaseEntity skillDatabaseEntity = skillValueCache.getEntity();
switch (attribute) {
case TWO_HANDED_CRUSHING_WEAPONS:
skillDatabaseEntity.setTwoHandedCrushingWeaponsXp(value);
skillMapper.addTwoHandedCrushingWeaponsXp(userEntity.getId(), value);
break;
case ONE_HANDED_CRUSHING_WEAPONS:
skillDatabaseEntity.setOneHandedCrushingWeaponsXp(value);
skillMapper.addOneHandedCrushingWeaponsXp(userEntity.getId(), value);
break;
case TWO_HANDED_AXES:
skillDatabaseEntity.setTwoHandedAxesXp(value);
skillMapper.addTwoHandedAxesXp(userEntity.getId(), value);
break;
case ONE_HANDED_AXES:
skillDatabaseEntity.setOneHandedAxesXp(value);
skillMapper.addOneHandedAxesXp(userEntity.getId(), value);
break;
case THROWING_WEAPONS:
skillDatabaseEntity.setThrowingWeaponsXp(value);
skillMapper.addThrowingWeaponsXp(userEntity.getId(), value);
break;
case FISTFIGHT:
skillDatabaseEntity.setFistfightXp(value);
skillMapper.addFistfightXp(userEntity.getId(), value);
break;
...
}
开关继续进行20多例。 SkillDatabaseEntity是一个简单的DAO类:
public class SkillDatabaseEntity {
private int twoHandedCrushingWeaponsXp;
private int oneHandedCrushingWeaponsXp;
private int twoHandedAxesXp;
private int oneHandedAxesXp;
private int throwingWeaponsXp;
private int fistfightXp;
private int longswordsXp;
private int shortswordsXp;
private int polearmsXp;
private int daggersXp;
private int longbowsXp;
private int showrtbowsXp;
private int crossbowsXp;
private int lightArmorXp;
private int heavyArmorXp;
private int robeArmorXp;
private int armorlessDefenseXp;
private int shieldDefenseXp;
private int staffsXp;
private int wandsXp;
private int spectresXp;
private int scavengingXp;
private int cookingXp;
public int getTwoHandedCrushingWeaponsXp() {
return twoHandedCrushingWeaponsXp;
}
public void setTwoHandedCrushingWeaponsXp(int twoHandedCrushingWeaponsXp) {
this.twoHandedCrushingWeaponsXp = twoHandedCrushingWeaponsXp;
}
public int getOneHandedCrushingWeaponsXp() {
return oneHandedCrushingWeaponsXp;
}
public void setOneHandedCrushingWeaponsXp(int oneHandedCrushingWeaponsXp) {
this.oneHandedCrushingWeaponsXp = oneHandedCrushingWeaponsXp;
}
public int getTwoHandedAxesXp() {
return twoHandedAxesXp;
}
public void setTwoHandedAxesXp(int twoHandedAxesXp) {
this.twoHandedAxesXp = twoHandedAxesXp;
}
public int getOneHandedAxesXp() {
return oneHandedAxesXp;
}
public void setOneHandedAxesXp(int oneHandedAxesXp) {
this.oneHandedAxesXp = oneHandedAxesXp;
}
public int getThrowingWeaponsXp() {
return throwingWeaponsXp;
}
public void setThrowingWeaponsXp(int throwingWeaponsXp) {
this.throwingWeaponsXp = throwingWeaponsXp;
}
...
}
我需要添加removeSkillXp,但我真的想避免这个巨大的开关,如果我在这里,我也希望改进那个旧的scwitch。我怎么能这样做?
我的计划是创建一个像这样的新类:
SkillModifier:
为交换机中的每个案例创建此类的实例,将实例添加到地图中(这可以通过Spring DI轻松完成)并使用以下内容:
public void addSkillXp(SkillType attribute, int value) {
skillMap.get(attribute).increaseExperience(userEntity, value);
}
这可以吗?或者有更好的模式吗?
答案 0 :(得分:1)
整个开关看起来多余,因为每个案例都做同样的事情。为什么不创建一个抽象类武器,它有一个方法increaseXP并且被每个武器类扩展(2h等)。
通过这种方式,实现在抽象类中,其他子类只调用.increaseXP。
顺便说一下数据库类似乎没必要,只需为每个玩家保留一份武器列表/数组。
更多背景信息请参阅:
https://sourcemaking.com/refactoring/replace-conditional-with-polymorphism
答案 1 :(得分:1)
如果将功能从代码移动到对象中,事情会变得容易多了。
例如:
enum SkillType {
TWO_HANDED_CRUSHING_WEAPONS {
@Override
void updateEntity(SkillDatabaseEntity entity, int value) {
entity.setTwoHandedCrushingWeaponsXp(value);
}
@Override
void mapSkill(SkillMapper mapper, int userId, int value) {
mapper.addTwoHandedCrushingWeaponsXp(userId, value);
}
},
ONE_HANDED_CRUSHING_WEAPONS {
@Override
void updateEntity(SkillDatabaseEntity entity, int value) {
entity.addOneHandedCrushingWeaponsXp(value);
}
@Override
void mapSkill(SkillMapper mapper, int userId, int value) {
mapper.addOneHandedCrushingWeaponsXp(userId, value);
}
},
TWO_HANDED_AXES {
@Override
void updateEntity(SkillDatabaseEntity entity, int value) {
entity.setTwoHandedAxesXp(value);
}
@Override
void mapSkill(SkillMapper mapper, int userId, int value) {
mapper.addTwoHandedAxesXp(userId, value);
}
};
abstract void updateEntity(SkillDatabaseEntity entity, int value);
abstract void mapSkill(SkillMapper mapper, int userId, int value);
}
public void addSkillXp(SkillType skill, int value) {
final SkillDatabaseEntity skillDatabaseEntity = skillValueCache.getEntity();
skill.updateEntity(skillDatabaseEntity, value);
skill.mapSkill(skillMapper, userEntity.getId(), value);
}
此处addSkillXp
只变成了三行代码。
另一个优雅的好处是,所有技能相关的代码都在同一个enum
。