一,命令模式的实现:
命令模式里边一般都有以下几个角色:客户端,请求者,命令接口,命令实现,接受者,
下边是简单命令模式的实现代码实现:
1
public
class
Client
{
2
public static void main(String[] args)
{
3
Receiver receiver = new Receiver();
4
Command commandOne = new ConcreteCommandOne(receiver);
5
Command commandTwo = new ConcreteCommandTwo(receiver);
6
Invoker invoker = new Invoker(commandOne,commandTwo);
7
invoker.actionOne();
8
invoker.actionTwo();
9
}
10
}
11

public
class
Invoker
{
12
private Command commandOne;
13
private Command commandTwo;
14
public Invoker(Command commandOne,Command commandTwo)
{
15
this.commandOne = commandOne;
16
this.commandTwo = commandTwo;
17
}
18
public void actionOne()
{
19
commandOne.execute();
20
}
21
public void actionTwo()
{
22
commandTwo.execute();
23
}
24
}
25

public
interface
Command
{
26
void execute();
27
}
28

public
class
ConcreteCommandOne
implements
Command
{
29
private Receiver receiver
30
public ConcreteCommandOne(Receiver receiver)
{
31
this.receiver = receiver;
32
}
33
public void execute()
{
34
receiver.actionOne();
35
}
36
}
37

public
class
ConcreteCommandTwo
implements
Command
{
38
private Receiver receiver
39
public ConcreteCommandTwo(Receiver receiver)
{
40
this.receiver = receiver;
41
}
42
public void execute()
{
43
receiver.actionTwo();
44
}
45
}
46

public
class
Receiver
{
47
public Receiver()
{
48
//
49
}
50
public void actionOne()
{
51
System.out.println("ActionOne has been taken.");
52
}
53
public void actionTwo()
{
54
System.out.println("ActionTwo has been taken.");
55
}
56
}
二,命令模式的功能,好处,或者说为什么使用命令模式?
上边的代码是否看起来很傻呢,本来可以这样简单实现的:
1
public
class
Client
{
2
public static void main(String[] args)
{
3
Receiver receiver = new Receiver();
4
receiver.actionOne();
5
receiver.actionTwo();
6
}
7
}
8

public
class
Receiver
{
9
public Receiver()
{
10
//
11
}
12
public void actionOne()
{
13
System.out.println("ActionOne has been taken.");
14
}
15
public void actionTwo()
{
16
System.out.println("ActionTwo has been taken.");
17
}
18
}
看多简洁,如果是像上边如此简单的需求,这个才应该是我们的选择,但是有些情况下这样的写法不能解决的,
或者说解决起来不好,所以引入命令模式.
(1)我们须要Client和Receiver同时开发,而且在开发过程中分别须要不停重购,改名
(2)如果我们要求Redo ,Undo等功能
(3)我们须要命令不按照调用执行,而是按照执行时的情况排序,执行
(4)开发后期,我们发现必须要log哪些方法执行了,如何在尽量少更改代码的情况下实现.并且渐少重复代码
(5)在上边的情况下,我们的接受者有很多,不止一个
解决办法:
情况一,我们可以定义一个接口,让Receiver实现这个接口,Client按照接口调用。
情况二,我们可以让Receiver记住一些状态,例如执行前的自己的状态,用来undo,但自己记录自己的状态
实现起来比较混乱,一般都是一个累记录另一个类的状态.
情况三,很难实现
情况四,,我们须要在每个Action,前后加上log
情况五,相对好实现,但是再加上这个,是否感觉最终的实现很混乱呢
好,我们再来看看命令模式,在命令模式中,我们增加一些过渡的类,这些类就是上边的命名接口和命令实现,
这样就很好的解决了情况一,情况二。我们再加入一个Invoker,这样情况三和情况四就比较好解决了。
如下加入Log和排序后的Invoker
1
public
class
Invoker
{
2
private List cmdList = new ArrayList();
3
public Invoker()
{
4
}
5
public add(Command command)
{
6
cmdList.add(command);
7
}
8
public remove(Command command)
{
9
cmdList.remove(command);
10
}
11
public void action()
{
12
Command cmd;
13
while((cmd =getCmd()) != null)
{
14
log("begin"+cmd.getName());
15
cmd.execute();
16
log("end"+cmd.getName());
17
}
18
}
19
public Command getCmd()
{
20
//按照自定义优先级,排序取出cmd
21
}
22
}
23

public
class
Client
{
24
public static void main(String[] args)
{
25
Receiver receiver = new Receiver();
26
Command commandOne = new ConcreteCommandOne(receiver);
27
Command commandTwo = new ConcreteCommandTwo(receiver);
28
Invoker invoker = new Invoker();
29
invoker.add(commandOne);
30
invoker.add(commandTwo);
31
iinvoker.action();
32
}
33
}
三,命令模式与其它模式的配合使用:
1,看上边的Invoker的实现是否很像代理模式呢,Invoker的这种实现其实就是一种代理模式。
2,需求:有个固定命令组合会多次被执行
解决:加入合成模式,实现方法如下,定义一个宏命令类:
1
public
class
MacroCommand
implements
Command
{
2
private List cmdList = new ArrayList();
3