如何优雅实现Fighter对象晋升时的类型转换?
更优雅的Fighter晋升方案
你的现有方案(创建新对象复制数据、替换旧对象)确实能实现需求,但存在对象身份丢失、聚合器/其他依赖需手动更新引用的问题。下面几种方案可以优化这个场景:
1. 状态模式(State Pattern)—— 推荐优先考虑
把等级相关的行为和状态抽离成独立的状态类,Fighter作为上下文持有当前状态,晋升时仅切换状态而非替换整个对象。这样Fighter的核心数据(姓名、任务数等)始终保留,对象身份不变,聚合器的引用无需修改。
示例代码(Java):
// 等级状态抽象类,封装各等级的行为 abstract class FighterRankState { abstract void promote(Fighter fighter); abstract String getRankName(); // 可添加其他等级专属方法,比如任务分配上限、薪资计算等 } // 初级状态 class JuniorRankState extends FighterRankState { @Override void promote(Fighter fighter) { fighter.setRankState(new MediorRankState()); } @Override String getRankName() { return "Junior"; } } // 中级状态 class MediorRankState extends FighterRankState { @Override void promote(Fighter fighter) { fighter.setRankState(new SeniorRankState()); } @Override String getRankName() { return "Medior"; } } // 高级状态(无法再晋升) class SeniorRankState extends FighterRankState { @Override void promote(Fighter fighter) { throw new UnsupportedOperationException("Senior无法继续晋升"); } @Override String getRankName() { return "Senior"; } } // 核心Fighter类,保持对象身份不变 class Fighter { private String name; private int completedMissions; private FighterRankState rankState; public Fighter(String name) { this.name = name; this.completedMissions = 0; this.rankState = new JuniorRankState(); // 默认初级 } // 晋升方法,委托给当前状态处理 public void promote() { rankState.promote(this); } // 其他核心方法和字段的getter/setter public String getRank() { return rankState.getRankName(); } public void setRankState(FighterRankState rankState) { this.rankState = rankState; } }
优点:
- 对象身份始终一致,聚合器、任务关联等依赖无需更新引用
- 等级行为与核心数据解耦,新增等级只需添加新的状态类,符合开闭原则
- 避免重复的数据拷贝逻辑
2. 组合替代继承(Composition over Inheritance)—— 轻量方案
如果各等级的行为差异不大,无需复杂的状态逻辑,可以用组合的方式:把等级定义为枚举或独立类,作为Fighter的成员变量,晋升时直接修改该变量。
示例代码:
// 等级枚举,封装晋升逻辑 enum FighterRank { JUNIOR { @Override public FighterRank nextRank() { return MEDIOR; } }, MEDIOR { @Override public FighterRank nextRank() { return SENIOR; } }, SENIOR { @Override public FighterRank nextRank() { throw new UnsupportedOperationException("Senior无法晋升"); } }; public abstract FighterRank nextRank(); } class Fighter { private String name; private int completedMissions; private FighterRank rank; public Fighter(String name) { this.name = name; this.completedMissions = 0; this.rank = FighterRank.JUNIOR; } public void promote() { this.rank = rank.nextRank(); } public FighterRank getRank() { return rank; } }
优点:
- 实现极简,代码量少
- 同样保持Fighter对象身份不变
- 适合等级逻辑简单的场景
3. 优化现有继承方案(保留继承结构时用)
如果因业务需求必须保留Junior/Medior/Senior的继承结构,可以通过拷贝构造器封装数据拷贝逻辑,并让聚合器统一处理对象替换,避免手动操作的混乱。
示例代码:
// 抽象Fighter类,定义公共字段和晋升接口 abstract class Fighter { protected String name; protected int completedMissions; // 拷贝构造器,用于复制公共字段 protected Fighter(Fighter source) { this.name = source.name; this.completedMissions = source.completedMissions; } // 子类实现晋升逻辑 public abstract Fighter promote(); // getter方法 public String getName() { return name; } } // Junior子类 class Junior extends Fighter { private int trainingHours; // Junior专属字段 public Junior(String name, int completedMissions, int trainingHours) { super(name, completedMissions); this.trainingHours = trainingHours; } // Junior拷贝构造器 protected Junior(Junior source) { super(source); this.trainingHours = source.trainingHours; } @Override public Fighter promote() { // 转换为Medior,可根据需要处理专属字段的映射 return new Medior(this.name, this.completedMissions, this.trainingHours * 2); } } // Medior子类 class Medior extends Fighter { private int leadershipScore; // Medior专属字段 public Medior(String name, int completedMissions, int leadershipScore) { super(name, completedMissions); this.leadershipScore = leadershipScore; } protected Medior(Medior source) { super(source); this.leadershipScore = source.leadershipScore; } @Override public Fighter promote() { return new Senior(this.name, this.completedMissions, this.leadershipScore); } } // Senior子类(无法晋升) class Senior extends Fighter { private int mentorCount; // Senior专属字段 public Senior(String name, int completedMissions, int mentorCount) { super(name, completedMissions); this.mentorCount = mentorCount; } @Override public Fighter promote() { throw new UnsupportedOperationException("Senior无法晋升"); } } // 聚合器类统一处理晋升和对象替换 class FighterMissionTracker { private Map<String, Fighter> fighterMap = new HashMap<>(); public void promoteFighter(String fighterName) { Fighter oldFighter = fighterMap.get(fighterName); if (oldFighter == null) return; Fighter newFighter = oldFighter.promote(); fighterMap.put(fighterName, newFighter); } }
优点:
- 保留了继承结构,适合等级有大量专属字段/行为的场景
- 拷贝逻辑封装在子类内部,避免重复代码
- 聚合器统一处理对象替换,减少手动出错的概率
内容的提问来源于stack exchange,提问作者tmsnvk
相关产品推荐
相关产品推荐

