• 设计模式之命令模式


    命令模式

    设计模式之命令模式的理解



    前言

    命令模式的基本介绍

    1,
    在这里插入图片描述

    1,命令模式(CommandPattern):在软件设计中,我们经常需要
    向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计
    2,命名模式使得请求发送者与请求接收者消除彼此之间的耦合,让
    对象之间的调用关系更加灵活,实现解耦。
    3,在命名模式中,会将一个请求封装为一个对象,以便使用不同参
    数来表示不同的请求(即命名),同时命令模式也支持可撤销的操作
    4,通俗易懂的理解:将军发布命令,士兵去执行。其中有几个角色:
    将军(命令发布者)、士兵(命令的具体执行者)、命令(连接将军和士兵)。
    Invoker是调用者(将军),Receiver是被调用者(士兵), MvCommand是命令,实现了Command接口,持有接收对象


    以下是本篇文章正文内容,下面案例可供参考

    一、图形

    在这里插入图片描述

    二、实现步骤

    1.抽象类

    public interface Command {
    
        /**
         * 执行
         */
        void execute();
    
        /**
         * 撤销
         */
        void undo();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.灯的开关

    public class LightOffCommand implements Command{
    
        LightReceiver light;
    
        public LightOffCommand(LightReceiver light) {
            this.light = light;
        }
    
        // 聚合 LightReceiver
        @Override
        public void execute() {
            // 调用接收者的方法
            light.off();
        }
    
        @Override
        public void undo() {
            light.on();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    public class LightOnCommand implements Command{
    
        LightReceiver light;
    
        public LightOnCommand(LightReceiver light) {
            this.light = light;
        }
    
        // 聚合 LightReceiver
        @Override
        public void execute() {
            // 调用接收者的方法
            light.on();
        }
    
        @Override
        public void undo() {
            light.off();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3. 空命令的接收

    public class NoCommand implements Command{
        @Override
        public void execute() {
    
        }
    
        @Override
        public void undo() {
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.遥控器

    public class RemoteController {
        // 开按钮命令数组
        Command[] onCommands;
        Command[] offCommands;
        // 撤销
        Command undoCommand;
        public RemoteController() {
            onCommands  = new Command[5];
            offCommands = new Command[5];
            for (int i = 0; i < onCommands.length; i++) {
                onCommands[i] = new NoCommand();
                offCommands[i] = new NoCommand();
            }
        }
        public void setCommand(int no,Command onCommand,Command offCommand){// 设置命令
                onCommands[no] = onCommand;
                offCommands[no] = offCommand;
        }
        public void onButtonWasPushed(int no){
            // 找到你按下的开的按钮,并调用对应方法
            onCommands[no].execute();
            undoCommand = onCommands[no];
        }
        public void offButtonWasPushed(int no){
            // 找到你按下的开的按钮,并调用对应方法
            offCommands[no].execute();
            undoCommand = offCommands[no];
        }
        public void undoButtonWasPushed(){
            undoCommand.undo();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    5.调用

    public class Client {
    
        public static void main(String[] args) {
    
            // 电灯接收者
            LightReceiver lightReceiver = new LightReceiver();
    
            LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
    
            LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
    
            RemoteController remoteController = new RemoteController();
    
            remoteController.setCommand(0,lightOnCommand,lightOffCommand);
    
            System.out.println("=====按下灯(开)=====");
            remoteController.onButtonWasPushed(0);
            System.out.println("=====按下灯(关)=====");
            remoteController.offButtonWasPushed(0);
    
            remoteController.undoButtonWasPushed();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    6.输出

    在这里插入图片描述


    命令模式注意事项和细节

    1,将发起请求的对象与执行请求的对象解耦。发起请求的对象是调用者,调用者只要调用命令对象的execute()方法就可以让接收者工作,而不必知道具体的接收者对象是谁,是如何实现的,命令对象会负责让接收者执行请求的动作,也就是说:"请求发起者”和“请求执行者”之间的解耦是通过命令对象实现的,命令对象起到了纽带桥梁的作用。
    2,容易设计一个命令队列。只要把命令对象放到列队,就可以多线程的执行命令
    3,容易实现对请求的撤销和重做
    4,命令模式不足:可能导致某些系统有过多的具体命令类,增加了系统的复杂度,这点在在使用的时候要注意
    5,空命令也是一种设计模式,它为我们省去了判空的操作。在上面的实例中,如果没有用空命令,我们每按下一个按键都要判空,这给我们编码带来一定的麻烦。
    6,命令模式经典的应用场景:界面的一个按钮都是一条命令 模拟CMD(DOS命令)订单的撤销/恢复、触发-反馈机制
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    学习来源 B站韩顺平老师

  • 相关阅读:
    什么是人工智能(AI)数据平台?
    Blender:使用立方体制作动漫头像
    Java基础-继承性
    基于verilog的CRC校验(汇总)
    【Java面试】生产环境服务器变慢,如何诊断处理?
    网络防御--防火墙
    ajax图书管理项目
    基于大数据的学习资源推送系统
    代码随想录-Day25
    C++算法之旅、06 基础篇 | 第四章 动态规划 详解
  • 原文地址:https://blog.csdn.net/Susan003/article/details/126684681