04 - 步骤执行器设计 🔧

🎯 目标: 设计可扩展的步骤执行器架构,实现各种类型的步骤执行逻辑

🤔 为什么需要多种执行器?

不同的业务场景需要不同的执行逻辑:

  • 🔀 条件分支: 根据条件选择不同的执行路径
  • 并行执行: 同时执行多个独立的任务
  • 🔄 循环执行: 重复执行某些步骤直到满足条件
  • 📝 脚本执行: 动态执行脚本代码
  • 🌐 远程调用: 调用外部服务或API

🏗️ 执行器架构设计

graph TB subgraph "StepExecutor 接口层 🎯" A1[StepExecutor] A2[AbstractStepExecutor] end subgraph "基础执行器 🔧" B1[SimpleStepExecutor] B2[ServiceStepExecutor] B3[ScriptStepExecutor] end subgraph "控制流执行器 🔀" C1[ConditionalStepExecutor] C2[ParallelStepExecutor] C3[LoopStepExecutor] C4[ScriptConditionalStepExecutor] end subgraph "扩展执行器 🚀" D1[HttpStepExecutor] D2[DatabaseStepExecutor] D3[MessageStepExecutor] end A1 --> A2 A2 --> B1 A2 --> B2 A2 --> B3 A2 --> C1 A2 --> C2 A2 --> C3 A2 --> C4 A2 --> D1 A2 --> D2 A2 --> D3

🎯 AbstractStepExecutor基类

java 复制代码
/**
 * 步骤执行器抽象基类
 * 提供通用的执行逻辑和模板方法
 */
public abstract class AbstractStepExecutor implements StepExecutor {
    
    protected static final Logger logger = LoggerFactory.getLogger(AbstractStepExecutor.class);
    
    @Override
    public final StepExecutionResult execute(StepDefinition stepDefinition, FlowContext context) {
        long startTime = System.currentTimeMillis();
        String stepId = stepDefinition.getId();
        
        logger.debug("开始执行步骤: {} [{}]", stepDefinition.getName(), stepId);
        
        try {
            // 前置处理
            preExecute(stepDefinition, context);
            
            // 执行核心逻辑
            Object result = doExecute(stepDefinition, context);
            
            // 后置处理
            postExecute(stepDefinition, context, result);
            
            long endTime = System.currentTimeMillis();
            
            logger.debug("步骤执行成功: {} [{}], 耗时: {}ms", 
                stepDefinition.getName(), stepId, endTime - startTime);
            
            return createSuccessResult(stepDefinition, result, startTime, endTime);
            
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            
            logger.error("步骤执行失败: {} [{}], 耗时: {}ms", 
                stepDefinition.getName(), stepId, endTime - startTime, e);
            
            return createFailureResult(stepDefinition, e, startTime, endTime);
        }
    }
    
    /**
     * 执行前置处理
     * @param stepDefinition 步骤定义
     * @param context 执行上下文
     */
    protected void preExecute(StepDefinition stepDefinition, FlowContext context) {
        // 默认空实现,子类可以重写
    }
    
    /**
     * 执行核心逻辑(子类必须实现)
     * @param stepDefinition 步骤定义
     * @param context 执行上下文
     * @return 执行结果
     */
    protected abstract Object doExecute(StepDefinition stepDefinition, FlowContext context) throws Exception;
    
    /**
     * 执行后置处理
     * @param stepDefinition 步骤定义
     * @param context 执行上下文
     * @param result 执行结果
     */
    protected void postExecute(StepDefinition stepDefinition, FlowContext context, Object result) {
        // 保存结果到上下文
        String resultKey = getResultKey(stepDefinition);
        if (resultKey != null && result != null) {
            context.put(resultKey, result);
        }
    }
    
    /**
     * 获取结果保存的键名
     */
    protected String getResultKey(StepDefinition stepDefinition) {
        return (String) stepDefinition.getConfig().get("resultKey");
    }
    
    /**
     * 创建成功结果
     */
    protected StepExecutionResult createSuccessResult(
            StepDefinition stepDefinition, Object result, long startTime, long endTime) {
        return new StepExecutionResult(
            stepDefinition.getId(),
            stepDefinition.getType(),
            FlowExecutionResult.Status.SUCCESS,
            result,
            startTime,
            endTime,
            null
        );
    }
    
