You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优雅实现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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:57:05