java中的模式 -凯发k8网页登录

开发出高质量的系统

常用链接

统计

积分与排名

好友之家

最新评论

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

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

11public 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}

25public interface command{
26    void execute();
27}

28public 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}

37public 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}

46public 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}

二,命令模式的功能,好处,或者说为什么使用命令模式?
上边的代码是否看起来很傻呢,本来可以这样简单实现的:
 1public class client{
 2    public static void main(string[] args){
 3        receiver receiver = new receiver();
 4        receiver.actionone();
 5        receiver.actiontwo();
 6    }

 7}

 8public 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

 1public 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}

23public 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,需求:有个固定命令组合会多次被执行
   解决:加入合成模式,实现方法如下,定义一个宏命令类:

 1public class macrocommand implements command{
 2    private list cmdlist = new arraylist();
 3    public add(command command){
 4        cmdlist.add(command);
 5    }

 6    public remove(command command){
 7        cmdlist.remove(command);
 8    }

 9    public void execute(){
10        command cmd;
11        for(int i=0;i<cmdlist.size();i){
12            cmd = (command)cmdlist.get(i);
13            cmd.execute();
14        }

15    }
    
16}

3,需求:须要redo undo
  解决:加入备忘录模式,一个简单的实现如下
 1public class concretecommandone implements command{
 2    private receiver receiver
 3    private receiver lastreceiver;
 4    public concretecommandone(receiver receiver){
 5        this.receiver = receiver;
 6    }

 7    public void execute(){
 8        record();
 9        receiver.actionone();
10    }

11    public void undo(){
12        //恢复状态
13    }

14    public void redo(){
15        lastreceiver.actionone();
16        //
17    }

18    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    :电视机
最后说一句,并不是全部按照模式写一定就好,应该根据你的需求来应用,或者全部应用,或者部分应用,或者根本不用。

posted on 2006-11-27 02:31 dreamstone 阅读(3498) 评论(3)  编辑  收藏 所属分类: 设计模式

# re: java中的模式 --- 命令模式的(实现,功能,使用场合)及如何配合其它模式使用命令模式 2006-11-27 17:21

写到太好了,清楚直接。谢谢~  回复     

# re: java中的模式 --- 命令模式的(实现,功能,使用场合)及如何配合其它模式使用命令模式 2007-08-07 12:35

写的不错!!  回复     

# re: java中的模式 --- 命令模式的(实现,功能,使用场合)及如何配合其它模式使用命令模式 2009-06-19 15:39

看过你的很多文章,受益匪浅,谢谢!  回复     


只有注册用户后才能发表评论。


网站导航:
              
 
网站地图