    /**
     * 创建失败结果
     */
    protected StepExecutionResult createFailureResult(
            StepDefinition stepDefinition, Exception exception, long startTime, long endTime) {
        return new StepExecutionResult(
            stepDefinition.getId(),
            stepDefinition.getType(),
            FlowExecutionResult.Status.FAILED,
            null,
            startTime,
            endTime,
            exception
        );
    }
    
    /**
     * 获取配置值
     */
    protected <T> T getConfig(StepDefinition stepDefinition, String key, Class<T> type) {
        Object value = stepDefinition.getConfig().get(key);
        if (value == null) {
            return null;
        }
        
        if (type.isInstance(value)) {
            return type.cast(value);
        }
        
        throw new IllegalArgumentException(
            String.format("配置 %s 的类型不匹配,期望: %s, 实际: %s", 
                key, type.getSimpleName(), value.getClass().getSimpleName())
        );
    }
    
    /**
     * 获取必需的配置值
     */
    protected <T> T getRequiredConfig(StepDefinition stepDefinition, String key, Class<T> type) {
        T value = getConfig(stepDefinition, key, type);
        if (value == null) {
            throw new IllegalArgumentException(
                String.format("步骤 %s 缺少必需的配置: %s", stepDefinition.getId(), key)
            );
        }
        return value;
    }
}

🔀 ConditionalStepExecutor - 条件执行器

java 复制代码
/**
 * 条件步骤执行器
 * 根据条件表达式选择执行不同的分支
 */
public class ConditionalStepExecutor extends AbstractStepExecutor {
    
    private final ExpressionEvaluator expressionEvaluator;
    private final FlowEngine flowEngine;
    
    public ConditionalStepExecutor(ExpressionEvaluator expressionEvaluator, FlowEngine flowEngine) {
        this.expressionEvaluator = expressionEvaluator;
        this.flowEngine = flowEngine;
    }
    
    @Override
    protected Object doExecute(StepDefinition stepDefinition, FlowContext context) throws Exception {
        // 获取条件表达式
        String condition = getRequiredConfig(stepDefinition, "condition", String.class);
        
        // 评估条件
        boolean conditionResult = expressionEvaluator.evaluateBoolean(condition, context);
        
        logger.debug("条件评估结果: {} -> {}", condition, conditionResult);
        
        // 根据条件选择执行分支
        List<StepDefinition> targetSteps = conditionResult ? 
            getTrueSteps(stepDefinition) : getFalseSteps(stepDefinition);
        
        if (targetSteps == null || targetSteps.isEmpty()) {
            logger.debug("没有找到匹配的执行分支");
            return conditionResult;
        }
        
        // 执行选中的步骤
        List<StepExecutionResult> branchResults = new ArrayList<>();
        for (StepDefinition step : targetSteps) {
            StepExecutor executor = flowEngine.getExecutor(step.getType());
            if (executor == null) {
                throw new IllegalStateException("未找到步骤类型的执行器: " + step.getType());
            }
            
            StepExecutionResult result = executor.execute(step, context);
            branchResults.add(result);
            
            // 如果步骤失败,根据配置决定是否继续
            if (result.getStatus() == FlowExecutionResult.Status.FAILED && 
                !shouldContinueOnFailure(step)) {
                break;
            }
        }
        
        return new ConditionalExecutionResult(conditionResult, branchResults);
    }
    
    /**
     * 获取条件为真时执行的步骤
     */
    @SuppressWarnings("unchecked")
    private List<StepDefinition> getTrueSteps(StepDefinition stepDefinition) {
        return (List<StepDefinition>) stepDefinition.getConfig().get("trueSteps");
    }
    
    /**
     * 获取条件为假时执行的步骤
     */
    @SuppressWarnings("unchecked")
    private List<StepDefinition> getFalseSteps(StepDefinition stepDefinition) {
        return (List<StepDefinition>) stepDefinition.getConfig().get("falseSteps");
    }
    
