一,命令模式的实现:
命令模式里边一般都有以下几个角色:客户端,请求者,命令接口,命令实现,接受者,
下边是简单命令模式的实现代码实现: 
 1
 public class Client
public class Client {
{
 2
 public static void main(String[] args)
    public static void main(String[] args) {
{
 3 Receiver receiver = new Receiver();
        Receiver receiver = new Receiver();
 4 Command commandOne = new ConcreteCommandOne(receiver);
        Command commandOne = new ConcreteCommandOne(receiver);
 5 Command commandTwo = new ConcreteCommandTwo(receiver);
        Command commandTwo = new ConcreteCommandTwo(receiver);
 6 Invoker invoker = new Invoker(commandOne,commandTwo);
        Invoker invoker = new Invoker(commandOne,commandTwo);
 7 invoker.actionOne();
        invoker.actionOne();
 8 invoker.actionTwo();
        invoker.actionTwo();
 9 }
    }
10 }
}
11
 public class Invoker
public class Invoker {
{
12 private Command commandOne;
    private Command commandOne;
13 private Command commandTwo;
    private Command commandTwo;
14
 public Invoker(Command commandOne,Command commandTwo)
    public Invoker(Command commandOne,Command commandTwo) {
{
15 this.commandOne = commandOne;
        this.commandOne = commandOne;
16 this.commandTwo = commandTwo;
        this.commandTwo = commandTwo;
17 }
    }
18
 public void actionOne()
    public void actionOne() {
{
19 commandOne.execute();
        commandOne.execute();
20 }
    }
21
 public void actionTwo()
    public void actionTwo() {
{
22 commandTwo.execute();
        commandTwo.execute();
23 }
    }
24 }
}
25
 public interface Command
public interface Command {
{
26 void execute();
    void execute();
27 }
}
28
 public class ConcreteCommandOne implements Command
public class ConcreteCommandOne implements Command {
{
29 private Receiver receiver
    private Receiver receiver
30
 public ConcreteCommandOne(Receiver receiver)
    public ConcreteCommandOne(Receiver receiver) {
{
31 this.receiver = receiver;
        this.receiver = receiver;
32 }
    }
33
 public void execute()
    public void execute() {
{
34 receiver.actionOne();
        receiver.actionOne();
35 }
    }
36 }
}
37
 public class ConcreteCommandTwo implements Command
public class ConcreteCommandTwo implements Command {
{
38 private Receiver receiver
    private Receiver receiver
39
 public ConcreteCommandTwo(Receiver receiver)
    public ConcreteCommandTwo(Receiver receiver) {
{
40 this.receiver = receiver;
        this.receiver = receiver;
41 }
    }
42
 public void execute()
    public void execute() {
{
43 receiver.actionTwo();
        receiver.actionTwo();
44 }
    }
45 }
}
46
 public class Receiver
public class Receiver {
{
47
 public Receiver()
    public Receiver() {
{
48 //
        //
49 }
    }
50
 public void actionOne()
    public void actionOne() {
{
51 System.out.println("ActionOne has been taken.");
        System.out.println("ActionOne has been taken.");
52 }
    }
53
 public void actionTwo()
    public void actionTwo() {
{
54 System.out.println("ActionTwo has been taken.");
        System.out.println("ActionTwo has been taken.");
55 }
    }
56 }
} 二,命令模式的功能,好处,或者说为什么使用命令模式?
上边的代码是否看起来很傻呢,本来可以这样简单实现的:
 1
 public class Client
public class Client {
{
 2
 public static void main(String[] args)
    public static void main(String[] args) {
{
 3 Receiver receiver = new Receiver();
        Receiver receiver = new Receiver();
 4 receiver.actionOne();
        receiver.actionOne();
 5 receiver.actionTwo();
        receiver.actionTwo();
 6 }
    }
 7 }
}
 8
 public class Receiver
