模板方法模式需要開發抽象類和具體子類的設計師之間的協作。一個設計師負責給出一個算法的輪廓和骨架,另一些設計師則負責給出這個算法的各個邏輯步驟。代表這些具體邏輯步驟的方法稱做基本方法(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) 這個代碼就是子類實現的邏輯。