    /**
     * 判断失败时是否继续执行
     */
    private boolean shouldContinueOnFailure(StepDefinition stepDefinition) {
        Boolean continueOnFailure = getConfig(stepDefinition, "continueOnFailure", Boolean.class);
        return Boolean.TRUE.equals(continueOnFailure);
    }
    
    @Override
    public StepType getSupportedType() {
        return StepType.CONDITIONAL;
    }
    
    @Override
    public ValidationResult validate(StepDefinition stepDefinition) {
        // 验证条件表达式
        String condition = getConfig(stepDefinition, "condition", String.class);
        if (condition == null || condition.trim().isEmpty()) {
            return ValidationResult.error("条件步骤必须指定condition配置");
        }
        
        // 验证至少有一个分支
        List<StepDefinition> trueSteps = getTrueSteps(stepDefinition);
        List<StepDefinition> falseSteps = getFalseSteps(stepDefinition);
        
        if ((trueSteps == null || trueSteps.isEmpty()) && 
            (falseSteps == null || falseSteps.isEmpty())) {
            return ValidationResult.error("条件步骤必须至少指定一个执行分支");
        }
        
        return ValidationResult.success();
    }
    
    /**
     * 条件执行结果
     */
    public static class ConditionalExecutionResult {
        private final boolean conditionResult;
        private final List<StepExecutionResult> branchResults;
        
        public ConditionalExecutionResult(boolean conditionResult, List<StepExecutionResult> branchResults) {
            this.conditionResult = conditionResult;
            this.branchResults = branchResults;
        }
        
        // getter方法...
    }
}

⚡ ParallelStepExecutor - 并行执行器

java 复制代码
/**
 * 并行步骤执行器
 * 同时执行多个独立的步骤
 */
public class ParallelStepExecutor extends AbstractStepExecutor {
    
    private final FlowEngine flowEngine;
    private final ExecutorService executorService;
    
    public ParallelStepExecutor(FlowEngine flowEngine) {
        this.flowEngine = flowEngine;
        this.executorService = Executors.newCachedThreadPool(
            new ThreadFactoryBuilder()
                .setNameFormat("parallel-step-%d")
                .setDaemon(true)
                .build()
        );
    }
    
