最近在看Activiti的源代码,发现是基于命令模式进行的开发,所以对于Command模式做了个了解。
什么是命令模式?
这个随便翻开一本模式的书,都有介绍,这里就不再冗余了。画一个Command的图,然后加一个例子吧,方法和类的命名加入了自己的理解。
1、模式的根本是把“行为的请求者”和“行为的处理者”分开,实现解耦;
2、实现Command的ConcreteCommand,有时候要跟进实际情况保存额外的状态信息,例如上下文等;
3、大多数请求响应的处理,可以使用Command模式来扩展;
4、缺点的话,就是如果涉及的命令很多的话,本来简单的命令几行代码的事情,但是利用了这个模式之后,就需要搞一个类去做了;
1
2
3
4
5
|
//需要执行的命令都在这里
public
interface
Command {
//命令的执行方法
public
void
execute( ) ;
}
|
1
2
3
4
5
6
7
8
9
10
11
|
public
class
ConcreteCommand
implements
Command{
private
CommandProcess receiver;
@Override
public
void
execute() {
this
.receiver.doSomething();
}
public
ConcreteCommand(CommandProcess receiver) {
super
();
this
.receiver = receiver;
}
}
|
1
2
3
4
5
6
7
8
9
10
|
//调用命令
public
class
CommandInvoker {
private
Command command;
public
void
action(){
command.execute();
}
public
void
setCommand(Command command) {
this
.command = command;
}
}
|
1
2
3
4
5
|
//命令的执行者
public
interface
CommandProcess {
public
String doSomething();
}
|
1
2
3
4
5
6
7
8
9
|
public
class
CommandProcessForWindows
implements
CommandProcess {
@Override
public
String doSomething() {
System.out.println(
"ReceiverCmdForWindows doSomething "
);
return
"iamzhongyong windows"
;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
class
Client {
public
static
void
main(String[] args) {
CommandInvoker invoker =
new
CommandInvoker();
//确定命令的处理者,构建命令
CommandProcess process =
new
CommandProcessForWindows();
Command command =
new
ConcreteCommand(process);
invoker.setCommand(command);
invoker.action();
}
}
|
Activiti中的命令模式是咋样的?
看了源代码,发现应该是Command模式和责任链模式的结合,执行命令的之后,加入了迭代的成分在里面。
Command类,这个和标准的Command模式不同之处,就是execute方法中增加了CommandContext信息,这个类可以说是执行命令的上下文
1
2
3
4
5
|
public
interface
Command <T> {
T execute(CommandContext commandContext);
}
|
ServiceImpl类,所有的服务类继承这个,其实就一个作用,持有CommandExecutor类,这个类是命令的请求者
1
2
3
4
5
6
7
8
9
10
11
12
|
public
class
ServiceImpl {
protected
CommandExecutor commandExecutor;
public
CommandExecutor getCommandExecutor() {
return
commandExecutor;
}
public
void
setCommandExecutor(CommandExecutor commandExecutor) {
this
.commandExecutor = commandExecutor;
}
}
|
CommandExecutor这个是命令的执行,其中CommandConfig是命令的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
interface
CommandExecutor {
/**
* @return the default {@link CommandConfig}, used if none is provided.
*/
CommandConfig getDefaultConfig();
/**
* Execute a command with the specified {@link CommandConfig}.
*/
<T> T execute(CommandConfig config, Command<T> command);
/**
* Execute a command with the default {@link CommandConfig}.
*/
<T> T execute(Command<T> command);
}
|
这个是一个具体命令类,内部含义可以不用看,就是一个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/**
* @author Joram Barrez
*/
public
class
DeleteDeploymentCmd
implements
Command<Void>, Serializable {
private
static
final
long
serialVersionUID = 1L;
protected
String deploymentId;
protected
boolean
cascade;
public
DeleteDeploymentCmd(String deploymentId,
boolean
cascade) {
this
.deploymentId = deploymentId;
this
.cascade = cascade;
}
public
Void execute(CommandContext commandContext) {
if
(deploymentId ==
null
) {
throw
new
ActivitiIllegalArgumentException(
"deploymentId is null"
);
}
// Remove process definitions from cache:
Context
.getProcessEngineConfiguration()
.getDeploymentManager()
.removeDeployment(deploymentId, cascade);
return
null
;
}
}
|
CommandExecutor在啥时候初始化?
在ProcessEngineConfigurationImpl中有个init方法,里面有对于executor和intecerptor的初始化。
CommandExecutorImpl 这个是一个基本的实现,没有迭代的东西在里面,CommandInterceptor这个和CommmandExecutor一样的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
public
class
CommandExecutorImpl
implements
CommandExecutor {
private
final
CommandConfig defaultConfig;
private
final
CommandInterceptor first;
public
CommandExecutorImpl(CommandConfig defaultConfig, CommandInterceptor first) {
this
.defaultConfig = defaultConfig;
this
.first = first;
}
public
CommandInterceptor getFirst() {
return
first;
}
@Override
public
CommandConfig getDefaultConfig() {
return
defaultConfig;
}
@Override
public
<T> T execute(Command<T> command) {
return
execute(defaultConfig, command);
}
@Override
public
<T> T execute(CommandConfig config, Command<T> command) {
return
first.execute(config, command);
}
}
|
CommandInterceptor拦截类,有多个实现,这里是串接命令模式和责任链模式的衔接点
1
2
3
4
5
6
7
8
9
|
public
interface
CommandInterceptor {
<T> T execute(CommandConfig config, Command<T> command);
CommandInterceptor getNext();
void
setNext(CommandInterceptor next);
}
|