【设计模式-行为型】命令模式

一、什么是命令模式

什么是命令模式?就是字面理解,下命令,但是还不能这么快下定义,可以举一个例子来说明一下。好多电影里面经常会有一个神秘的杀手组织,他们只管要钱和目标。不管是谁的委托,经常有个大富豪,说"为了确保万无一失,无论多少钱,我要求派出江湖第一杀手",他们可是把命令模式玩的飞起。就好像《这个杀手不太冷》中主角杀手莱昂接受任务和执行任务的过程。

在电影中,莱昂(里昂)是一个职业杀手,他通过中间人接受任务,并执行任务。这个过程可以类比为命令模式,其中莱昂是"接收者",中间人是"调用者",而任务本身是"命令"。通过《这个杀手不太冷》中的场景,我们可以清晰地看到命令模式的核心优势。命令模式通过将请求封装为对象,使得请求的发起者和执行者之间解耦,提高了系统的灵活性和可扩展性。这种模式特别适用于需要动态执行命令(封装的请求)的场景。命令模式(Command Pattern)是一种行为型设计模式,它将请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化。

二、为什么用命令模式

  1. 解耦客户端和接收者:客户端(客户)不需要直接调用接收者(杀手)的业务方法,而是通过命令对象间接调用。杀手组织只接受命令,而不管命令的具体内容或发起者是谁。

  2. 支持可撤销操作:命令模式可以轻松实现命令的撤销和重做功能。具体命令类可以保存操作前的状态,以便在需要时恢复。

  3. 支持命令排队和日志记录:命令对象可以被存储在队列中,支持命令的排队执行。同时,命令对象可以被记录在日志中,便于后续的审计和恢复。

  4. 扩展性:命令模式支持动态添加新的命令,而不需要修改现有的代码。新的命令只需要实现命令接口即可。

三、命令模式示例

代码示例以及命令模式的角色解析

  1. Command(命令接口,定义任务统一行为):定义了执行操作的接口,所有具体命令类都实现这个接口。

    java 复制代码
    public interface Command {
        void execute();
    }
  2. ConcreteCommand(具体命令类,具体的任务):实现了命令接口,具体执行操作。它通常持有一个接收者对象,并调用接收者的业务方法来完成操作。

    java 复制代码
    public class KillCommand implements Command {
        private Hitman hitman;
        private String target;
    
        public KillCommand(Hitman hitman, String target) {
            this.hitman = hitman;
            this.target = target;
        }
    
        @Override
        public void execute() {
            hitman.kill(target);
        }
    }
  3. Receiver(接收者,杀手):实际执行操作的对象。具体命令类会调用接收者的业务方法来完成操作。

    java 复制代码
    public class Hitman {
        public void kill(String target) {
            System.out.println("杀手莱恩准备执行刺杀任务,任务目标: " + target);
        }
    }
  4. Invoker(调用者,杀手组织中间人):负责调用命令对象的执行方法。它通常持有一个命令对象,并在适当的时候调用命令对象的执行方法。

    java 复制代码
    public class Middleman {
        private Command command;
    
        public void setCommand(Command command) {
            this.command = command;
        }
    
        public void executeCommand() {
            command.execute();
        }
    }
  5. Client(客户端):创建具体命令对象,并将其与接收者关联。客户端将命令对象传递给调用者,调用者在适当的时候执行命令。

    java 复制代码
    public class Main {
        public static void main(String[] args) {
            // 创建接收者(杀手莱昂)
            Hitman hitman = new Hitman();
    
            // 创建具体命令对象(任务)
            Command killCommand = new KillCommand(hitman, "小女孩");
    
            // 创建调用者(中间人)
            Middleman middleman = new Middleman();
    
            // 设置命令并执行
            middleman.setCommand(killCommand);
            middleman.executeCommand();
        }
    }
    
    //输出
    杀手莱恩准备执行刺杀任务,任务目标: 小女孩
相关推荐
嘟嘟07172 小时前
TypeScript 工具类型通关:Pick、Omit、Partial、Record 区别与 Omit 等价实现一次讲清
设计模式·面试·typescript
SL_staff3 小时前
中小离散制造如何用工艺路线模板解决‘人走流程丢’——JVS-APS 实践解析
java·设计模式·全栈
Asize3 小时前
3 种设计模式 + DI:Nest.js 后端第一课
后端·设计模式·nestjs
St_rive12 小时前
Page Object设计模式
java·开发语言·设计模式
烬羽1 天前
NestJS 依赖注入:Controller 里那个没有 new 的 service,到底从哪来的?
设计模式·typescript·nestjs
用户938515635072 天前
工厂模式与 Nest.js 核心思想 —— 从蜜雪冰城到企业级架构
后端·设计模式·nestjs
烬羽2 天前
从 nest new 到 Hello World:一个最小 NestJS 项目,讲透工厂 + 装饰器 + 模块化
设计模式·node.js·nestjs
艺艺生辉3 天前
从if-else到策略模式
后端·设计模式
小林ixn3 天前
单例模式:从弹窗管理到全局状态,一个模式搞定
前端·javascript·设计模式
AI人工智能+电脑小能手3 天前
大白话说Java设计模式-17-装饰器模式(源码剖析篇)
java·spring·设计模式·装饰器模式·源码分析·io流