命令模式的核心是将对资源的调用封装成标准的命令格式,然后交给调用者调用
public interface Command{ public void open(); } public class CommandLight implements Command{ Light light; public CommandLight(Light light){this.Light = light;} public void open(){...}; } public class CommandMicrowave implements Command{ Microwave microwave; public CommandLight(Microwave microwave){this.Microwave=microwave;} public void open(){...}; } public class Invoker{ ArrayList<Command> commandList; public Invoker(){ commandList = new ArrayList<Command>(); } public void addCommand(Command command){...}; public void runOpen(){...} ... } public class DEMO{ public static void main(String[] args){ //装载invoker .......... //调用invoker ............. } }
命令模式用来将被调用者的实现与调用隔离,这样的实现有利于流水化作业,应用实例有队列化请求:java多线程的时候,调度器无需知道调用的线程到底在做什么,只需要在控制权交给该线程的时候调用线程的恢复状态和继续操作的函数。
//2015年9月2日23:22:22
最近重新思考了下命令模式,现在我认为命令模式还是更加适合异步模型,如果属于同步调用,那么我认为命令模式不如去掉invoker,而直接使用适配器模式,直接调用command对象的对应方法就可以实现解耦。
以java中线程模型为例,当我们需要使用线程的时候我们是需要让任务类实现runnable 接口,并且在run()方法中添加我们预期的操作,new出对应的线程对象并start之后,线程变启动执行了,这中间便是使用了命令模式,所有的线程任务被封装成runnable task,task放入到线程容器中,在线程拿到cpu占有权时候,进程执行run方法中的对应的方法。
我认为命令模式中的invoker可以作为一个单独的线程运行,我们通过其他线程向invoker中添加任务,而在invoker中实现任务的执行,可以在invoker中插入hook来实现额外的功能,比如操作日志和故障恢复等。由于本身是多线程模型,所以适合使用基于信号量的事件驱动模型,如果无需要执行的任务那么就把自己挂起,在插入任务的时候发出信号量唤醒沉睡的线程。