命令模式(Command Pattern)

命令模式(Command Pattern)

定义

命令模式是对命令的封装,每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。

命令模式解耦了请求方和接收方,请求方只需请求执行命令,不用关心命令是怎样被接收,怎样被操作以及是否被执行等。

命令模式是将请求封装成一个对象,这样可以使用不同的请求参数化其他对象(依赖注入),并且能够支持请求的排队执行、记录日志、撤销等功能。

本质:解耦命令请求与处理。

属于行为型模式。

适用场景

命令模式的适用场景

1.实现语义中的"命令"的操作(如命令菜单,shell命令)

2.请求调用者和请求的接收者需要解耦,使得调用者和接收者不直接交互。

3.需要抽象出等待执行的行为,比如撤销(undo)和恢复(redo)等操作。

4.需要支持命令宏(及命令组合操作)

标准示例

ICommand 命令接口;
ConcreteCommand 具体命令实现类;
Invoker 调用类,构造方法入参为 ICommand,它的execute方法,实际调用的是传入对象的 cmd.execute()
Receiver 接收类,只有一个方法action

调用类和接收类通过ConcreteCommand 实现了解耦。

具体代码如下:

java 复制代码
//命令接口
public interface ICommand {
    void execute();
}
java 复制代码
//具体命令接口
public class ConcreteCommand implements ICommand{

    //每个命令对应一个不同的receiver
    private Receiver receiver = new Receiver();

    @Override
    public void execute() {
        receiver.action();
    }
}
java 复制代码
/**
 * 调用者
 */
public class Invoker {
    private ICommand cmd;

    public Invoker(ICommand cmd){
        this.cmd = cmd;
    }

    public void execute(){
        this.cmd.execute();
    }
}
java 复制代码
/**
 * 接收者
 */
public class Receiver {
    public void action(){
        System.out.println("执行动作");
    }
}
java 复制代码
public class ClientTest {
    public static void main(String[] args) {
        ICommand cmd = new ConcreteCommand();
        Invoker invoker = new Invoker(cmd);
        invoker.execute();
    }
}

生活中也有很多命令模式的例子。

比如遥控器:它把我们的请求和设备的执行做了解耦,将请求和执行做了分离。

比如餐厅点菜单:客人按照菜单点菜,后厨根据菜单配菜做菜,菜单就是个解耦的介质,将请求和执行做了解耦,可以达到灵活扩展的目的。

下面举个智能空调的例子:

现在的空调,都支持APP操控了。这必然就涉及到 设备与服务器 的交互。

我们现在定义2个接口:
设备注册设备心跳上送

我们使用命令模式来实现这四个接口。

相应的类为:
ICommandAbstractCommand
RegistCommandHeartbeatCommand
Invoker
Receiver


ICommand

java 复制代码
public interface ICommand {
    void execute();
}

AbstractCommand

java 复制代码
public abstract class AbstractCommand implements ICommand {
    protected Receiver receiver = new Receiver();
}

RegistCommand

java 复制代码
public class RegistCommand extends AbstractCommand {
    public void execute() {
        receiver.registAction();
    }
}
java 复制代码
public class HeartbeatCommand extends AbstractCommand {
    public void execute() {
        receiver.heartbeatAction();
    }
}

Receiver

java 复制代码
public class Receiver {
    public void registAction(){
        System.out.println("regist ...");
    }
    public void heartbeatAction(){
        System.out.println("heartbeat ...");
    }
}

Invoker

java 复制代码
public class Invoker {
    public void execute(ICommand command){
        command.execute();
    }
}

ClientTest

java 复制代码
public class ClientTest {
    public static void main(String[] args) {
        Invoker invoker = new Invoker();
        invoker.execute(new RegistCommand());

        Invoker invoker1 = new Invoker();
        invoker1.execute(new HeartbeatCommand());
    }
}

执行结果:

shell 复制代码
regist ...
heartbeat ...

以上就是命令模式全部内容,感谢阅读。

相关推荐
hqxstudying1 小时前
Java异常处理
java·开发语言·安全·异常
我命由我123454 小时前
Kotlin 数据容器 - List(List 概述、创建 List、List 核心特性、List 元素访问、List 遍历)
java·开发语言·jvm·windows·java-ee·kotlin·list
武子康6 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
YuTaoShao9 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先
源码_V_saaskw9 小时前
JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
java·微信小程序·小程序·uni-app·音视频·交友
超浪的晨9 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发
双力臂40410 小时前
Spring Boot 单元测试进阶:JUnit5 + Mock测试与切片测试实战及覆盖率报告生成
java·spring boot·后端·单元测试
Edingbrugh.南空10 小时前
Aerospike与Redis深度对比:从架构到性能的全方位解析
java·开发语言·spring
QQ_43766431411 小时前
C++11 右值引用 Lambda 表达式
java·开发语言·c++
永卿00111 小时前
设计模式-迭代器模式
java·设计模式·迭代器模式