命令模式里边一般都有以下几个角色:客户端,请求者,命令接口,命令实现,接受者,
下边是简单命令模式的实现代码实现:
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 receiver30

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 receiver39

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
}
二,命令模式的功能,好处,或者说为什么使用命令模式?
上边的代码是否看起来很傻呢,本来可以这样简单实现的:
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
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
//按照自定义优先级,排序取出cmd21
}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,需求:有个固定命令组合会多次被执行
解决:加入合成模式,实现方法如下,定义一个宏命令类:
public
class
MacroCommand
implements
Command
{2
private List cmdList = new ArrayList();3
本文详细介绍了命令模式的概念、实现方式及应用场景,并对比了命令模式与其他模式的优劣,展示了如何通过命令模式来解决实际开发中遇到的问题。

519

被折叠的 条评论
为什么被折叠?



