Java中的模式 --- 命令模式的(实现,功能,使用场合)及如何配合其它模式使用命令模式...

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

10ExpandedBlockEnd.gif}

11 ExpandedBlockStart.gifContractedBlock.gif public   class  Invoker dot.gif {
12InBlock.gif    private Command commandOne;
13InBlock.gif    private Command commandTwo;
14ExpandedSubBlockStart.gifContractedSubBlock.gif    public Invoker(Command commandOne,Command commandTwo)dot.gif{
15InBlock.gif        this.commandOne = commandOne;
16InBlock.gif        this.commandTwo = commandTwo;
17ExpandedSubBlockEnd.gif    }

18ExpandedSubBlockStart.gifContractedSubBlock.gif    public void actionOne()dot.gif{
19InBlock.gif        commandOne.execute();
20ExpandedSubBlockEnd.gif    }

21ExpandedSubBlockStart.gifContractedSubBlock.gif    public void actionTwo()dot.gif{
22InBlock.gif        commandTwo.execute();
23ExpandedSubBlockEnd.gif    }

24ExpandedBlockEnd.gif}

25 ExpandedBlockStart.gifContractedBlock.gif public   interface  Command dot.gif {
26InBlock.gif    void execute();
27ExpandedBlockEnd.gif}

28 ExpandedBlockStart.gifContractedBlock.gif public   class  ConcreteCommandOne  implements  Command dot.gif {
29InBlock.gif    private Receiver receiver
30ExpandedSubBlockStart.gifContractedSubBlock.gif    public ConcreteCommandOne(Receiver receiver)dot.gif{
31InBlock.gif        this.receiver = receiver;
32ExpandedSubBlockEnd.gif    }

33ExpandedSubBlockStart.gifContractedSubBlock.gif    public void execute()dot.gif{
34InBlock.gif        receiver.actionOne();
35ExpandedSubBlockEnd.gif    }

36ExpandedBlockEnd.gif}

37 ExpandedBlockStart.gifContractedBlock.gif public   class  ConcreteCommandTwo  implements  Command dot.gif {
38InBlock.gif    private Receiver receiver
39ExpandedSubBlockStart.gifContractedSubBlock.gif    public ConcreteCommandTwo(Receiver receiver)dot.gif{
40InBlock.gif        this.receiver = receiver;
41ExpandedSubBlockEnd.gif    }

42ExpandedSubBlockStart.gifContractedSubBlock.gif    public void execute()dot.gif{
43InBlock.gif        receiver.actionTwo();
44ExpandedSubBlockEnd.gif    }

45ExpandedBlockEnd.gif}

46 ExpandedBlockStart.gifContractedBlock.gif public   class  Receiver dot.gif {
47ExpandedSubBlockStart.gifContractedSubBlock.gif    public Receiver()dot.gif{
48InBlock.gif        //dot.gif
49ExpandedSubBlockEnd.gif    }

50ExpandedSubBlockStart.gifContractedSubBlock.gif    public void actionOne()dot.gif{
51InBlock.gif        System.out.println("ActionOne has been taken.");
52ExpandedSubBlockEnd.gif    }

53ExpandedSubBlockStart.gifContractedSubBlock.gif    public void actionTwo()dot.gif{
54InBlock.gif        System.out.println("ActionTwo has been taken.");
55ExpandedSubBlockEnd.gif    }

56ExpandedBlockEnd.gif}

二,命令模式的功能,好处,或者说为什么使用命令模式?
上边的代码是否看起来很傻呢,本来可以这样简单实现的:
 1 ExpandedBlockStart.gif ContractedBlock.gif public   class  Client dot.gif {
 2ExpandedSubBlockStart.gifContractedSubBlock.gif    public static void main(String[] args)dot.gif{
 3InBlock.gif        Receiver receiver = new Receiver();
 4InBlock.gif        receiver.actionOne();
 5InBlock.gif        receiver.actionTwo();
 6ExpandedSubBlockEnd.gif    }

 7ExpandedBlockEnd.gif}

 8 ExpandedBlockStart.gifContractedBlock.gif public   class  Receiver dot.gif {
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    public Receiver()dot.gif{
10InBlock.gif        //dot.gif
11ExpandedSubBlockEnd.gif    }

12ExpandedSubBlockStart.gifContractedSubBlock.gif    public void actionOne()dot.gif{
13InBlock.gif        System.out.println("ActionOne has been taken.");
14ExpandedSubBlockEnd.gif    }

15ExpandedSubBlockStart.gifContractedSubBlock.gif    public void actionTwo()dot.gif{
16InBlock.gif        System.out.println("ActionTwo has been taken.");
17ExpandedSubBlockEnd.gif    }

18ExpandedBlockEnd.gif}


