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
相关产品推荐
相关产品推荐

