模板方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法(primitive method);而将这些基本方法汇总起来的方法叫做模板方法(template method),这个设计模式的名字就是从此而来。
在activit中很多地方用到了此模式,用这个模式可以重用业务逻辑。
实例代码如下:
比如在ACTIVITI 的设置流程变量代码就采用了此模式。
1.抽象模板类。
public abstract class NeedsActiveExecutionCmd<T> implements Command<T>, Serializable { private static final long serialVersionUID = 1L; protected String executionId; public NeedsActiveExecutionCmd(String executionId) { this.executionId = executionId; } public T execute(CommandContext commandContext) { if(executionId == null) { throw new ActivitiIllegalArgumentException("executionId is null"); } ExecutionEntity execution = commandContext .getExecutionEntityManager() .findExecutionById(executionId); if (execution==null) { throw new ActivitiObjectNotFoundException("execution "+executionId+" doesn't exist", Execution.class); } if (execution.isSuspended()) { throw new ActivitiException(getSuspendedExceptionMessage()); } return execute(commandContext, execution); } /** * Subclasses should implement this method. * The provided {@link ExecutionEntity} is guaranteed to be active (ie. not suspended). */ protected abstract T execute(CommandContext commandContext, ExecutionEntity execution);
这个代码可以被其他的子类继承,这个类实现了根据executionId获取ExecutionEntity 实例逻辑,其他的子类可以继承这个类,实现 T execute(CommandContext commandContext, ExecutionEntity execution)方法。重用这此逻辑。
子类代码如下:
public class SetExecutionVariablesCmd extends NeedsActiveExecutionCmd<Object> { private static final long serialVersionUID = 1L; protected Map<String, ? extends Object> variables; protected boolean isLocal; public SetExecutionVariablesCmd(String executionId, Map<String, ? extends Object> variables, boolean isLocal) { super(executionId); this.variables = variables; this.isLocal = isLocal; } protected Object execute(CommandContext commandContext, ExecutionEntity execution) { if (isLocal) { execution.setVariablesLocal(variables); } else { execution.setVariables(variables); } // ACT-1887: Force an update of the execution's revision to prevent simultaneous inserts of the same // variable. If not, duplicate variables may occur since optimistic locking doesn't work on inserts execution.forceUpdate(); return null; } @Override protected String getSuspendedExceptionMessage() { return "Cannot set variables because execution '" + executionId + "' is suspended"; } }
protected Object execute(CommandContext commandContext, ExecutionEntity execution) 这个代码就是子类实现的逻辑。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人