美文网首页
命令模式

命令模式

作者: 满天星爱我 | 来源:发表于2018-12-09 21:59 被阅读5次

    定义

    将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作

    要点

    • 命令模式将发出请求的对象和执行请求的对象解耦
    • 在被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接收者的一个或一组动作
    • 调用者可以接收命令当作参数,甚至在运行的时候动态进行
    • 命令可以被撤销,做法是实现一个undo()方法来回到execute()被执行前的状态
    • 宏命令是命令的一种简单延申,允许调用多个命令。宏方法也可以支持撤销。

    案例

    • 定义一个命令接口Command,里面有执行命令和撤销命令两个方法
    public interface Command {
        //执行命令
        void execute();
        //撤销命令
        void undo();
    }
    
    • 定义一个接收者对象,用来完成自己的动作
    public class Receiver {
    
    public void sendData(){
        System.out.println("发送数据");
    }
    public void cancelSend(){
        System.out.println("取消发送"); 
    }
    }
    
    • 实现一个命令并将接收者对象用组合的方式跟命令绑定到一起,请求者只需执行此命令而并不用知道接收者具体要做什么,这样的话,请求者和接收者之间就解除了耦合
    public class ReceiverCommand implements Command {
    private Receiver receiver;
    
    public ReceiverCommand(Receiver receiver) {
        this.receiver = receiver;
    }
    
    @Override
    public void execute() {
        receiver.sendData();
    }
    @Override
    public void undo() {
        receiver.cancelSend();
    }
    }
    
    • 将命令与请求者进行绑定
    public class RequestManager {
    Command command;
    
    public void setCommand(Command onCommand) {
        this.command = onCommand;
    }
    
    public void executeCommand(){
        this.command.execute();
    }
    public void undoCommand(){
        this.command.undo();
    }
    }
    

    通过一个setCommand()方法可以将任何实现了Command接口的命令和请求者绑定起来,这样请求者就可以执行不同的命令,从而让不同的命令去做出不同的动作,而具体做什么是由被封装到命令中的接收者对象去完成的,因此请求者是不知道接收者具体要做什么的。

    • 最后测试一下
    public class CommandTest {
    
    public static void main(String[] args){
        Receiver receiver = new Receiver();
        ReceiverCommand receiverCommand = new ReceiverCommand(receiver);
        RequestManager requestManager = new RequestManager();
        requestManager.setCommand(receiverCommand);
        requestManager.executeCommand();
        requestManager.undoCommand();
    }
    }
    
    • 打印结果
    发送数据
    取消发送
    

    宏命令

    上面只是定义了一个命令,实际情况中,我们可能会执行一组命令,也就是宏命令。我们来修改RequestManager类,让它可以接收一组命令,代码如下:

    public class RequestManager {
    Command[] commands;
    
    public void setCommand(Command[] commands) {
        this.commands = commands;
    }
    
    public void executeCommand(){
        for (Command command : commands) {
            command.execute();
        }
    }
    public void undoCommand(){
        for (Command command : commands) {
            command.undo();
        }
    }
    }
    

    Command声明成数组用来接收一组命令,然后在执行请求的时候去遍历所有的命令执行它们的execute()undo()方法,这样便完成了一组命令的执行。

    相关文章

      网友评论

          本文标题:命令模式

          本文链接:https://www.haomeiwen.com/subject/qfflhqtx.html