feat: 抽象更高层的状态事件注册接口.

This commit is contained in:
2025-03-28 14:51:10 +08:00
parent 921520b097
commit 92ee373ea4
7 changed files with 309 additions and 135 deletions

View File

@@ -34,9 +34,6 @@ public abstract class AbstractStateMachine<S> extends AbstractStateManager<S> im
public AbstractStateMachine(List<S> stateList, StateMachineContext<S> context) { public AbstractStateMachine(List<S> stateList, StateMachineContext<S> context) {
super(stateList); super(stateList);
this.context = context; this.context = context;
// 设置初始状态
tryInitialState();
} }
@Override @Override
@@ -250,58 +247,13 @@ public abstract class AbstractStateMachine<S> extends AbstractStateManager<S> im
*/ */
protected final void invokeHandlers(S from, S to) { protected final void invokeHandlers(S from, S to) {
// 触发离开处理器 // 触发离开处理器
doInvokeHandlers(context.leaveHandlers.get(from), from, to); HandlerInvocationDelegate.doInvokeHandlers(context, context.leaveHandlers.get(from), from, to);
// 触发进入处理器 // 触发进入处理器
doInvokeHandlers(context.entryHandlers.get(to), from, to); HandlerInvocationDelegate.doInvokeHandlers(context, context.entryHandlers.get(to), from, to);
// 触发交换处理器 // 触发交换处理器
final String key = from.toString() + "-" + to.toString(); final String key = from.toString() + "-" + to.toString();
doInvokeHandlers(context.exchangeHandlers.get(key), from, to); HandlerInvocationDelegate.doInvokeHandlers(context, context.exchangeHandlers.get(key), from, to);
}
/**
* 触发
*/
private void doInvokeHandlers(List<StateHandlerWrapper<S>> handlerWrappers, S from, S to) {
if (handlerWrappers == null)
return;
handlerWrappers.forEach(hw -> {
final StateHandler<S> stateHandler;
if (hw == null ||
(stateHandler = hw.getStateHandler()) == null)
return;
final StateHandlerProcessParams<S> params = new StateHandlerProcessParams<>(from, to, null);
/*
* 一、异步逻辑校验: 首先判断是否需要异步执行状态处理器, 具体的状态逻辑处理器优先级大于全局
* 即: 如果全局指定了同步执行, 但此时特定的状态处理器注册时指定为异步执行的话. 该处理器
* 为异步执行.
*
* 二、 当确定了为异步执行时会选择合适的异步执行器(通常都是线程池), 如果状态处理器注册
* 时指定了异步执行器, 则优先使用该异步执行器;反则会使用全局的异步执行器。如果上一步骤
* 中确定为异步执行但当前步骤没有寻找到合适的异步执行器则会报空指针异常(当前版本不会出现)
*/
if (hw.getAsync() == null ?
(context.async != null && context.async) :
hw.getAsync()) {
final Executor executor;
if ((executor = hw.getExecutor() == null ?
context.executor : hw.getExecutor()) == null)
// 不应该发生
throw new Error();
executor.execute(() -> stateHandler.handle(params));
} else
stateHandler.handle(params);
});
}
/**
* 尝试设置初始状态(如果有指定的话)
*/
private void tryInitialState() {
if (context.initialState != null) {
switchTo(context.initialState, false);
}
} }
} }

View File

@@ -0,0 +1,72 @@
package com.serliunx.statemanagement.machine;
import com.serliunx.statemanagement.machine.handler.StateHandler;
import com.serliunx.statemanagement.machine.handler.StateHandlerProcessParams;
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
import java.util.List;
import java.util.concurrent.Executor;
/**
* 状态处理器触发
*
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 2025/3/28
*/
public final class HandlerInvocationDelegate {
/**
* 触发处理器
*
* @param from 源状态
* @param to 目的状态
*/
public static <S> void invokeHandlers(StateMachineContext<S> context, S from, S to) {
// 触发离开处理器
doInvokeHandlers(context, context.leaveHandlers.get(from), from, to);
// 触发进入处理器
doInvokeHandlers(context, context.entryHandlers.get(to), from, to);
// 触发交换处理器
final String key = from.toString() + "-" + to.toString();
doInvokeHandlers(context, context.exchangeHandlers.get(key), from, to);
}
/**
* 触发逻辑
*/
public static <S> void doInvokeHandlers(StateMachineContext<S> context,
List<StateHandlerWrapper<S>> handlerWrappers, S from, S to) {
if (handlerWrappers == null)
return;
handlerWrappers.forEach(hw -> {
final StateHandler<S> stateHandler;
if (hw == null ||
(stateHandler = hw.getStateHandler()) == null)
return;
final StateHandlerProcessParams<S> params = new StateHandlerProcessParams<>(from, to, null);
/*
* 一、异步逻辑校验: 首先判断是否需要异步执行状态处理器, 具体的状态逻辑处理器优先级大于全局
* 即: 如果全局指定了同步执行, 但此时特定的状态处理器注册时指定为异步执行的话. 该处理器
* 为异步执行.
*
* 二、 当确定了为异步执行时会选择合适的异步执行器(通常都是线程池), 如果状态处理器注册
* 时指定了异步执行器, 则优先使用该异步执行器;反则会使用全局的异步执行器。如果上一步骤
* 中确定为异步执行但当前步骤没有寻找到合适的异步执行器则会报空指针异常(当前版本不会出现)
*/
if (hw.getAsync() == null ?
(context.async != null && context.async) :
hw.getAsync()) {
final Executor executor;
if ((executor = hw.getExecutor() == null ?
context.executor : hw.getExecutor()) == null)
// 不应该发生
throw new Error();
executor.execute(() -> stateHandler.handle(params));
} else
stateHandler.handle(params);
});
}
}

