JBPM与软件架构模式之命令模式
前面我们介绍了JBPM的长事务设计,其中用到了职责链模式和命令模式,其中职责链模式我们已经介绍过了,今天我们来看看JBPM是怎样使用命令模式的。
命令模式定义
将请求封装成一个对象,使你可以使用不同的请求对客户端进行参数化;对请求排队和记录请求队列,并支持对请求的撤销操作。
命令模式UML类图
命令模式代码示例
package org.jbpm.pvm.internal.svc;
public abstract class Command {
protected Reciever reviever;
public Command(Reciever reviever)
{
this.reviever=reviever;
}
public abstract void Execution();
}
public abstract class Command {
protected Reciever reviever;
public Command(Reciever reviever)
{
this.reviever=reviever;
}
public abstract void Execution();
}
package org.jbpm.pvm.internal.svc;
public class ConcreteCommand extends Command{
public ConcreteCommand(Reciever reviever) {
super(reviever);
// TODO Auto-generated constructor stub
}
@Override
public void Execution() {
// TODO Auto-generated method stub
reviever.Action();
}
}
public class ConcreteCommand extends Command{
public ConcreteCommand(Reciever reviever) {
super(reviever);
// TODO Auto-generated constructor stub
}
@Override
public void Execution() {
// TODO Auto-generated method stub
reviever.Action();
}
}
package org.jbpm.pvm.internal.svc;
public class Invoker {
private Command command;
public void SetCommand(Command command)
{
this.command=command;
}
public void ExecutionCommand()
{
this.command.Execution();
}
}
public class Invoker {
private Command command;
public void SetCommand(Command command)
{
this.command=command;
}
public void ExecutionCommand()
{
this.command.Execution();
}
}
package org.jbpm.pvm.internal.svc;
public class Reciever {
public void Action(){}
}
public class Reciever {
public void Action(){}
}
package org.jbpm.pvm.internal.svc;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Reciever r=new Reciever();
Command c=new ConcreteCommand(r);
Invoker i=new Invoker();
i.SetCommand(c);
i.ExecutionCommand();
}
}
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Reciever r=new Reciever();
Command c=new ConcreteCommand(r);
Invoker i=new Invoker();
i.SetCommand(c);
i.ExecutionCommand();
}
}
命令模式的优点
可以比较容易的设置一个命令队列
在需要的情况下可以很容易的将命令记录下来
允许接受请求的一方决定是否否决命令
很容易实现对请求的撤销和重做
JBPM的命令模式实现
package org.jbpm.api;
import org.jbpm.api.history.HistoryComment;
import org.jbpm.api.history.HistoryActivityInstance;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface TaskService {
Task getTask(String taskId);
}
import org.jbpm.api.history.HistoryComment;
import org.jbpm.api.history.HistoryActivityInstance;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface TaskService {
Task getTask(String taskId);
}
package org.jbpm.pvm.internal.svc;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jbpm.api.TaskQuery;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryComment;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.cmd.AddParticipationCmd;
import org.jbpm.pvm.internal.cmd.AddReplyCommentCmd;
import org.jbpm.pvm.internal.cmd.AddTaskCommentCmd;
import org.jbpm.pvm.internal.cmd.AssignTaskCmd;
import org.jbpm.pvm.internal.cmd.CompositeCmd;
import org.jbpm.pvm.internal.cmd.DeleteTaskCmd;
import org.jbpm.pvm.internal.cmd.CompleteTaskCmd;
import org.jbpm.pvm.internal.cmd.CreateTaskQueryCmd;
import org.jbpm.pvm.internal.cmd.DeleteCommentCmd;
import org.jbpm.pvm.internal.cmd.GetOutcomes;
import org.jbpm.pvm.internal.cmd.GetParticipantsCmd;
import org.jbpm.pvm.internal.cmd.GetSubTasksCmd;
import org.jbpm.pvm.internal.cmd.GetTaskCmd;
import org.jbpm.pvm.internal.cmd.GetTaskCommentsCmd;
import org.jbpm.pvm.internal.cmd.GetTaskVariableNamesCmd;
import org.jbpm.pvm.internal.cmd.GetTaskVariablesCmd;
import org.jbpm.pvm.internal.cmd.NewTaskCmd;
import org.jbpm.pvm.internal.cmd.RemoveParticipantCmd;
import org.jbpm.pvm.internal.cmd.SaveTaskCmd;
import org.jbpm.pvm.internal.cmd.SetTaskVariablesCmd;
import org.jbpm.pvm.internal.query.TaskQueryImpl;
import org.jbpm.pvm.internal.task.TaskImpl;
public class TaskServiceImpl extends AbstractServiceImpl implements TaskService {
public Task getTask(String taskId) {
return commandService.execute(new GetTaskCmd(taskId));
}
}
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jbpm.api.TaskQuery;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryComment;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.cmd.AddParticipationCmd;
import org.jbpm.pvm.internal.cmd.AddReplyCommentCmd;
import org.jbpm.pvm.internal.cmd.AddTaskCommentCmd;
import org.jbpm.pvm.internal.cmd.AssignTaskCmd;
import org.jbpm.pvm.internal.cmd.CompositeCmd;
import org.jbpm.pvm.internal.cmd.DeleteTaskCmd;
import org.jbpm.pvm.internal.cmd.CompleteTaskCmd;
import org.jbpm.pvm.internal.cmd.CreateTaskQueryCmd;
import org.jbpm.pvm.internal.cmd.DeleteCommentCmd;
import org.jbpm.pvm.internal.cmd.GetOutcomes;
import org.jbpm.pvm.internal.cmd.GetParticipantsCmd;
import org.jbpm.pvm.internal.cmd.GetSubTasksCmd;
import org.jbpm.pvm.internal.cmd.GetTaskCmd;
import org.jbpm.pvm.internal.cmd.GetTaskCommentsCmd;
import org.jbpm.pvm.internal.cmd.GetTaskVariableNamesCmd;
import org.jbpm.pvm.internal.cmd.GetTaskVariablesCmd;
import org.jbpm.pvm.internal.cmd.NewTaskCmd;
import org.jbpm.pvm.internal.cmd.RemoveParticipantCmd;
import org.jbpm.pvm.internal.cmd.SaveTaskCmd;
import org.jbpm.pvm.internal.cmd.SetTaskVariablesCmd;
import org.jbpm.pvm.internal.query.TaskQueryImpl;
import org.jbpm.pvm.internal.task.TaskImpl;
public class TaskServiceImpl extends AbstractServiceImpl implements TaskService {
public Task getTask(String taskId) {
return commandService.execute(new GetTaskCmd(taskId));
}
}
public interface CommandService {
String NAME_TX_REQUIRED_COMMAND_SERVICE = "txRequiredCommandService";
String NAME_NEW_TX_REQUIRED_COMMAND_SERVICE = "newTxRequiredCommandService";
/**
* @throws JbpmException if command throws an exception.
*/
<T> T execute(Command<T> command);
}
String NAME_TX_REQUIRED_COMMAND_SERVICE = "txRequiredCommandService";
String NAME_NEW_TX_REQUIRED_COMMAND_SERVICE = "newTxRequiredCommandService";
/**
* @throws JbpmException if command throws an exception.
*/
<T> T execute(Command<T> command);
}
package org.jbpm.pvm.internal.svc;
import org.jbpm.pvm.internal.cmd.CommandService;
public class AbstractServiceImpl {
protected CommandService commandService;
public CommandService getCommandService() {
return commandService;
}
public void setCommandService(CommandService commandService) {
this.commandService = commandService;
}
}
import org.jbpm.pvm.internal.cmd.CommandService;
public class AbstractServiceImpl {
protected CommandService commandService;
public CommandService getCommandService() {
return commandService;
}
public void setCommandService(CommandService commandService) {
this.commandService = commandService;
}
}
public interface Command<T> extends Serializable {
T execute(Environment environment) throws Exception;
}
T execute(Environment environment) throws Exception;
}
public class GetTaskCmd extends Command<Task> {
private static final long serialVersionUID = 1L;
protected String taskId;
public GetTaskCmd(String taskId) {
if (taskId==null) {
throw new JbpmException("taskId is null");
}
this.taskId = taskId;
}
public Task execute(Environment environment) throws Exception {
DbSession dbSession = environment.get(DbSession.class);
return dbSession.get(TaskImpl.class, Long.parseLong(taskId));
}
}
private static final long serialVersionUID = 1L;
protected String taskId;
public GetTaskCmd(String taskId) {
if (taskId==null) {
throw new JbpmException("taskId is null");
}
this.taskId = taskId;
}
public Task execute(Environment environment) throws Exception {
DbSession dbSession = environment.get(DbSession.class);
return dbSession.get(TaskImpl.class, Long.parseLong(taskId));
}
}
JBPM使用命令模式的设计的优点请参见 JBPM长事务设计