命令模式提供一个处理用户请求的标准接口。每个请求被封装名为Command的对象中。命令模式中的三个类分别是:Command、CommandManager和Invoker。
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,处理所有的请求,使用一个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); } }
负责按照一定方式执行命令类。看下面的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