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

Java实现有限状态机时Transition自限定泛型的替代设计方案咨询

有限状态机结构示意图

你当前使用的Transition<T extends Transition<T>>写法是Java中标准的*递归类型限定(Recursive Type Bound)*写法,和JDK内置的Enum<E extends Enum<E>>实现逻辑完全一致,本身不存在语法问题,核心作用是保证子类继承后,关联的状态类可以直接绑定到子类自身类型,避免额外的类型转换,只是对不熟悉泛型高级用法的开发者来说可读性稍差。

以下是三种可替代的实现思路,你可以根据自己的业务场景选型:

方案1:保留递归类型限定,补充子类实现逻辑优化可读性

如果你的场景需要严格的编译期类型校验,完全可以保留现有写法,只要补充子类实现就会非常清晰:

// 现有基类保持不变
public class Etat<T extends Transition<T>> {
    private ObservableSet<T> listeTransitions;
}

public abstract class Transition<T extends Transition<T>> {
    private Etat<T> etatDepart;
    private Etat<T> etatArrivee;
}

// 自定义转移子类实现示例
public class EventTransition extends Transition<EventTransition> {
    // 自定义转移的独有属性,比如触发事件、校验规则等
    private String triggerEventCode;
}

// 使用时直接绑定子类类型,不需要任何强转
Etat<EventTransition> eventState = new Etat<>();
方案2:拆分泛型定义,去掉递归绑定

如果优先考虑代码可读性,不需要在Transition基类中返回子类具体类型,可以去掉递归泛型,简化泛型限定:

// 转移基类不需要递归限定
public abstract class Transition {
    private Etat<? extends Transition> etatDepart;
    private Etat<? extends Transition> etatArrivee;
}

// 状态类泛型直接限定为Transition的子类即可
public class Etat<T extends Transition> {
    private ObservableSet<T> listeTransitions;
}

// 子类实现更简洁
public class TimeoutTransition extends Transition {
    private long timeoutThresholdMs;
}

// 使用示例
Etat<TimeoutTransition> timeoutState = new Etat<>();

该方案语法更直观,劣势是如果需要在Transition基类中获取子类的具体类型,需要手动做类型转换。

方案3:面向接口抽象,完全解耦泛型依赖

如果你的状态机需要支持动态扩展多种转移类型,不需要编译期强类型校验,可以用接口定义公共行为,完全去掉泛型耦合:

// 转移公共接口
public interface ITransition {
    IEtat getDepartState();
    IEtat getArriveState();
    // 公共方法:判断当前转移是否满足触发条件
    boolean checkTriggerCondition(Object context);
}

// 状态公共接口
public interface IEtat {
    Set<ITransition> getAllTransitions();
    void addTransition(ITransition transition);
}

// 具体实现类
public class CustomTransition implements ITransition {
    private CustomEtat depart;
    private CustomEtat arrivee;
    // 实现接口方法
}

public class CustomEtat implements IEtat {
    private ObservableSet<ITransition> transitions = FXCollections.observableSet();
    // 实现接口方法
}

该方案灵活度最高,适合转移类型多变、需要动态组装状态机的场景,缺点是放弃了编译期的类型校验,需要在运行时保证类型安全。

选型建议:需要强类型安全选方案1,优先可读性选方案2,需要高扩展灵活度选方案3。

内容的提问来源于stack exchange,提问作者emerick biron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 04:24:01