• 初识设计模式 - 命令模式


    简介

    命令设计模式(Command Design Pattern)可以将请求发送者和接收者完全解耦。发送者和接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。

    其定义是,将请求(命令)封装成一个对象,从而可用不同的请求对客户进行参数化(将不同请求依赖注入到其他对象),并且能够支持请求(命令)的排队执行、记录日志、撤销等(附加控制)功能。

    典型实现

    首先,定义一个抽象命令 Command 接口,通常仅声明一个执行命令的方法,其代码示例如下:

    public interface Command {
    // 业务处理方法
    void execute();
    }

    具体命令会实现各种类型的请求,其自身并不完成工作,而是将调用委派给一个业务逻辑对象,其代码示例如下:

    public class ConcreteCommand implements Command {
    // 维持一个对请求者对象的引用
    private final Receiver receiver;
    public ConcreteCommand(Receiver receiver) {
    this.receiver = receiver;
    }
    // 调用请求接收者的业务处理方法
    public void execute() {
    this.receiver.action();
    }
    }

    接收者是真正命令执行的对象,是客户端直接操作的对象,其代码示例如下:

    public class Receiver {
    public void action() {
    // 具体操作
    }
    }

    最后,需要定义的是调用者 Invoker 类,其作用是负责对请求进行初始化,其代码示例如下:

    public class Invoker {
    private final List commandList;
    public Invoker() {
    this.commandList = new ArrayList<>();
    }
    public Invoker(Command command) {
    this();
    this.commandList.add(command);
    }
    // 添加命令
    public void pushCommand(Command command) {
    this.commandList.add(command);
    }
    // 执行命令
    public void executeAll() {
    for (Command command : commandList) {
    command.execute();
    }
    commandList.clear();
    }
    }

    对于客户端而言,需要知道自己需要操作的接收者对象是什么、可以执行的命令有哪些、通过调用者如何去执行这些命令。

    如下是客户端使用命令模式的代码示例:

    public class CommandDemo {
    public static void main(String[] args) {
    // 操作的接收者对象是什么
    Receiver receiver = new Receiver();
    // 可以执行的命令有哪些
    Command command = new ConcreteCommand(receiver);
    // 通过调用者如何去执行这些命令
    Invoker invoker = new Invoker(command);
    invoker.executeAll();
    }
    }

    总结

    优点

    命令模式的主要优点如下:

    • 降低请求者和接收者的耦合度
    • 新的命令可以很方便地加入到系统中
    • 可以比较容易地设计一个命令队列或者宏命令(组合命令)
    • 为请求的撤销和恢复操作提供了一种设计和实现方案

    缺点

    命令模式的主要缺点如下:

    • 可能会导致系统中有过多的具体命令类

    适用场景

    命令模式的适用场景如下:

    • 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互
    • 系统需要在不同的时间指定请求、将请求排队和执行请求
    • 系统需要支持命令的撤销操作和恢复操作
    • 系统需要将一组操作组合在一起形成宏命令

    源码

    在 JDK 中,Runnable 接口就类似于命令模式的命令接口。

    只要实现了 Runnable 接口的类都被认为是一个线程类,相当于命令模式中具体命令类的角色。而实现了 Runnable 接口的 Thread 类既可以作为具体命令类,也可以作为调用者。

    如下是客户端使用 Runnable 和 Thread 的代码示例:

    public class ThreadDemo {
    public static void main(String[] args) {
    Runnable command = new Runnable() {
    @Override
    public void run() {
    System.out.println("command 线程执行");
    }
    };
    Thread thread = new Thread(command);
    // command 线程执行
    thread.start();
    }
    }
  • 相关阅读:
    CDQ分治学习笔记
    【OJ每日一练】1017 - 计算蔬菜总价
    《软件工程》期末题型
    测试用例基础
    mulesoft MCIA 易错题汇总解析
    leetcode:87场双周赛总结 = 思维贪心专场
    5、WebApi 在腾讯云服务器中部署初试
    easyui datagrid单元格点击进入编辑时,行会自动向上错位
    Kubernetes教程(五)---Service 的几种访问方式
    移动通信网络规划:室内分布系统的分类
  • 原文地址:https://www.cnblogs.com/fatedeity/p/16812261.html