ts.flipdown( );
}
}
command.java
public interface command {
public abstract void execute ( );
}
在上面的示例代码中,command模式将 "调用操作的对象" (switch)和 "知道如何执行操作的对象" (light和fan)完全分离开来。这带来了很大的灵活性:发送请求的对象只需要知道如何发送;它不必知道如何完成请求。
command模式实现transaction
command模式也被称为action(动作)模式或transaction(事务)模式。假设有一个服务器,它接收并处理客户通过tcp/ip socket连接发送的transaction。这些transaction包含一个命令,后跟零个或多个 参数。
一些设计者可能会使用switch语句,每个command对应一个case。在一个面向对象工程的设计中,代码中如果使用switch语句,往往表示这是一个糟糕的设计。command模式展现的是支持transaction的面向对象的方法,它可以用于解决这类设计问题。
在testtransactioncommand.java程序的客户代码中,所有请求都被封装在通用的transactioncommand对象中。transactioncommand对象由客户创建并用commandmanager进行登记。等待的请求可以通过调用runcommands()在不同时期被执行,这带来了很大的灵活性。而且我们还可以将多个command组装成一个复合command。示例代码中还有commandargument,commandreceiver,commandmanager这些类,以及transactioncommand的子类--addcommand和subtractcommand。下面是对这些类的介绍。
· commandargument是一个helper类,它保存命令的参数。如果是大量(或可变数量)的任何类型的参数,它可以被重写,以简化参数的传递工作。
· commandreceiver实现所有的命令处理方法(command-processing method),它用singleton模式来实现。
· commandmanager是调用者,和前面例子中的switch相当。它在其私有mycommand变量中保存通用transactioncommand对象。runcommands()被调用时,它调用合适的transactioncommand对象的execute()。
java中,可以根据一个包含类名的字符串查找类的定义。在transactioncommand类的execute ()操作中,我先计算出类名,然后将它链接到运行系统中--也就是说,类是根据需要被即时载入的。这里所采用的命名方式是,在命令名后连接一个 "command" 字符串作为transaction command子类名,这样它就可以被动态载入。
注意,newinstance()返回的class对象必须被转换为合适的类型。这意味着新的类要么必须实现一个接口,要么继承一个在编译期就为程序所知道的现有的类。本例中我们是实现command接口,所以不存在问题。
file://testtransactioncommand.java
import java.util.*;
final class commandreceiver {
private int[] c;
private commandargument a;
private commandreceiver(){
c = new int[2];
}
private static commandreceiver cr = new commandreceiver();
public static commandreceiver gethandle() {
return cr;
}
public void setcommandargument(commandargument a) {
this.a = a;
}
public void methadd() {
c = a.getarguments();
system.out.println("the result is " + (c[0]+c[1]));
}
public void methsubtract() {
c = a.getarguments();
system.out.println("the result is " + (c[0]-c[1]));
}
}
class commandmanager {
private command mycommand;
public commandmanager(command mycommand) {
this.mycommand = mycommand ;
}
public void runcommands( ) {
mycommand.execute();
}
}
class transactioncommand implements command {
private commandreceiver commandreceiver;
private vector commandnamelist,commandargumentlist;
private string commandname;
private commandargument commandargument;
private command command;
public transactioncommand () {
this(null,null);
}
public transactioncommand ( vector commandnamelist, vector
commandargumentlist){
this.commandnamelist = commandnamelist;
this.commandargumentlist = commandargumentlist;
commandreceiver = commandreceiver.gethandle();
}
public void execute( ) {
for (int i = 0; i < commandnamelist.size(); i++) {
commandname = (string)(commandnamelist.get(i));
commandargument = (commandargument)((commandargumentlist.get(i)));
commandreceiver.setcommandargument(commandargument);
string classname = commandname + "command";