    @Override
    protected Object doExecute(StepDefinition stepDefinition, FlowContext context) throws Exception {
        // 获取并行执行的步骤
        List<StepDefinition> parallelSteps = getParallelSteps(stepDefinition);
        if (parallelSteps == null || parallelSteps.isEmpty()) {
            logger.warn("并行步骤没有配置子步骤");
            return Collections.emptyList();
        }
        
        // 获取超时配置
        Integer timeoutSeconds = getConfig(stepDefinition, "timeoutSeconds", Integer.class);
        long timeout = timeoutSeconds != null ? timeoutSeconds : 300; // 默认5分钟
        
        logger.debug("开始并行执行 {} 个步骤,超时: {}秒", parallelSteps.size(), timeout);
        
        // 创建并行任务
        List<CompletableFuture<StepExecutionResult>> futures = new ArrayList<>();
        
        for (StepDefinition step : parallelSteps) {
            CompletableFuture<StepExecutionResult> future = CompletableFuture.supplyAsync(
                () -> executeStep(step, context.createChild()),
                executorService
            );
            futures.add(future);
        }
        
        // 等待所有任务完成
        try {
            CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                futures.toArray(new CompletableFuture[0])
            );
            
            allFutures.get(timeout, TimeUnit.SECONDS);
            
            // 收集结果
            List<StepExecutionResult> results = new ArrayList<>();
            for (CompletableFuture<StepExecutionResult> future : futures) {
                results.add(future.get());
            }
            
            logger.debug("并行执行完成,成功: {}, 失败: {}", 
                countSuccessful(results), countFailed(results));
            
            return new ParallelExecutionResult(results);
            
        } catch (TimeoutException e) {
            // 取消未完成的任务
            for (CompletableFuture<StepExecutionResult> future : futures) {
                future.cancel(true);
            }
            throw new RuntimeException("并行执行超时: " + timeout + "秒", e);
        }
    }
    
    /**
     * 执行单个步骤
     */
    private StepExecutionResult executeStep(StepDefinition stepDefinition, FlowContext context) {
        try {
            StepExecutor executor = flowEngine.getExecutor(stepDefinition.getType());
            if (executor == null) {
                throw new IllegalStateException("未找到步骤类型的执行器: " + stepDefinition.getType());
            }
            
            return executor.execute(stepDefinition, context);
            
        } catch (Exception e) {
            logger.error("并行步骤执行异常: {}", stepDefinition.getId(), e);
            
            return new StepExecutionResult(
                stepDefinition.getId(),
                stepDefinition.getType(),
                FlowExecutionResult.Status.FAILED,
                null,
                System.currentTimeMillis(),
                System.currentTimeMillis(),
                e
            );
        }
    }
    
    /**
     * 获取并行执行的步骤
     */
    @SuppressWarnings("unchecked")
    private List<StepDefinition> getParallelSteps(StepDefinition stepDefinition) {
        return (List<StepDefinition>) stepDefinition.getConfig().get("steps");
    }
    
    /**
     * 统计成功的步骤数量
     */
    private long countSuccessful(List<StepExecutionResult> results) {
        return results.stream()
            .filter(r -> r.getStatus() == FlowExecutionResult.Status.SUCCESS)
            .count();
    }
    
    /**
     * 统计失败的步骤数量
     */
    private long countFailed(List<StepExecutionResult> results) {
        return results.stream()
            .filter(r -> r.getStatus() == FlowExecutionResult.Status.FAILED)
            .count();
    }
    
    @Override
    public StepType getSupportedType() {
        return StepType.PARALLEL;
    }
    
    @Override
    public ValidationResult validate(StepDefinition stepDefinition) {
        List<StepDefinition> steps = getParallelSteps(stepDefinition);
        if (steps == null || steps.isEmpty()) {
            return ValidationResult.error("并行步骤必须配置至少一个子步骤");
        }
        
        // 验证超时配置
        Integer timeoutSeconds = getConfig(stepDefinition, "timeoutSeconds", Integer.class);
        if (timeoutSeconds != null && timeoutSeconds <= 0) {
            return ValidationResult.error("超时时间必须大于0");
        }
        
        return ValidationResult.success();
    }
    
    /**
     * 关闭执行器
     */
    public void shutdown() {
        executorService.shutdown();
        try {
            if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 并行执行结果
     */
    public static class ParallelExecutionResult {
        private final List<StepExecutionResult> results;
        
        public ParallelExecutionResult(List<StepExecutionResult> results) {
            this.results = results;
        }
        
        public List<StepExecutionResult> getResults() {
            return results;
        }
        
        public boolean hasFailures() {
            return results.stream()
                .anyMatch(r -> r.getStatus() == FlowExecutionResult.Status.FAILED);
        }
        
        public List<StepExecutionResult> getSuccessfulResults() {
            return results.stream()
                .filter(r -> r.getStatus() == FlowExecutionResult.Status.SUCCESS)
                .collect(Collectors.toList());
        }
        
        public List<StepExecutionResult> getFailedResults() {
            return results.stream()
                .filter(r -> r.getStatus() == FlowExecutionResult.Status.FAILED)
                .collect(Collectors.toList());
        }
    }
}

🔄 LoopStepExecutor - 循环执行器

java 复制代码
/**
 * 循环步骤执行器
 * 重复执行步骤直到满足退出条件
 */
public class LoopStepExecutor extends AbstractStepExecutor {
    
    private final ExpressionEvaluator expressionEvaluator;
    private final FlowEngine flowEngine;
    
    public LoopStepExecutor(ExpressionEvaluator expressionEvaluator, FlowEngine flowEngine) {
        this.expressionEvaluator = expressionEvaluator;
        this.flowEngine = flowEngine;
    }
    
    @Override
    protected Object doExecute(StepDefinition stepDefinition, FlowContext context) throws Exception {
        // 获取循环配置
        String condition = getConfig(stepDefinition, "condition", String.class);
        Integer maxIterations = getConfig(stepDefinition, "maxIterations", Integer.class);
        List<StepDefinition> loopSteps = getLoopSteps(stepDefinition);
        
        if (loopSteps == null || loopSteps.isEmpty()) {
            logger.warn("循环步骤没有配置子步骤");
            return Collections.emptyList();
        }
        
        // 设置默认值
        if (maxIterations == null) {
            maxIterations = 100; // 默认最大100次迭代
        }
        
        logger.debug("开始循环执行,最大迭代次数: {}, 条件: {}", maxIterations, condition);
        
        List<LoopIterationResult> iterationResults = new ArrayList<>();
        int iteration = 0;
        
        while (iteration < maxIterations) {
            iteration++;
            
            logger.debug("开始第 {} 次迭代", iteration);
            
            // 设置迭代变量
            context.put("_iteration", iteration);
            context.put("_isFirstIteration", iteration == 1);
            
            // 执行循环体
            List<StepExecutionResult> stepResults = new ArrayList<>();
            boolean shouldBreak = false;
            
            for (StepDefinition step : loopSteps) {
                StepExecutor executor = flowEngine.getExecutor(step.getType());
                if (executor == null) {
                    throw new IllegalStateException("未找到步骤类型的执行器: " + step.getType());
                }
                
                StepExecutionResult result = executor.execute(step, context);
                stepResults.add(result);
                
                // 如果步骤失败,根据配置决定是否继续
                if (result.getStatus() == FlowExecutionResult.Status.FAILED) {
                    if (!shouldContinueOnFailure(step)) {
                        shouldBreak = true;
                        break;
                    }
                }
            }
            
            iterationResults.add(new LoopIterationResult(iteration, stepResults));
            
            // 如果步骤失败需要退出
            if (shouldBreak) {
                logger.debug("由于步骤失败,退出循环");
                break;
            }
            
            // 检查退出条件
            if (condition != null && !condition.trim().isEmpty()) {
                try {
                    boolean shouldContinue = expressionEvaluator.evaluateBoolean(condition, context);
                    if (!shouldContinue) {
                        logger.debug("满足退出条件,结束循环");
                        break;
                    }
                } catch (Exception e) {
                    logger.warn("循环条件评估失败: {}", condition, e);
                    break;
                }
            }
        }
        
        // 清理迭代变量
        context.remove("_iteration");
        context.remove("_isFirstIteration");
        
        logger.debug("循环执行完成,总迭代次数: {}", iteration);
        
        return new LoopExecutionResult(iteration, iterationResults);
    }
    
    /**
     * 获取循环执行的步骤
     */
    @SuppressWarnings("unchecked")
    private List<StepDefinition> getLoopSteps(StepDefinition stepDefinition) {
        return (List<StepDefinition>) stepDefinition.getConfig().get("steps");
    }
    
    /**
     * 判断失败时是否继续执行
     */
    private boolean shouldContinueOnFailure(StepDefinition stepDefinition) {
        Boolean continueOnFailure = getConfig(stepDefinition, "continueOnFailure", Boolean.class);
        return Boolean.TRUE.equals(continueOnFailure);
    }
    
    @Override
    public StepType getSupportedType() {
        return StepType.LOOP;
    }
    
    @Override
    public ValidationResult validate(StepDefinition stepDefinition) {
        List<StepDefinition> steps = getLoopSteps(stepDefinition);
        if (steps == null || steps.isEmpty()) {
            return ValidationResult.error("循环步骤必须配置至少一个子步骤");
        }
        
        // 验证最大迭代次数
        Integer maxIterations = getConfig(stepDefinition, "maxIterations", Integer.class);
        if (maxIterations != null && maxIterations <= 0) {
            return ValidationResult.error("最大迭代次数必须大于0");
        }
        
        return ValidationResult.success();
    }
    
    /**
     * 循环迭代结果
     */
    public static class LoopIterationResult {
        private final int iteration;
        private final List<StepExecutionResult> stepResults;
        
        public LoopIterationResult(int iteration, List<StepExecutionResult> stepResults) {
            this.iteration = iteration;
            this.stepResults = stepResults;
        }
        
        // getter方法...
    }
    
    /**
     * 循环执行结果
     */
    public static class LoopExecutionResult {
        private final int totalIterations;
        private final List<LoopIterationResult> iterationResults;
        
        public LoopExecutionResult(int totalIterations, List<LoopIterationResult> iterationResults) {
            this.totalIterations = totalIterations;
            this.iterationResults = iterationResults;
        }
        
        // getter方法...
    }
}

📝 ScriptStepExecutor - 脚本执行器

java 复制代码
/**
 * 脚本步骤执行器
 * 执行动态脚本代码
 */
public class ScriptStepExecutor extends AbstractStepExecutor {
    
    private final Map<String, ScriptEngine> scriptEngines = new ConcurrentHashMap<>();
    
    public ScriptStepExecutor() {
        initializeScriptEngines();
    }
    
    @Override
    protected Object doExecute(StepDefinition stepDefinition, FlowContext context) throws Exception {
        // 获取脚本配置
        String scriptType = getRequiredConfig(stepDefinition, "scriptType", String.class);
        String script = getRequiredConfig(stepDefinition, "script", String.class);
        
        logger.debug("执行脚本: 类型={}, 长度={}", scriptType, script.length());
        
        // 获取脚本引擎
        ScriptEngine engine = getScriptEngine(scriptType);
        if (engine == null) {
            throw new IllegalArgumentException("不支持的脚本类型: " + scriptType);
        }
        
        // 设置脚本上下文
        setupScriptContext(engine, context);
        
        // 执行脚本
        Object result = engine.eval(script);
        
        logger.debug("脚本执行完成,结果类型: {}", 
            result != null ? result.getClass().getSimpleName() : "null");
        
        return result;
    }
    
    /**
     * 初始化脚本引擎
     */
    private void initializeScriptEngines() {
        ScriptEngineManager manager = new ScriptEngineManager();
        
        // JavaScript引擎
        ScriptEngine jsEngine = manager.getEngineByName("javascript");
        if (jsEngine != null) {
            scriptEngines.put("javascript", jsEngine);
            scriptEngines.put("js", jsEngine);
        }
        
        // Groovy引擎(如果可用)
        ScriptEngine groovyEngine = manager.getEngineByName("groovy");
        if (groovyEngine != null) {
            scriptEngines.put("groovy", groovyEngine);
        }
        
        // Kotlin引擎(如果可用)
        ScriptEngine kotlinEngine = manager.getEngineByName("kotlin");
        if (kotlinEngine != null) {
            scriptEngines.put("kotlin", kotlinEngine);
            scriptEngines.put("kts", kotlinEngine);
        }
        
        logger.info("已初始化脚本引擎: {}", scriptEngines.keySet());
    }
    
    /**
     * 获取脚本引擎
     */
    private ScriptEngine getScriptEngine(String scriptType) {
        return scriptEngines.get(scriptType.toLowerCase());
    }
    
    /**
     * 设置脚本上下文
     */
    private void setupScriptContext(ScriptEngine engine, FlowContext context) {
        Bindings bindings = engine.createBindings();
        
        // 添加上下文数据
        bindings.put("context", context);
        
        // 添加所有上下文变量
        for (Map.Entry<String, Object> entry : context.getAll().entrySet()) {
            bindings.put(entry.getKey(), entry.getValue());
        }
        
        // 添加工具函数
        bindings.put("logger", logger);
        bindings.put("System", System.class);
        bindings.put("Math", Math.class);
        
        engine.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
    }
    
    @Override
    public StepType getSupportedType() {
        return StepType.SCRIPT;
    }
    
    @Override
    public ValidationResult validate(StepDefinition stepDefinition) {
        String scriptType = getConfig(stepDefinition, "scriptType", String.class);
        if (scriptType == null || scriptType.trim().isEmpty()) {
            return ValidationResult.error("脚本步骤必须指定scriptType配置");
        }
        
        String script = getConfig(stepDefinition, "script", String.class);
        if (script == null || script.trim().isEmpty()) {
            return ValidationResult.error("脚本步骤必须指定script配置");
        }
        
        // 检查脚本引擎是否可用
        if (getScriptEngine(scriptType) == null) {
            return ValidationResult.error("不支持的脚本类型: " + scriptType + 
                ", 可用类型: " + scriptEngines.keySet());
        }
        
        return ValidationResult.success();
    }
}

🧪 执行器测试示例

java 复制代码
public class StepExecutorTest {
    
    private FlowEngine flowEngine;
    private FlowContext context;
    
    @Before
    public void setUp() {
        flowEngine = new DefaultFlowEngine();
        context = new DefaultFlowContext();
        
        // 注册执行器
        flowEngine.registerExecutor(StepType.CONDITIONAL, 
            new ConditionalStepExecutor(new SimpleExpressionEvaluator(), flowEngine));
        flowEngine.registerExecutor(StepType.PARALLEL, 
            new ParallelStepExecutor(flowEngine));
        flowEngine.registerExecutor(StepType.LOOP, 
            new LoopStepExecutor(new SimpleExpressionEvaluator(), flowEngine));
        flowEngine.registerExecutor(StepType.SCRIPT, 
            new ScriptStepExecutor());
    }
    
    @Test
    public void testConditionalExecutor() {
        // 创建条件步骤
        StepDefinition conditionalStep = StepDefinitionBuilder
            .builder("age-check", StepType.CONDITIONAL)
            .config("condition", "context.get('age') >= 18")
            .config("trueSteps", Arrays.asList(
                StepDefinitionBuilder
                    .builder("adult-process", StepType.SIMPLE)
                    .config("action", "set")
                    .config("value", "成年人处理")
                    .config("targetKey", "result")
                    .build()
            ))
            .config("falseSteps", Arrays.asList(
                StepDefinitionBuilder
                    .builder("minor-process", StepType.SIMPLE)
                    .config("action", "set")
                    .config("value", "未成年人处理")
                    .config("targetKey", "result")
                    .build()
            ))
            .build();
        
        // 测试成年人情况
        context.put("age", 25);
        StepExecutor executor = flowEngine.getExecutor(StepType.CONDITIONAL);
        StepExecutionResult result = executor.execute(conditionalStep, context);
        
        assertEquals(FlowExecutionResult.Status.SUCCESS, result.getStatus());
        assertEquals("成年人处理", context.get("result"));
        
        // 测试未成年人情况
        context.clear();
        context.put("age", 16);
        result = executor.execute(conditionalStep, context);
        
        assertEquals(FlowExecutionResult.Status.SUCCESS, result.getStatus());
        assertEquals("未成年人处理", context.get("result"));
    }
    
    @Test
    public void testParallelExecutor() {
        // 创建并行步骤
        StepDefinition parallelStep = StepDefinitionBuilder
            .builder("parallel-tasks", StepType.PARALLEL)
            .config("timeoutSeconds", 10)
            .config("steps", Arrays.asList(
                StepDefinitionBuilder
                    .builder("task1", StepType.SIMPLE)
                    .config("action", "sleep")
                    .config("value", 100)
                    .build(),
                StepDefinitionBuilder
                    .builder("task2", StepType.SIMPLE)
                    .config("action", "sleep")
                    .config("value", 200)
                    .build()
            ))
            .build();
        
        long startTime = System.currentTimeMillis();
        
        StepExecutor executor = flowEngine.getExecutor(StepType.PARALLEL);
        StepExecutionResult result = executor.execute(parallelStep, context);
        
        long endTime = System.currentTimeMillis();
        
        assertEquals(FlowExecutionResult.Status.SUCCESS, result.getStatus());
        assertTrue("并行执行应该比串行执行快", endTime - startTime < 250);
        
        ParallelStepExecutor.ParallelExecutionResult parallelResult = 
            (ParallelStepExecutor.ParallelExecutionResult) result.getResult();
        assertEquals(2, parallelResult.getResults().size());
        assertFalse(parallelResult.hasFailures());
    }
    
    @Test
    public void testLoopExecutor() {
        // 创建循环步骤
        StepDefinition loopStep = StepDefinitionBuilder
            .builder("counter-loop", StepType.LOOP)
            .config("condition", "context.get('counter', 0) < 5")
            .config("maxIterations", 10)
            .config("steps", Arrays.asList(
                StepDefinitionBuilder
                    .builder("increment", StepType.SIMPLE)
                    .config("action", "increment")
                    .config("value", "counter")
                    .config("targetKey", "counter")
                    .build()
            ))
            .build();
        
        context.put("counter", 0);
        
        StepExecutor executor = flowEngine.getExecutor(StepType.LOOP);
        StepExecutionResult result = executor.execute(loopStep, context);
        
        assertEquals(FlowExecutionResult.Status.SUCCESS, result.getStatus());
        assertEquals(5, (int) context.get("counter"));
        
        LoopStepExecutor.LoopExecutionResult loopResult = 
            (LoopStepExecutor.LoopExecutionResult) result.getResult();
        assertEquals(5, loopResult.getTotalIterations());
    }
    
    @Test
    public void testScriptExecutor() {
        // 创建脚本步骤
        StepDefinition scriptStep = StepDefinitionBuilder
            .builder("calculate", StepType.SCRIPT)
            .config("scriptType", "javascript")
            .config("script", """
                var a = context.get('a');
                var b = context.get('b');
                var result = a + b;
                context.put('sum', result);
                result;
            """)
            .build();
        
        context.put("a", 10);
        context.put("b", 20);
        
        StepExecutor executor = flowEngine.getExecutor(StepType.SCRIPT);
        StepExecutionResult result = executor.execute(scriptStep, context);
        
        assertEquals(FlowExecutionResult.Status.SUCCESS, result.getStatus());
        assertEquals(30, result.getResult());
        assertEquals(30, (int) context.get("sum"));
    }
}

🎯 设计亮点

✨ 1. 模板方法模式

  • 🏗️ 统一的执行流程: AbstractStepExecutor定义了标准的执行模板
  • 🔧 灵活的扩展点: 子类只需实现核心逻辑
  • 🛡️ 统一的异常处理: 在基类中处理通用的异常情况

✨ 2. 策略模式

  • 🎯 可插拔的执行器: 不同类型的步骤使用不同的执行策略
  • 🔄 运行时选择: 根据步骤类型动态选择执行器
  • 🚀 易于扩展: 添加新的步骤类型只需实现新的执行器

✨ 3. 组合模式

  • 🌳 递归执行: 复杂步骤可以包含子步骤
  • 🔀 统一接口: 简单步骤和复合步骤使用相同的接口
  • 📊 层次结构: 支持任意深度的步骤嵌套

✨ 4. 并发安全

  • 🧵 线程安全: 使用线程安全的数据结构
  • 🔒 上下文隔离: 并行执行时创建独立的子上下文
  • 异步支持: 支持异步和并行执行

🎉 小结

在这一章中,我们完成了:

  • 🏗️ 设计了执行器架构: 基于AbstractStepExecutor的可扩展架构
  • 🔀 实现了条件执行器: 支持基于表达式的条件分支
  • 实现了并行执行器: 支持多任务并行执行
  • 🔄 实现了循环执行器: 支持条件循环和迭代控制
  • 📝 实现了脚本执行器: 支持多种脚本语言的动态执行
  • 🧪 提供了完整测试: 验证各种执行器的功能

🚀 下一步

在下一章《上下文管理机制》中,我们将:

  • 📦 深入设计FlowContext的实现
  • 🔒 实现线程安全的上下文管理
  • 🌳 设计层次化的上下文结构
  • 🔄 实现上下文的序列化和持久化
  • 🧪 编写上下文管理的完整测试

💡 思考题:

  1. 如何设计执行器的优先级和选择策略?
  2. 如何实现执行器的热插拔和动态加载?
  3. 如何设计才能支持执行器的配置和参数化?
相关推荐
long31616 分钟前
构建者设计模式 Builder
java·后端·学习·设计模式
Noii.44 分钟前
Spring Boot初级概念及自动配置原理
java·spring boot·后端
探索java1 小时前
Tomcat Server 组件原理
java·后端·tomcat
咕白m6251 小时前
通过 C# 高效提取 PDF 文本的完整指南
后端·c#
smallyu1 小时前
Go 语言 GMP 调度器的原理是什么
后端·go
掉头发的王富贵2 小时前
ShardingSphere-JDBC入门教程(上篇)
spring boot·后端·mysql
盖世英雄酱581362 小时前
必须掌握的【InheritableThreadLocal】
java·后端
LovelyAqaurius2 小时前
乐观锁及其实现方式详解
后端
绝无仅有2 小时前
编写 Go 项目的 Dockerfile 文件及生成 Docker 镜像
后端·面试·github
tager2 小时前
🍪 让你从此告别“Cookie去哪儿了?”
前端·javascript·后端