• 23中设计模式之一— — — —命令模式的详细介绍


    概念

    命令模式(别名:动作,事务)
    命令模式是一种行为设计模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

    描述

    命令模式的本质封装请求
    在命令模式中,我们通常会定义一个抽象的Command接口,其中声明了一个execute()方法。具体的命令类(ConcreteCommand)将实现这个execute()方法,将一个发送者(Invoker)的请求转换为一个或多个接收者(Receiver)的操作。发送者并不知道接收者的具体实现,它只需要触发命令对象的execute()方法即可

    模式结构

    主要角色

    1、命令接口(Command Interface):定义了一个统一的执行操作的接口,通常包含一个execute()方法。
    2、具体命令(Concrete Command):实现了命令接口,负责具体的业务逻辑处理。它通常会持有对接收者(Receiver)的引用。
    3、接收者(Receiver):真正知道如何执行命令的实体。任何类都可能成为一个接收者。
    4、调用者/请求者(Invoker/Client):负责调用命令对象的execute()方法,它并不关心命令是如何被执行的,也不知道具体的接收者是谁。

    模式的UIM类图

    在这里插入图片描述

    模式优点

    1、在命令模式中,请求者(Invoker)不直接与接收者(Receiver)交互,即请求者(Invoker)不包含接收者(Receiver)的引用,因此彻底消除了彼此之间的耦合。
    2、命令模式满足“开-闭原则”。如果增加新的具体命令和该命令的接受者,不必修改调用者的代码,调用者就可以使用新的命令对象;反之,如果增加新的调用者,不必修改现有的具体命令和接受者,新增加的调用者就可以使用已有的具体命令。
    3、由于请求者的请求被封装到了具体命令中,那么就可以将具体命令保存到持久化的媒介中,在需要的时候,重新执行这个具体命令。因此,使用命令模式可以记录日志。
    4、使用命令模式可以对请求者的“请求”进行排队。每个请求都各自对应一个具体命令,因此可以按一定顺序执行这些具体命令。

    模式缺点

    • 类数量增加:引入了大量的命令类,可能会导致类的数量急剧增加,增加了系统的复杂度。
    • 设计复杂度:在包含大量命令和复杂撤销操作的系统中,设计和管理命令模式可能会比较复杂。

    应用场景

    • UI事件处理:在图形界面系统中,用户的各种操作(如点击按钮)可以被封装为命令对象,然后由控制器统一处理。
    • 日志与事务:通过命令模式记录用户的操作日志,便于后续审计或回滚事务。
    • 宏命令:将多个命令组合成一个宏命令,实现批量操作。
    • 支持撤销/重做功能:命令模式天然适合于实现软件中的撤销和重做功能。

    实例演示

    题目:模拟带控制开关的小电器。该电器上有四个开关,两个一组,其中一组负责打开、关闭小电器上的照明灯,另一组负责打开、关闭小电器上的摄像头

    类图

    在这里插入图片描述

    代码演示
    package task2;
    
    public interface Command {
    	public void execute();
    	
    
    }
    
    package task2;
    
    public class Light {
    	public void on() {
    		System.out.println("灯找了");
    	}
    
    	public void off() {
    		System.out.println("灯灭了");
    
    	}
    
    }
    
    package task2;
    
    public class OnLightCommand implements Command {
    	public Light light;
    
    	public OnLightCommand(Light light) {
    		// TODO Auto-generated constructor stub
    		this.light=light;
    	}
    
    	public void execute() {
    		light.on();
    	}
    
    }
    
    package task2;
    
    public class OffLightCommand implements Command {
    	public Light light;
    
    	public OffLightCommand(Light light) {
    		// TODO Auto-generated constructor stub
    		this.light=light;
    	}
    
    	public void execute() {
    		light.off();
    
    	}
    
    }
    
    package task2;
    
    public class Camera {
    	public void on(){
    		System.out.println("摄像头开了");
    		
    	}
    	public void off(){
    		System.out.println("摄像头灭了");
    	}
    
    }
    
    package task2;
    
    public class OnCameraCommand implements Command {
    	public Camera camera;
    	public OnCameraCommand(Camera camera){
    		this.camera=camera;
    	}
    	public void execute() {
    		camera.on();
    
    	}
    
    }
    
    package task2;
    
    public class OffCameraCommand implements Command {
    	public Camera camera;
    	public OffCameraCommand(Camera camera){
    		this.camera=camera;
    	}
    	public void execute(){
    		camera.off();
    		
    	}
    
    }
    
    package task2;
    
    public class Invoker {
    	public Command command;
    
    	public void setCommand(Command command) {
    		this.command = command;
    	}
    
    	public void executeCommand(Command command) {
    		command.execute();
    
    	}
    
    }
    
    

    测试类

    package task2;
    
    public class Test {
    	public static void main(String[] args) {
    		Light light = new Light();
    		Command command1 = new OnLightCommand(light);
    		Command command2 = new OffLightCommand(light);
    		Invoker invoker = new Invoker();
    		invoker.setCommand(command1);
    		invoker.executeCommand(command1);
    		invoker.setCommand(command2);
    		invoker.executeCommand(command2);
    		Camera camera = new Camera();
    		Command command3 = new OnCameraCommand(camera);
    		Command command4 = new OffCameraCommand(camera);
    		invoker.setCommand(command3);
    		invoker.executeCommand(command3);
    		invoker.setCommand(command4);
    		invoker.executeCommand(command4);
    
    	}
    
    }
    
    

    在这个例子中,Command 是一个接口,定义了 execute 方法。OnLightCommand OffLightCommand OnCameraCommand OffCameraCommand 是 Command 接口的具体实现.Invoker 是请求者,它持有一个 Command 对象,并提供了获取命令并执行命令。

    运行结果

    在这里插入图片描述
    博主用心写,读者点关注;互动传真情,知识不迷路

  • 相关阅读:
    【At Coder begin 345】[D - Tiling] 回溯
    【动态规划】求解编辑距离问题
    【云原生之kubernetes实战】安装kubeopertor教程
    Vue2.0开发之——Vue基础用法-vue-cli(30)
    深入理解New操作符
    在deepin上使用Fleet开发SpringBoot 3.0.0项目
    Vue真实技术面试题解析【兄弟组件、vue-router、增量部署】
    【电动车】电动汽车两阶段优化调度策略(Matlab代码实现)
    修改了windows dns配置,在wsl2中不生效
    使用WebApi+Vue3从0到1搭建《权限管理系统》:二、搭建JWT系统鉴权
  • 原文地址:https://blog.csdn.net/2201_75851346/article/details/139503574