• 浅谈Java设计模式——命令模式(Command)


    一、概述

            将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。有些时候我们想某个对象发送一个请求,但是我们并不知道该请求的具体接收者是谁,具体的处理过程是如何的,们只知道在程序运行中指定具体的请求接收者即可,对于这样将请求封装成对象的我们称之为命令模式。所以命令模式将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。同时命令模式支持可撤销的操作。

            命令模式可以将请求的发送者和接收者之间实现完全的解耦,发送者和接收者之间没有直接的联系,发送者只需要知道如何发送请求命令即可,其余的可以一概不管,甚至命令是否成功都无需关心。同时我们可以非常方便的增加新的命令,但是可能就是因为方便和对请求的封装就会导致系统中会存在过多的具体命令类。

    二、使用场景

    1.抽象出待执行的动作以参数化某对象。 

    2.在不同的时刻指定、排列和执行请求。 

    3.支持取消操作。 

    4.支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。

    5.用构建在原语操作上的高层操作构造一个系统。

    三、参与者

    1.Command 声明执行操作的接口。 

    2.ConcreteCommand 将一个接收者对象绑定于一个动作。 调用接收者相应的操作,以实现Execute。 

    3.Client 创建一个具体命令对象并设定它的接收者。 

    4.Invoker 要求该命令执行这个请求。

    5.Receiver 知道如何实施与执行一个请求相关的操作。任何类都可能作为一个接收者。

    四、类图

    五、代码示例

    1.Command

    /**
     * Command
     * @author zhipeng_Tong
     */
    public abstract class Command {
        protected Receiver receiver;  // 命令真正的执行者
    
        public Command(Receiver receiver) {
            this.receiver = receiver;
        }
    
        public abstract void execute(); // 延迟到子类实现
    }

    2.ConcreteCommand

    /**
     * ConcreteCommand
     * @author zhipeng_Tong
     */
    public class ConcreteCommand extends Command {
    
        public ConcreteCommand(Receiver receiver) {
            super(receiver);
        }
    
        @Override
        public void execute() {
            receiver.execute();
        }
    }

    3.Invoker

    /**
     * Invoker
     * @author zhipeng_Tong
     */
    public class Invoker {
        private Command command;
    
        public void setCommand(Command command) {
            this.command = command;
        }
    
        public void executeCommand() {
            command.execute();
        }
    }

    4.Receiver

    /**
     * Reseiver
     * @author zhipeng_Tong
     */
    public class Receiver {
        public void execute() {
            System.out.println("执行成功!");
        }
    }

    5.测试代码

    public class Client {
        public static void main(String[] args) {
            Invoker invoker = new Invoker();
            invoker.setCommand(new ConcreteCommand(new Receiver()));
    
            invoker.executeCommand();
        }
    }

    运行结果

    执行成功!
  • 相关阅读:
    golang模拟动态高优先权优先调度算法
    【2019腾讯暑期实习生正式批笔试1,2】
    golang优先队列
    git常见操作
    小L的试卷
    Unable to connect to the Redgate Client Service. Sql Prompt 报错不能用解决
    未能加载文件或程序集“Microsoft.VisualStudio.Enterprise.AspNetHelper, Version=15.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统找不到指定的文件。
    LumiSoft 邮件操作删除(无法删除解决方法)
    .net MVC 项目中 上传或者处理进度获取方案
    C# mvc Request 请求过长报404错误的解决思路分析
  • 原文地址:https://www.cnblogs.com/IdealSpring/p/11871165.html
Copyright © 2020-2023  润新知