Java设计模式之命令模式详解

作者:在下木子李 时间:2023-11-15 21:18:43 

命令模式

定义:将请求封装成对象,这可以让你使用不同的请求、队列、或者日志来参数化其他对象。

何时使用命令模式?当需要将发出请求的对象和执行请求的对象解耦的时候,使用命令模式。

在被解耦的两者之间是通过命令对象进行沟通的。命令对象封装了接收者和一个或一组动作。

调用者通过调用命令对象的execute()方法发出请求,这会使接收者的动作被调用。

调用者可以接收命令当作参数,甚至在运行时动态地进行。

优点:

1、降低了系统耦合度。

2、新的命令可以很容易添加到系统中去。

缺点:使用命令模式可能会导致某些系统有过多的具体命令类。

实现案例

需求:实现一个遥控器类,遥控器有多组开/关按钮,每组按钮控制一个电器对象的开和关。使用命令模式实现整个功能。

1、创建命令接口


package com.example.designpatternsdemo.commandPattern;

/**
* 命令接口
*/
public interface Command {
   public void execute();
}

2、创建电灯、电视类(命令接收者)


package com.example.designpatternsdemo.commandPattern;

/**
* 电灯
*/
public class Light {
//on/off动作
   public void on(){
       System.out.println("开启电灯");
   }
   public void off(){
       System.out.println("关闭电灯");
   }
}

package com.example.designpatternsdemo.commandPattern;

/**
* 电视
*/
public class TV {
   public void on(){
       System.out.println("开启电视");
   }

public void off(){
       System.out.println("关闭电视");
   }
}

3、创建具体命令类


package com.example.designpatternsdemo.commandPattern;

/**
* 开启电灯命令类
*/
public class LightOnCommand implements Command{
   //电灯对象
   private Light mLight;

public LightOnCommand(Light light){
       this.mLight = light;
   }
   @Override
   public void execute() {
       mLight.on();
   }
}

package com.example.designpatternsdemo.commandPattern;

/**
* 关闭电灯命令类
*/
public class LightOffCommand implements Command{
   //电灯对象
   private Light mLight;

public LightOffCommand(Light light){
       this.mLight = light;
   }
   @Override
   public void execute() {
       mLight.off();
   }
}

这里省略电视的开关命令类

4、创建遥控器类


package com.example.designpatternsdemo.commandPattern;

/**
* 命令调用者
* 遥控器
*/
public class RemoteControl {
   //保存开关命令对象的数组
   Command[] onCommands;
   Command[] offCommands;

public RemoteControl(){
       //初始化数组
       onCommands = new Command[2];
       offCommands = new Command[2];
   }

//存储命令
   public void setCommand(int index,Command onCommand,Command offCommand){
       onCommands[index] = onCommand;
       offCommands[index] = offCommand;
   }
   //开按钮
   public void onButtonPress(int btnIndex){
       onCommands[btnIndex].execute();
   }

//关按钮
   public void offButtonPress(int btnIndex){
       offCommands[btnIndex].execute();
   }
}

5、创建客户类(测试类)


package com.example.designpatternsdemo.commandPattern;

public class Client {

public static void main(String[] args) {
       //创建电灯对象(命令接收者)
       Light myLight = new Light();
       //创建电灯开关命令对象
       LightOnCommand lightOnCommand = new LightOnCommand(myLight);
       LightOffCommand lightOffCommand = new LightOffCommand(myLight);
       //创建遥控器对象(命令调用者)
       RemoteControl remoteControl = new RemoteControl();
       //设置命令
       remoteControl.setCommand(0,lightOnCommand,lightOffCommand);
       //发起命令执行请求
       remoteControl.onButtonPress(0);
       remoteControl.offButtonPress(0);

TV myTv = new TV();
       TvOnCommand tvOnCommand = new TvOnCommand(myTv);
       TvOffCommand tvOffCommand = new TvOffCommand(myTv);
       remoteControl.setCommand(1,tvOnCommand,tvOffCommand);
       remoteControl.onButtonPress(1);
       remoteControl.offButtonPress(1);
   }
}

将开/关电灯、电视的请求封装成命令类对象,在类中的execute()方法调用具体电灯/电视的开关动作,调用时,遥控器类(命令调用者)只需调用具体某个命令对象的execute()方法,那他就会通知具体的电器来执行动作,这样,就实现了命令调用者和执行者之间的解耦。调用者不需要知道是谁执行动作,只需要调用命令对象的execute()方法去通知执行就可以。

来源:https://blog.csdn.net/weixin_44902943/article/details/116118136

标签:Java,命令模式,设计模式
0
投稿

猜你喜欢

  • Java利用反射自动封装成实体对象的方法

    2022-01-06 05:54:29
  • Spring案例打印机的实现过程详解

    2023-12-02 12:28:47
  • WPF中ImageBrush常用方式介绍

    2022-02-26 09:45:30
  • IntelliJ IDEA 下载安装超详细教程(推荐)

    2023-11-19 23:50:16
  • Android RecyclerView的卡顿问题的解决方法

    2023-07-01 20:01:14
  • 关于Android 4.4相机预览、录像花屏的问题的解决方法

    2023-01-21 11:50:26
  • C# double和decimal数据类型以截断的方式保留指定的小数位数

    2021-12-09 02:19:04
  • java中dart类详细讲解

    2022-01-23 13:01:13
  • android图像绘制(六)获取本地图片或拍照图片等图片资源

    2021-07-26 14:20:51
  • 使用mongoTemplate实现多条件加分组查询方式

    2022-05-21 01:41:51
  • 基于Viewpager2实现登录注册引导页面

    2023-06-16 11:04:10
  • SpringBoot整合MongoDB的步骤详解

    2023-10-11 17:20:32
  • Java判断所给年份是平年还是闰年

    2023-10-21 17:48:59
  • android效果TapBarMenu绘制底部导航栏的使用方式示例

    2023-07-29 20:53:36
  • 一次排查@CacheEvict注解失效的经历及解决

    2023-11-13 12:07:23
  • Android Splash界面白屏、黑屏问题的解决方法

    2022-03-24 07:14:44
  • Java设计模式中的七大原则详细讲解

    2021-07-23 15:38:14
  • springBoot详解集成Swagger流程

    2023-02-26 22:23:33
  • 解决使用mybatis-plus时,生成的SQL大写变小写加下划线问题

    2022-10-20 09:24:47
  • Android绘制钟表的方法

    2023-09-01 13:18:03
  • asp之家 软件编程 m.aspxhome.com