简单_命令模式(command)

命令模式定义:命令模式用一句话表示就是说:一个命令一个类。在面向对象程式设计的范畴中,命令模式是一种设计模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。

先来看一看我本人认为每个人学设计模式不得不看的图,尽管“奇丑无比”,甚至曾经“束缚过我们的思想”
[img]http://dl.iteye.com/upload/attachment/0062/6156/c7b22ff0-00f7-350d-8ff0-04a6f48975b6.png[/img]

这个模式非常的简单,许多人都说JDK中的
java.lang.Runnable
javax.swing.Action
使用到了此模式,但javax.swing.Action我没看出来,可能是我眼拙只看到用了listener模式,这个很明显。

--------------------
网上都说命令模式的简单例子是这样的:玉帝下达了一道命令封孙悟空为弼马温,要太上老君去执行。下面以此来模拟命令模式。
package design.command;
/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午09:55:26 <br>
* 命令接口
*/
public interface Command {
void execute();
}

package design.command;

/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午09:55:51 <br>
* 圣旨
*/
public class ConcreteCommand implements Command {

private Receiver rev;

public ConcreteCommand(Receiver rev) {
this.rev = rev;
}

public void execute() {
System.out.println("command.execute");
this.rev.action();
}

}

package design.command;
/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午09:56:28 <br>
* 命令的接受者
*/
public class Receiver {
public void action(){
System.out.println("receiver.action");
}
}

package design.command;

/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午09:58:17 <br>
* 命令的执行者
*/
public class Invoker {
private Command command;

public Invoker(Command command) {
this.command = command;
}

//设置执行者要执行的命令
public void setCommand(Command command) {
this.command = command;
}

//执行命令
public void runCommand() {
System.out.println("Invoker.runCommand");
this.command.execute();
}
}

package design.command;
/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午09:54:54 <br>
*
*/
public class Test {
public static void main(String[] args) {
/*
* 命令模式:
* 玉帝下达了一道命令封孙悟空为弼马温,要太上老君去执行
*/
Receiver rev = new Receiver();//创建孙悟空----接受命令的人
Command command = new ConcreteCommand(rev);//创建一道给孙悟空的圣旨----命令
Invoker invoker = new Invoker(command);//创建执行该圣旨的人----太上老君
invoker.runCommand();//太上老君宣读该圣旨

//写成一句话(太上老君对孙悟空宣读圣旨)
new Invoker(new ConcreteCommand(new Receiver())).runCommand();
}
}

这样是命令模式正规的写法,反正是照着图片画代码,但是很显然我们的客户端的调用太啰嗦,客户端根本没必要做这么多事情,客户端其只要创建一个太上老君然后给他一道圣旨就OK了。
看下面改进后的代码(为了不产生混淆下面的代码和上面的不相关):
package design.command2;
/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午10:32:20 <br>
*
*/
public interface Command {
void execute();
}

package design.command2;
/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午10:32:43 <br>
* 改进后,接受者不在是一个具体的类而是一个抽象的接受者
*/
public interface Receiver {
void action();
}

package design.command2;

/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午10:33:27 <br>
* 圣旨--命令
*/
public class ShengzhiCommand implements Command {

//圣旨需要持有一个接受者的引用
private Receiver rev;

public ShengzhiCommand(Receiver rev) {
this.rev = rev;
}

public void execute() {
this.rev.action();
}

}

package design.command2;
/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午10:34:29 <br>
* 孙悟空------接受者
*/
public class SunWuKongReceiver implements Receiver{

public void action() {
System.out.println("孙悟空执行去当弼马温的圣旨");
}
}

package design.command2;

/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午10:35:28 <br>
* 太上老君----命令的执行者
*/
public class TaiShangLaoJunInvoker {
private Command command;

public void setCommand(Command command) {
this.command = command;
}

public void runCommand() {
this.command.execute();
}
}

package design.command2;
/**
* @author 作者 E-mail: jqsl2012@163.com
* @version 创建时间:2012-2-1 下午10:32:07 <br>
*
*/
public class Test {
public static void main(String[] args) {
TaiShangLaoJunInvoker t = new TaiShangLaoJunInvoker();
//只需要告诉太上老君 圣旨和孙悟空就行了
t.setCommand(new ShengzhiCommand(new SunWuKongReceiver()));
t.runCommand();
// t.runCommand();
}
}

很明显改进后客户端调用起来清晰多了。

最后:回归设计模式的自然美,为什么说是自然美呢?因为我打心眼里觉得设计真的很美,如果按照设计模式的图纸去写个例子出来其实并不难,但真正的理解设计模式然后灵活的运用却非常不容易,照着图纸写几个类其实你还是局限在设计模式的条条框框中。
其实真正的去理解一个模式最好的办法是[color=red]看它存在的意义[/color],也就是它是为什么而生的,如果无法理解它存在的真正的意义那估计是很难学好设计模式的,而其他的枝枝叶叶的都可以暂时不管,这是我学设计模式的体会。就拿此模式来说,其存在的目的就是把命令搞成对象的形式,理解了这就够了,然后那些枝枝叶叶的啊全当扯蛋,先把精髓理解了在理解枝枝叶叶,然后结合JDK看模式会发现相当简单。
都说java.lang.Runnable是命令模式,如果较真的和图片去比较那确实不是,但它其实是命令模式,反正不管东西南北,只要把命令搞成对象的形式能执行、取消、记录等等就都算命令模式了,这也算是模式回归自然吧,一种广义的理解,可能狭义的理解就是图片的样子了。
如果学模式老抱着个图片死在那看估计越学越受打击,最后落得个设计模式恐惧症。
前几天iteye不就有人把设计模式搞成chm的文件吗!

所以[color=red]运用设计模式在于运用其思想而非招式[/color],菜鸟就算给他把绝世宝剑也杀不了人,但独孤前辈却能用树枝杀人。李小龙对武术的理解是去除繁杂的招式,没必要搞的明明要打别人一拳却先翻几个跟头然后转几圈。。。何必呢。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值