个人技术分享

命令模式简介

  • 命令模式(command pattern)也叫动作模式或者事务模式。它是将请求(命令)封装成对象,使得可以用不同的请求对客户端进行参数化,具体的请求可以在运行时更改、排队和记录,它将发出者和 接收者解耦,顺序是: 发出者 --> 命令 --> 接收者。
  • 实际使用:Spring JdbcTemplate 中的execute/query方法、Runnable Thread start()。

结构

  • 1.抽象命令(Abstract Command): 抽象命令是一个接口,定义了执行操作的统一方法。具体的命令类会实现这个接口,并提供执行相应操作的具体逻辑
  • 2.具体命令(Concrete Command):具体命令类实现了抽象命令类,它拥有 接收者对象 ,并通过调用接收者的功能来完成命令要执行的操作。
  • 3.接收者(Receiver): 执行实际命令的类,命令对象会调用接收者的方法来执行请求。
  • 4.调用者(Invoker):持有命令对象,通常是多个,并通过访问命令对象来执行相关请求,他不直接访问接收者。

UML图

在这里插入图片描述

具体实现

例子:餐厅中,服务员(Waiter)点菜,然后厨师(Chef)做菜。

UML图

在这里插入图片描述

代码实现

  • 抽象命令类
package com.xxliao.pattern.behavioral.command.demo;

/**
 * @author xxliao
 * @description: 抽象命令类接口,定义了执行操作的统一方法
 * @date 2024/5/25 19:26
 */
public interface Command {

    // 点菜
    void order();
    // 取消点菜
    void cancelOrder();
}
  • 具体命令类
package com.xxliao.pattern.behavioral.command.demo;

/**
 * @author xxliao
 * @description: 具体命令类,实现了抽象命令接口,通过组合,拥有接收者对象,并通过调用接收者对象的方法来完成命令要执行的操作。
 * @date 2024/5/25 19:30
 */

public class OrderCommand implements Command {

    // 聚合方式 持有 接收者对象
    private Chef chef;

    public OrderCommand(Chef chef) {
        this.chef = chef;
    }

    @Override
    public void order() {
        chef.cook();
    }

    @Override
    public void cancelOrder() {
        chef.cancelCooking();
    }
}
  • 接受者类
package com.xxliao.pattern.behavioral.command.demo;

/**
 * @author xxliao
 * @description: 接收者类,执行实际命令的类,命令对象会调用接收者的方法来执行请求
 * @date 2024/5/25 19:28
 */
public class Chef {

    public void cook() {
        System.out.println("chef process order。。。");
    }

    public void cancelCooking() {
        System.out.println("chef cancel cooking...");
    }
}
  • 调用者类
package com.xxliao.pattern.behavioral.command.demo;

/**
 * @author xxliao
 * @description: 调用者类 - 持有命令对象,通常是多个,并通过访问命令对象来执行相关请求,他不直接访问接收者。
 * @date 2024/5/25 22:40
 */
public class Waiter {

    // 持有命令对象
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    /**
     * @description  点餐
     * @author  xxliao
     * @date  2024/5/25 22:45
     */
    public void takeOrder() {
        // 服务员收到顾客(客户端)点餐请求
        System.out.println("服务员收到顾客(客户端)点餐请求");
        // 执行点餐操作,使用命令对象,实际是具体命令对象去执行,然后调用的是接收者对象Chef相关的执行方法。
        command.order();
    }

    /**
     * @description  取消点餐
     * @author  xxliao
     * @date  2024/5/25 22:46
     */
    public void cancelOrder() {
        // 服务员收到顾客(客户端)取消点餐请求
        System.out.println("服务员收到顾客(客户端)取消点餐请求");
        // 执行取消点餐操作,使用命令对象,实际是具体命令对象去执行,然后调用的是接收者对象Chef相关的执行方法。
        command.cancelOrder();
    }
}
  • 测试客户端
package com.xxliao.pattern.behavioral.command.demo;

/**
 * @author xxliao
 * @description: 命令模式 测试客户端
 * @date 2024/5/25 22:47
 */
public class Client {
    public static void main(String[] args) {
        // 创建接收者对象 -- 厨师对象
        Chef chef = new Chef();
        // 创建具体命令对象, 然后将接收者对象 当作参数 传入
        Command orderCommand = new OrderCommand(chef);
        // 创建调用者对象 -- 服务员
        Waiter waiter = new Waiter();
        // 将具体命令对象 传入 调用者对象
        waiter.setCommand(orderCommand);

        // 执行相关操作
        waiter.takeOrder();

        waiter.cancelOrder();

    }
}
  • 测试结果
    在这里插入图片描述