public class Receiver {
{
 9
 public Receiver()
    public Receiver() {
{
10 //
        //
11 }
    }
12
 public void actionOne()
    public void actionOne() {
{
13 System.out.println("ActionOne has been taken.");
        System.out.println("ActionOne has been taken.");
14 }
    }
15
 public void actionTwo()
    public void actionTwo() {
{
16 System.out.println("ActionTwo has been taken.");
        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
public class Invoker {
{
 2 private List cmdList = new ArrayList();
    private List cmdList = new ArrayList();
 3
 public Invoker()
    public Invoker() {
{
 4 }
    }
 5
 public add(Command command)
    public add(Command command) {
{
 6 cmdList.add(command);
        cmdList.add(command);
 7 }
    }
 8
 public remove(Command command)
    public remove(Command command) {
{
 9 cmdList.remove(command);
        cmdList.remove(command);
10 }
    }
11
 public void action()
    public void action() {
{
12 Command cmd;
        Command cmd;
13
 while((cmd =getCmd()) != null)
        while((cmd =getCmd()) != null) {
{
14 log("begin"+cmd.getName());
            log("begin"+cmd.getName());
15 cmd.execute();
            cmd.execute();
16 log("end"+cmd.getName());
            log("end"+cmd.getName());        
17 }
        }
18 }
    }
19
 public Command getCmd()
    public Command getCmd() {
{
20 //按照自定义优先级,排序取出cmd
        //按照自定义优先级,排序取出cmd
21 }
    }
22 }
}
23
 public class Client
public class Client {
{
24
 public static void main(String[] args)
    public static void main(String[] args) {
{
25 Receiver receiver = new Receiver();
        Receiver receiver = new Receiver();
26 Command commandOne = new ConcreteCommandOne(receiver);
        Command commandOne = new ConcreteCommandOne(receiver);
27 Command commandTwo = new ConcreteCommandTwo(receiver);
        Command commandTwo = new ConcreteCommandTwo(receiver);
28 Invoker invoker = new Invoker();
        Invoker invoker = new Invoker();
29 invoker.add(commandOne);
        invoker.add(commandOne);
30 invoker.add(commandTwo);
        invoker.add(commandTwo);
31 iinvoker.action();
        iinvoker.action();
32 }
    }
33 }
} 
三,命令模式与其它模式的配合使用:
1,看上边的Invoker的实现是否很像代理模式呢,Invoker的这种实现其实就是一种代理模式。
2,需求:有个固定命令组合会多次被执行
   解决:加入合成模式,实现方法如下,定义一个宏命令类:
 1
 public class MacroCommand implements Command
public class MacroCommand implements Command {
{
 2 private List cmdList = new ArrayList();
    private List cmdList = new ArrayList();
 3
 public add(Command command)
    public add(Command command) {
{
 4 cmdList.add(command);
        cmdList.add(command);
 5 }
    }
 6
 public remove(Command command)
    public remove(Command command) {
{
 7 cmdList.remove(command);
        cmdList.remove(command);
 8 }
    }
 9
 public void execute()
    public void execute() {
{
10 Command cmd;
        Command cmd;
11
 for(int i=0;i<cmdList.size();i++)
        for(int i=0;i<cmdList.size();i++) {
{
12 cmd = (Command)cmdList.get(i);
            cmd = (Command)cmdList.get(i);
13 cmd.execute();
            cmd.execute();
14 }
        }
15 }
    }    
16 }
} 3,需求:须要redo undo
  解决:加入备忘录模式,一个简单的实现如下
 1
 public class ConcreteCommandOne implements Command
public class ConcreteCommandOne implements Command {
{
 2 private Receiver receiver
    private Receiver receiver
 3 private Receiver lastReceiver;
    private Receiver lastReceiver;
 4
 public ConcreteCommandOne(Receiver receiver)
    public ConcreteCommandOne(Receiver receiver) {
{
 5 this.receiver = receiver;
        this.receiver = receiver;
 6 }
    }
 7
 public void execute()
    public void execute() {
{
 8 record();
        record();
 9 receiver.actionOne();
        receiver.actionOne();
10 }
    }
11
 public void undo()
    public void undo() {
{
12 //恢复状态
        //恢复状态
13 }
    }
14
 public void redo()
    public void redo() {
{
15 lastReceiver.actionOne();
        lastReceiver.actionOne();
16 //
        //
17 }
    }
18
 public record()
    public record() {
{
19 //记录状态
        //记录状态
20 }
    }
21 }
} 4,需求:命令很多类似的地方
   解决:使用原型模式,利用clone
   这个就不写例子了。
四,命令模式的使用场合
1,须要callback的时候,例如java awt/swing/swt中的Listening的消息方式
2,须要对请求排队执行,命令的发送者和接受者有不同对的生命周期,就是命令执行的时候,可能发出命令的
Client已经不存在了
3,须要Redo Undo等函数
4,须要log每条命令
5,须要支持transaction,封装一组数据命令的时候.
五,最后再次总结一下命令模式的优点和缺点:
优点:
降低Client和命令接受者的耦合,是命令请求和命令执行的对象分割
便于修改和扩张
便于聚合多个命令
缺点:
造成出现过多的具体命令类,太多文件。
五,一个比较有意思的例子,来说明命令模式
Client        :看电视的人
Invoker     :遥控器
Command :电信号
具体命令 :遥控器上的按键对应的不同的电信号
Receiver    :电视机
最后说一句,并不是全部按照模式写一定就好,应该根据你的需求来应用,或者全部应用,或者部分应用,或者根本不用。