命令模式提供一个处理用户请求的标准接口。每个请求被封装名为Command的对象中。命令模式中的三个类分别是:Command、CommandManager和Invoker。
Command
Command类表示单个行为的封装。应用程序中的每个行为,例如保存或者删除,都会被建模为命令。这样,应用程序的行为就是命令对象的集合。要向应用程序添加行为,开发人员要做的就只是实现附加的命令对象。
如下:
package command;
public interface Command {
public void execute();
}
Command接口,只是含有一个execute方法,其它的实现Command接口的类(DefaultCommand )就是一个命令,如下:
package command;
public class DefaultCommand implements Command{
public void execute(){
System.out.println("DefaultCommand命令执行中...");
}
}
当然,也可以扩展Command接口,实现更多的功能:
package command;
import java.util.Collection;
import java.util.Map;
/**
* 扩展自Command接口,ManagedCommand实现了该接口
*
*/
public interface ManagedLifecycle extends Command{
public void setApplicationContext(Map context);//用于传输需要的应用程序数据
public void initialize();//初始化方法
public boolean isValidated();//执行验证
public Collection<?> getErrors();//获取错误信息
public void destory();//销毁
}
下面是实现ManagedCommand类,实现了ManagedLifecycle,也是一个命令:
package command;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* 比DefaultCommand功能丰富很多,首先传递需要的应用程序数据,调用初始化方法,执行验证,最后执行命令
*
*
*/
public class ManagedCommand implements ManagedLifecycle{
private Map<?,?> context;
private Map<?,?> errors = new HashMap();
//初始化
public void initialize() {
System.out.println("初始化...");
}
//执行
public void execute() {
System.out.println("ManagedCommand命令执行中...");
}
//销毁
public void destory() {
System.out.println("销毁中...");
}
//是否验证成功
public boolean isValidated() {
System.out.println("验证成功...");
return true;
}
public void setApplicationContext(Map context) {
System.out.println("传输应用程序数据...");
this.context = context;
}
//获取错误信息
public Collection<?> getErrors() {
return errors.values();
}
}
CommandManager
命令模式的下一个组件CommandManager,该类负责管理对应用程序可用的命令。下面的CommandManager,处理所有的请求,使用一个HashMap,所有的命令将在请求处理之前被初始化,然后通过名称被获取
package command;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* 处理所有的请求,使用一个HashMap,所有的命令将在请求处理之前被初始化,然后通过名称被获取
*
*/
public class CommandManager {
private Map<String, Command> commands = new HashMap<String, Command>();
public void add(String name, Command command){
commands.put(name,command);
}
public Command getCommand(String name){
return commands.get(name);
}
}
Invoker
负责按照一定方式执行命令类。看下面的Client类:
package command;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
/**
* 一个单独的客户端可以掩饰命令模式的执行。单调用Client构造憾事是,它想管理器添加
*/
public class Client {
private Map context = new HashMap();
private CommandManager manager = new CommandManager();
public Client(){
manager.add("default", new DefaultCommand());
//一个新的命令添加到CommandManager中去
manager.add("Managed", new ManagedCommand());
}
public void invoke(String name){
Command command = manager.getCommand(name);
//确定被执行的命令是否实现了ManagedLifecycle接口
if(command instanceof ManagedLifecycle){
ManagedLifecycle managed =(ManagedLifecycle) command;
managed.setApplicationContext(context);
managed.initialize();
if(managed.isValidated()){
managed.execute();
}else{
Collection<?> error = managed.getErrors();
}
managed.destory();
}else{
command.execute();
}
}
public static void main(String[] args){
Client client = new Client();
System.out.println("1、执行DefaultCommand命令:");
client.invoke("default");
System.out.println("2、执行ManagedCommand命令:");
client.invoke("Managed");
}
}
运行结果:
允许客户端Invoker将资源传递到命令中是一个非常强大的概念,被称为反向控制(inversion of control,IOC)或依赖关系注入。它无需Command类去查找可用于invoker的服务和资源。
命令模式例子:使用命令模式,告别if-else