设计模式整理_命令模式

  命令模式将请求封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象,命令模式也支持可撤销的操作.当需要将发出请求的对象和执行请求的对象解耦的时候,采用命令模式.

  命令模式中有几个名词:调用者,命令,接受者,客户.客户负责创建命令和调用者,调用者将命令封装在自己里面,当客户需要执行某些操作的时候,调用者就将调用命令对象的方法,命令对象通知接受者执行操作.一个命令对象通过在特定的接受者上绑定一组动作来封装一个请求,调用者可以接受命令作为自己的参数,甚至在运行的时候动态的执行,命令可以支持撤销,做法是实现一个undo()方法,返回到excute方法之前的状态.

  命令模式的运用例如队列请求(在某一端添加命令,线程进行下面的动作:从队列中取出一个命令,调用excute方法执行命令,然后将此命令对象丢弃,再取出下一个命令,日志请求(在执行命令的时候,将历史记录存储在磁盘中一旦系统死机,就可以把命令对象重新加载,在依次执行.

  以下是示例,其中Light类是接收者,Command是命令接口,LightOnCommand是具体的命令对象,SimpleRemoteControl是具体的调用者.

  

/*
 * 接收者,命令对象将对调用它的方法执行操作.
 * */
public class Light {
    public void on() {
        System.out.println("The light is on.");
    }
}
public interface Command /*命令对象,通过excute方法来执行命令,其内部封装接收者*/{
    public void excute();
}
class LightOnCommand implements Command{
    Light light;    //接收者
    public LightOnCommand(Light light) {
        super();
        this.light = light;
    }
    @Override
    public void excute() /*执行命令的方法*/{
        light.on();
    }
    
}
//调用者其内部有一个或多个命令对象
public class SimpleRemoteControl {
    Command slot;
    
    public SimpleRemoteControl(){}
    
    public void setCommand(Command com) {
        slot=com;
    }
    
    public void buttonWasPressed() {
        slot.excute();
    }
}
//客户先创建调用者和命令对象,然后将接收者传给命令对象,再将命令对象传给调用者,在需要的时候调用调用者的方法.
public class RemoteControlTest {
    public static void main(String[] args) {
        SimpleRemoteControl remote=new SimpleRemoteControl();
        Light light=new Light();
        Command command=new LightOnCommand(light);
        remote.setCommand(command);
        remote.buttonWasPressed();
    }
}

  命令者模式的类图如下:

  也可以定义宏命令(即通过此命令完成一系列的命令).

/*
 * 内部封装了宏命令的命令对象.
 * */
public class MacroCommand implements Command{
    Command[] commands;
    public MacroCommand(Command[] commands) {
        super();
        this.commands = commands;
    }
    @Override
    public void excute() {
        for(int i=0;i<commands.length;i++) {
            commands[i].excute();
        }
    }

}
原文地址:https://www.cnblogs.com/hlhdidi/p/5597441.html