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();
}
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();
}
}
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();
}
}
package
org.jbpm.pvm.internal.svc;
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();
}
}
命令模式的优点
可以比较容易的设置一个命令队列
在需要的情况下可以很容易的将命令记录下来
允许接受请求的一方决定是否否决命令
很容易实现对请求的撤销和重做
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);
}
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));
}
}
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);
}
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;
}
}
public
interface
Command
<
T
>
extends
Serializable {
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));
}
}
JBPM使用命令模式的设计的优点请参见 JBPM长事务设计