命令模式

介绍

**定义:**命令模式的核心是将指令信息封装为对象后, 作为参数发送给接收方执行, 以此来达到请求方与执行方解耦的目的. 由于JAVA不支持将函数当做参数传递, 所以可以通过将函数封装为命令的方式来达到相同的目的.

UML

示例

java 复制代码
package com.sumlv.demo;

import com.sumlv.demo.command.Command;
import com.sumlv.demo.command.PayOrderCommand;
import com.sumlv.demo.entity.CommandContest;
import com.sumlv.demo.entity.Order;
import com.sumlv.demo.enumeration.OrderState;

import java.math.BigDecimal;

public class Main {

    public static void main(String[] args) {
        Order order = new Order(
                1L,
                2L,
                3L,
                new BigDecimal("100.00"),
                OrderState.PENDING,
                null
        );

        CommandContest<Order> contest = new CommandContest<>();
        contest.setData(order);

        Command<Order> command = new PayOrderCommand();
        command.execute(contest);
    }

}
java 复制代码
package com.sumlv.demo.command;

import com.sumlv.demo.entity.CommandContest;

/**
 * 抽象命令接口
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-27
 */
public interface Command<T> {

    void execute(CommandContest<T> contest);

}
java 复制代码
package com.sumlv.demo.command;

import com.sumlv.demo.entity.CommandContest;
import com.sumlv.demo.entity.Order;
import com.sumlv.demo.entity.Result;
import com.sumlv.demo.service.OrderService;
import com.sumlv.demo.service.impl.OrderServiceImpl;

/**
 * 订单支付命令
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-27
 */
public class PayOrderCommand implements Command<Order> {

    private final OrderService service = new OrderServiceImpl();

    @Override
    public void execute(CommandContest<Order> contest) {
        Result<Order> result = service.payOrder(contest.getData());
        System.out.println("命令执行完成, 执行结果: " + result);
    }

}
java 复制代码
package com.sumlv.demo.entity;

/**
 * 命令上下文
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-27
 */
public class CommandContest<T> {

    private T data;

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

}
java 复制代码
package com.sumlv.demo.service;

import com.sumlv.demo.entity.Order;
import com.sumlv.demo.entity.Result;

/**
 * 订单服务
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-27
 */
public interface OrderService {

    /**
     * 支付订单
     *
     * @param order 订单信息
     * @return 支付结果
     */
    Result<Order> payOrder(Order order);

}
java 复制代码
package com.sumlv.demo.service.impl;

import com.sumlv.demo.entity.Order;
import com.sumlv.demo.entity.Result;
import com.sumlv.demo.enumeration.OrderState;
import com.sumlv.demo.service.OrderService;

/**
 * 订单服务实现
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-27
 */
public class OrderServiceImpl implements OrderService {

    @Override
    public Result<Order> payOrder(Order order) {
        try {
            System.out.println("开始执行订单支付, 订单信息: " + order);
            // 此处省略支付逻辑
            order.setState(OrderState.PROCESSING);

            System.out.println("订单支付完成, 订单信息: " + order);
            return Result.buildSuccessResult(order);
        } catch (Throwable t) {
            System.out.println("订单支付异常");
            t.printStackTrace();
            // 此处省略回滚逻辑

            return Result.buildFailResult(order, t.getMessage());
        }
    }

}
java 复制代码
package com.sumlv.demo.entity;

import java.io.Serializable;

/**
 * 请求结果集
 *
 * @Auther: yuzhuo.song
 * @Date: 2026-03-26
 */
public class Result<T> implements Serializable {

    private Boolean success;

    private String code;

    private String message;

    private T data;

    public static <T> Result<T> buildSuccessResult(T data, String message) {
        return new Result<>(
                Boolean.TRUE,
                ResultCodeConstant.SUCCESS_CODE,
                message,
                data
        );
    }

    public static <T> Result<T> buildSuccessResult(T data) {
        return new Result<>(
                data,
                Boolean.TRUE,
                ResultCodeConstant.SUCCESS_CODE
        );
    }

    public static Result<?> buildSuccessResult() {
        return new Result<>(
                Boolean.TRUE,
                ResultCodeConstant.SUCCESS_CODE
        );
    }

    public static <T> Result<T> buildFailResult(String code, String message, T data) {
        return new Result<>(
                Boolean.FALSE,
                code,
                message,
                data
        );
    }

    public static Result<?> buildFailResult(String code, String message) {
        return new Result<>(
                Boolean.FALSE,
                code,
                message
        );
    }

    public static <T> Result<T> buildFailResult(T data, String message) {
        return new Result<>(
                Boolean.FALSE,
                ResultCodeConstant.FAIL_CODE,
                message,
                data
        );
    }

    public static Result<?> buildFailResult(String message) {
        return new Result<>(
                Boolean.FALSE,
                ResultCodeConstant.FAIL_CODE,
                message
        );
    }

    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "Result{" +
                "success=" + success +
                ", code='" + code + '\'' +
                ", message='" + message + '\'' +
                ", data=" + data +
                '}';
    }

    public Result(Boolean success, String code, String message, T data) {
        this.success = success;
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public Result(Boolean success, String code, String message) {
        this(success, code, message, null);
    }

    public Result(T data, Boolean success, String code) {
        this(success, code, null, data);
    }

    public Result(Boolean success, String code) {
        this(success, code, null);
    }

    /**
     * 返回状态码常量
     */
    public static class ResultCodeConstant {

        /**
         * 成功状态码
         */
        public static final String SUCCESS_CODE = "200";

        /**
         * 失败状态码
         */
        public static final String FAIL_CODE = "500";
        
    }

}

总结

使用场景

  1. 当遇到调用方和执行方必须解耦的场景时.

优点:

  1. 降低了系统耦合度(实现了调用方和执行方的解耦);

  2. 满足开闭原则(新增或删除命令不会对其他类产生影响);

  3. 可以实现宏命令(与组合模式相结合后, 可以将多个命令装配成一个组合命令).

缺点:

  1. 当需要执行的命令过多时, 会导致系统中存在数量庞大的具体命令类, 同时也会显得系统结构较为复杂.
相关推荐
其实防守也摸鱼1 天前
无线网络安全---WLAN相关安全工具--kali(理论附题目)
linux·安全·web安全·学习笔记·kali·命令模式·wlan
sg_knight3 天前
设计模式实战:命令模式(Command)
python·设计模式·命令模式
yaaakaaang3 天前
十四、命令模式
java·命令模式
无籽西瓜a4 天前
【西瓜带你学设计模式 | 第十八期 - 命令模式】命令模式 —— 请求封装与撤销实现、优缺点与适用场景
java·后端·设计模式·软件工程·命令模式
23.12 天前
【Linux】grep -F 及 双横线--的妙用
linux·命令模式
摸鱼仙人~14 天前
快照模式 vs 命令模式:一篇分清什么时候用谁
命令模式
2301_7644413314 天前
Dify工作流中实现查询优化(QO):将查询复杂度分类法与QOL框架融入工作流
人工智能·语言模型·自然语言处理·命令模式
fe7tQnVan15 天前
三大 Agent-UI 协议深度剖析:AG-UI、A2UI 与 MCP-UI 的设计哲学与工程实践
ui·状态模式·命令模式
程序员小寒16 天前
JavaScript设计模式(八):命令模式实现与应用
前端·javascript·设计模式·ecmascript·命令模式
砍光二叉树19 天前
【设计模式】行为型-命令模式
设计模式·命令模式