看多简洁,如果是像上边如此简单的需求,这个才应该是我们的选择,但是有些情况下这样的写法不能解决的,
或者说解决起来不好,所以引入命令模式.
(1)我们须要Client和Receiver同时开发,而且在开发过程中分别须要不停重购,改名
(2)如果我们要求Redo ,Undo等功能
(3)我们须要命令不按照调用执行,而是按照执行时的情况排序,执行
(4)开发后期,我们发现必须要log哪些方法执行了,如何在尽量少更改代码的情况下实现.并且渐少重复代码
(5)在上边的情况下,我们的接受者有很多,不止一个
解决办法:
情况一,我们可以定义一个接口,让Receiver实现这个接口,Client按照接口调用。
情况二,我们可以让Receiver记住一些状态,例如执行前的自己的状态,用来undo,但自己记录自己的状态
 实现起来比较混乱,一般都是一个累记录另一个类的状态.
情况三,很难实现
情况四,,我们须要在每个Action,前后加上log
情况五,相对好实现,但是再加上这个,是否感觉最终的实现很混乱呢
好,我们再来看看命令模式,在命令模式中,我们增加一些过渡的类,这些类就是上边的命名接口和命令实现,
这样就很好的解决了情况一,情况二。我们再加入一个Invoker,这样情况三和情况四就比较好解决了。

如下加入Log和排序后的Invoker

 1 ExpandedBlockStart.gif ContractedBlock.gif public   class  Invoker dot.gif {
 2InBlock.gif    private List cmdList = new ArrayList();
 3ExpandedSubBlockStart.gifContractedSubBlock.gif    public Invoker()dot.gif{
 4ExpandedSubBlockEnd.gif    }

 5ExpandedSubBlockStart.gifContractedSubBlock.gif    public add(Command command)dot.gif{
 6InBlock.gif        cmdList.add(command);
 7ExpandedSubBlockEnd.gif    }

 8ExpandedSubBlockStart.gifContractedSubBlock.gif    public remove(Command command)dot.gif{
 9InBlock.gif        cmdList.remove(command);
10ExpandedSubBlockEnd.gif    }

11ExpandedSubBlockStart.gifContractedSubBlock.gif    public void action()dot.gif{
12InBlock.gif        Command cmd;
13ExpandedSubBlockStart.gifContractedSubBlock.gif        while((cmd =getCmd()) != null)dot.gif{
14InBlock.gif            log("begin"+cmd.getName());
15InBlock.gif            cmd.execute();
16InBlock.gif            log("end"+cmd.getName());        
17ExpandedSubBlockEnd.gif        }

18ExpandedSubBlockEnd.gif    }

19ExpandedSubBlockStart.gifContractedSubBlock.gif    public Command getCmd()dot.gif{
20InBlock.gif        //按照自定义优先级,排序取出cmd
21ExpandedSubBlockEnd.gif    }

22ExpandedBlockEnd.gif}

23 ExpandedBlockStart.gifContractedBlock.gif public   class  Client dot.gif {
24ExpandedSubBlockStart.gifContractedSubBlock.gif    public static void main(String[] args)dot.gif{
25InBlock.gif        Receiver receiver = new Receiver();
26InBlock.gif        Command commandOne = new ConcreteCommandOne(receiver);
27InBlock.gif        Command commandTwo = new ConcreteCommandTwo(receiver);
28InBlock.gif        Invoker invoker = new Invoker();
29InBlock.gif        invoker.add(commandOne);
30InBlock.gif        invoker.add(commandTwo);
31InBlock.gif        iinvoker.action();
32ExpandedSubBlockEnd.gif    }

33ExpandedBlockEnd.gif}


三,命令模式与其它模式的配合使用:
1,看上边的Invoker的实现是否很像代理模式呢,Invoker的这种实现其实就是一种代理模式。

2,需求:有个固定命令组合会多次被执行
   解决:加入合成模式,实现方法如下,定义一个宏命令类:

 1 ExpandedBlockStart.gif ContractedBlock.gif public   class  MacroCommand  implements  Command dot.gif {
 2InBlock.gif    private List cmdList = new ArrayList();
 3ExpandedSubBlockStart.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值