View File

@@ -0,0 +1,111 @@
package com.serliunx.statemanagement.machine;
import com.serliunx.statemanagement.machine.external.FlexibleStateMachine;
import com.serliunx.statemanagement.machine.handler.StateHandler;
import java.util.concurrent.Executor;
/**
* 状态机之状态事件注册
* <li> 注册状态切换时的事件, 一般用于状态机构建和支持动态调整的状态机{@link FlexibleStateMachine};
* 当然实际不仅于此, 任何相关的都可以使用.
*
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 2025/3/28
* @see FlexibleStateMachine
*/
public interface StateEventRegistry<S> {
/**
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
*/
StateEventRegistry<S> whenEntry(S state, StateHandler<S> handler, Boolean async, Executor executor);
/**
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
*/
StateEventRegistry<S> whenEntry(S state, StateHandler<S> handler, Boolean async);
/**
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
*/
StateEventRegistry<S> whenEntry(S state, StateHandler<S> handler);
/**
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
*/
StateEventRegistry<S> whenLeave(S state, StateHandler<S> handler, Boolean async, Executor executor);
/**
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
*/
StateEventRegistry<S> whenLeave(S state, StateHandler<S> handler, Boolean async);
/**
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
*/
StateEventRegistry<S> whenLeave(S state, StateHandler<S> handler);
/**
* 添加交换事件
* <li> 从A状态切换至B状态时触发
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
*/
StateEventRegistry<S> exchange(S from, S to, StateHandler<S> handler, Boolean async, Executor executor);
/**
* 添加交换事件
* <li> 从A状态切换至B状态时触发
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
* @param async 是否异步执行
*/
StateEventRegistry<S> exchange(S from, S to, StateHandler<S> handler, Boolean async);
/**
* 添加交换事件
* <li> 从A状态切换至B状态时触发
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
*/
StateEventRegistry<S> exchange(S from, S to, StateHandler<S> handler);
}

View File

@@ -14,7 +14,7 @@ import java.util.function.Consumer;
* @version 1.0.0 * @version 1.0.0
* @since 2024/12/28 * @since 2024/12/28
*/ */
public final class StateMachineBuilder<S> { public final class StateMachineBuilder<S> implements StateEventRegistry<S> {
/** /**
* 状态管理器 * 状态管理器
@@ -63,16 +63,7 @@ public final class StateMachineBuilder<S> {
return this; return this;
} }
/** @Override
* 添加交换事件
* <li> 从A状态切换至B状态时触发
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
*/
public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler, Boolean async, Executor executor) { public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler, Boolean async, Executor executor) {
final String key = from.toString() + "-" + to.toString(); final String key = from.toString() + "-" + to.toString();
final List<StateHandlerWrapper<S>> stateHandlerWrappers = exchangeHandlers.computeIfAbsent(key, final List<StateHandlerWrapper<S>> stateHandlerWrappers = exchangeHandlers.computeIfAbsent(key,
@@ -81,40 +72,17 @@ public final class StateMachineBuilder<S> {
return this; return this;
} }
/** @Override
* 添加交换事件
* <li> 从A状态切换至B状态时触发
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
* @param async 是否异步执行
*/
public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler, Boolean async) { public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler, Boolean async) {
return exchange(from, to, handler, async, null); return exchange(from, to, handler, async, null);
} }
/** @Override
* 添加交换事件
* <li> 从A状态切换至B状态时触发
*
* @param from 源状态
* @param to 目的状态
* @param handler 处理器
*/
public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler) { public StateMachineBuilder<S> exchange(S from, S to, StateHandler<S> handler) {
return exchange(from, to, handler, null); return exchange(from, to, handler, null);
} }
/** @Override
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
*/
public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler, Boolean async, Executor executor) { public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler, Boolean async, Executor executor) {
final List<StateHandlerWrapper<S>> stateHandlerWrappers = leaveHandlers.computeIfAbsent(state, final List<StateHandlerWrapper<S>> stateHandlerWrappers = leaveHandlers.computeIfAbsent(state,
k -> new ArrayList<>()); k -> new ArrayList<>());
@@ -122,38 +90,17 @@ public final class StateMachineBuilder<S> {
return this; return this;
} }
/** @Override
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
*/
public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler, Boolean async) { public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler, Boolean async) {
return whenLeave(state, handler, async, null); return whenLeave(state, handler, async, null);
} }
/** @Override
* 添加离开事件
* <li> 从指定状态切换到别的状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
*/
public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler) { public StateMachineBuilder<S> whenLeave(S state, StateHandler<S> handler) {
return whenLeave(state, handler, null); return whenLeave(state, handler, null);
} }
/** @Override
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
* @param executor 异步执行器, 异步执行时将使用, 不指定时将使用状态机内置的执行器
*/
public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler, Boolean async, Executor executor) { public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler, Boolean async, Executor executor) {
final List<StateHandlerWrapper<S>> stateHandlerWrappers = entryHandlers.computeIfAbsent(state, final List<StateHandlerWrapper<S>> stateHandlerWrappers = entryHandlers.computeIfAbsent(state,
k -> new ArrayList<>()); k -> new ArrayList<>());
@@ -161,25 +108,12 @@ public final class StateMachineBuilder<S> {
return this; return this;
} }
/** @Override
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
* @param async 是否异步执行
*/
public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler, Boolean async) { public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler, Boolean async) {
return whenEntry(state, handler, async, null); return whenEntry(state, handler, async, null);
} }
/** @Override
* 添加进入事件
* <li> 切换到了指定状态时执行的逻辑
*
* @param state 状态
* @param handler 处理逻辑
*/
public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler) { public StateMachineBuilder<S> whenEntry(S state, StateHandler<S> handler) {
return whenEntry(state, handler, null); return whenEntry(state, handler, null);
} }

View File

@@ -1,9 +1,11 @@
package com.serliunx.statemanagement.machine; package com.serliunx.statemanagement.machine;
import com.serliunx.statemanagement.machine.handler.StateHandler;
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper; import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
import com.serliunx.statemanagement.support.DefaultCountableRejectedExecutionHandler; import com.serliunx.statemanagement.support.DefaultCountableRejectedExecutionHandler;
import com.serliunx.statemanagement.support.ExecutorUtils; import com.serliunx.statemanagement.support.ExecutorUtils;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -16,38 +18,38 @@ import java.util.function.Consumer;
* @version 1.0.0 * @version 1.0.0
* @since 2025/2/2 * @since 2025/2/2
*/ */
public final class StateMachineContext<S> { public final class StateMachineContext<S> implements StateEventRegistry<S> {
/** /**
* 进入事件集合 * 进入事件集合
*/ */
final Map<S, List<StateHandlerWrapper<S>>> entryHandlers; public Map<S, List<StateHandlerWrapper<S>>> entryHandlers;
/** /**
* 离开事件集合 * 离开事件集合
*/ */
final Map<S, List<StateHandlerWrapper<S>>> leaveHandlers; public Map<S, List<StateHandlerWrapper<S>>> leaveHandlers;
/** /**
* 交换事件集合 * 交换事件集合
*/ */
final Map<String, List<StateHandlerWrapper<S>>> exchangeHandlers; public Map<String, List<StateHandlerWrapper<S>>> exchangeHandlers;
/** /**
* 事件注册集合 * 事件注册集合
*/ */
final Map<Object, List<Consumer<StateMachine<S>>>> eventRegistries; public Map<Object, List<Consumer<StateMachine<S>>>> eventRegistries;
/** /**
* 异步执行器 * 异步执行器
*/ */
final Executor executor; public Executor executor;
/** /**
* 是否异步执行 * 是否异步执行
* <p> * <p>
* 当具体的执行器没有指定是否异步时, 将根据该值决定是否异步执行. * 当具体的执行器没有指定是否异步时, 将根据该值决定是否异步执行.
*/ */
final Boolean async; public Boolean async;
/** /**
* 初始化状态 * 初始化状态
*/ */
final S initialState; public S initialState;
public StateMachineContext(Map<S, List<StateHandlerWrapper<S>>> entryHandlers, public StateMachineContext(Map<S, List<StateHandlerWrapper<S>>> entryHandlers,
Map<S, List<StateHandlerWrapper<S>>> leaveHandlers, Map<S, List<StateHandlerWrapper<S>>> leaveHandlers,
@@ -76,6 +78,60 @@ public final class StateMachineContext<S> {
this(entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async, null); this(entryHandlers, leaveHandlers, exchangeHandlers, eventRegistries, executor, async, null);
} }
@Override
public StateMachineContext<S> whenEntry(S state, StateHandler<S> handler, Boolean async, Executor executor) {
final List<StateHandlerWrapper<S>> stateHandlerWrappers = entryHandlers.computeIfAbsent(state,
k -> new ArrayList<>());
stateHandlerWrappers.add(new StateHandlerWrapper<>(handler, executor, async));
return this;
}
@Override
public StateMachineContext<S> whenEntry(S state, StateHandler<S> handler, Boolean async) {
return whenEntry(state, handler, async, null);
}
@Override
public StateMachineContext<S> whenEntry(S state, StateHandler<S> handler) {
return whenEntry(state, handler, null);
}
@Override
public StateMachineContext<S> whenLeave(S state, StateHandler<S> handler, Boolean async, Executor executor) {
final List<StateHandlerWrapper<S>> stateHandlerWrappers = leaveHandlers.computeIfAbsent(state,
k -> new ArrayList<>());
stateHandlerWrappers.add(new StateHandlerWrapper<>(handler, executor, async));
return this;
}
@Override
public StateMachineContext<S> whenLeave(S state, StateHandler<S> handler, Boolean async) {
return whenLeave(state, handler, async, null);
}
@Override
public StateMachineContext<S> whenLeave(S state, StateHandler<S> handler) {
return whenLeave(state, handler, null);
}
@Override
public StateMachineContext<S> exchange(S from, S to, StateHandler<S> handler, Boolean async, Executor executor) {
final List<StateHandlerWrapper<S>> stateHandlerWrappers = exchangeHandlers.computeIfAbsent(from.toString()
+ "-" + to.toString(), k -> new ArrayList<>());
stateHandlerWrappers.add(new StateHandlerWrapper<>(handler, executor, async));
return this;
}
@Override
public StateMachineContext<S> exchange(S from, S to, StateHandler<S> handler, Boolean async) {
return exchange(from, to, handler, async, null);
}
@Override
public StateMachineContext<S> exchange(S from, S to, StateHandler<S> handler) {
return exchange(from, to, handler, null);
}
/** /**
* 执行器为空时自动创建一个适合当前操作系统的执行器(线程池) * 执行器为空时自动创建一个适合当前操作系统的执行器(线程池)
*/ */

View File

@@ -0,0 +1,48 @@
package com.serliunx.statemanagement.machine.external;
import com.serliunx.statemanagement.machine.StateEventRegistry;
import com.serliunx.statemanagement.machine.StateMachine;
import com.serliunx.statemanagement.machine.handler.StateHandler;
import com.serliunx.statemanagement.machine.handler.StateHandlerWrapper;
import java.util.List;
/**
* 可变的、灵活的状态机, 支持在运行的过程中动态的增减状态及状态切换的事件
*
* @author <a href="mailto:serliunx@yeah.net">SerLiunx</a>
* @since 2025/3/28
*/
public interface FlexibleStateMachine<S> extends StateMachine<S>, StateEventRegistry<S> {
/**
* 获取指定状态下所有的离开事件处理器.
* <p>
* 通过 {@link StateEventRegistry#whenLeave(Object, StateHandler)} 等方法注册.
*
* @param state 状态
* @return 所有与指定状态相关的离开事件处理器
*/
List<StateHandlerWrapper<S>> allLeaveHandlers(S state);
/**
* 获取指定状态下所有的进入事件处理器.
* <p>
* 通过 {@link StateEventRegistry#whenEntry(Object, StateHandler)} 等方法注册.
*
* @param state 状态
* @return 所有与指定状态相关的进入事件处理器
*/
List<StateHandlerWrapper<S>> allEntryHandlers(S state);
/**
* 获取指定状态下所有的交换事件处理器.
* <p>
* 通过 {@link StateEventRegistry#exchange(Object, Object, StateHandler)} 等方法注册.
*
* @param from 源状态
* @param to 目标状态
* @return 所有与指定状态相关的交换事件处理器
*/
List<StateHandlerWrapper<S>> allExchangeHandlers(S from, S to);
}

View File

@@ -38,6 +38,7 @@ public class MachineTest {
if (l.switchTo(PrinterState.STOPPING)) if (l.switchTo(PrinterState.STOPPING))
l.switchTo(PrinterState.STOPPED); l.switchTo(PrinterState.STOPPED);
}) })
.withInitial(PrinterState.STOPPING)
.concurrent() .concurrent()
.build(); .build();