Java设计模式 _行为型模式_命令模式

一、命令模式

1、命令模式
命令模式(Command Pattern)是一种行为型模式,一种数据驱动的设计模式。命令模式中请求以命令的形式包裹在对象中,即将命令封装为类,从而可以使用不同的请求,队列等操作具体的对象等。完整设计时需要支持执行和撤回两种操作,也可以继续扩展。

2、实现思路
命令模式包含三种角色
(1)、命令(包含:抽象和实现类)
(2)、接收者(用于执行命令,包含抽象和实现类)
(3)、发送者(发送命令,具体实现类)
具体步骤:
(1)、定义接收者规范接口
(2)、编写接收者的实现类
(3)、定义命令规范接口
(4)、编写命令的实现类(包含接收者对象属性,实例属性的方法(构造或自定义),实现命令的方法)
(5)、编写发送者类(内置封装业务的命令,用于统一控制命令的发送,类似遥控器)

二、代码示例

1、示例场景
电视遥控器不同的按钮发送不同的指令,电视机是接收者,使用遥控器控制电视机的各种使用场景。

// 1、定义接收者的规范
public interface Receiver {
    void turnOn();      // 开机
    void turnOff();     // 关闭
    void switchChannel(int num);    // 切换数据
}
// 2、定义接收者的实现类(电视机)
public class Tv implements Receiver {
    @Override
    public void turnOn() {
        System.out.println("打开电视机");
    }

    @Override
    public void turnOff() {
        System.out.println("关闭电视机");
    }

    @Override
    public void switchChannel(int num) {
        System.out.println("切换频道为" + num);
    }
}
// 3、定义命令的规范(仅执行,撤回本场景不考虑)
public interface Order {
    void excute(int num);   // 参数根据业务确认,可以使用map封装兼容所有的情况。本例比较简单以int整数测试
}
// 4.1、定义具体命令(打开电视)
public class Order_TurnOn implements Order {
    private Receiver receiver;

    public Order_TurnOn(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void excute(int num) {
        this.receiver.turnOn();
    }
}
// 4.2、定义具体命令(关闭电视)
public class Order_TurnOff implements Order {
    private Receiver receiver;

    public Order_TurnOff(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void excute(int num) {
        this.receiver.turnOff();
    }
}
// 4.3、定义具体命令(切换频道)
public class Order_SwitchChannel implements Order {
    private Receiver receiver;

    public Order_SwitchChannel(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void excute(int num) {
        this.receiver.switchChannel(num);
    }
}
// 5、定义遥控器类(封装命令的集合和遥控器案件的映射关系,通过映射完成具体的命令发送)
import org.apache.commons.lang3.math.NumberUtils;
import java.util.HashMap;
import java.util.Map;

public class TvRemoteControl {
    private static Map<String, Order> orderMap;   // 遥控器案件对应指令集合

    static {  // 初始化封装遥控器指令
        orderMap = new HashMap<>();
        Tv tv = new Tv();
        orderMap.put("on", new Order_TurnOn(tv));   // 按1打开电视
        orderMap.put("off", new Order_TurnOff(tv));   // 按2关闭电视
        Order_SwitchChannel order_switchChannel = new Order_SwitchChannel(tv);
        for (int i = 1; i <= 10; i++) {
            orderMap.put(String.valueOf(i), order_switchChannel);   // 数字对应为切换的频道
        }
    }

    public void sendOrder(String orderNum) {
        if (orderMap.keySet().contains(orderNum)) {
            Order order = orderMap.get(orderNum);
            int num = 0;
            boolean isNum = NumberUtils.isDigits(orderNum);
            if (isNum) {
                num = NumberUtils.toInt(orderNum);
            }
            order.excute(num);
        } else {
            System.out.println("无效的指令");
        }
    }
}
// 6、测试
public static void main(String[] args) {
        TvRemoteControl tvRemoteControl = new TvRemoteControl();
        tvRemoteControl.sendOrder("on");
        tvRemoteControl.sendOrder("5");
        tvRemoteControl.sendOrder("9");
        tvRemoteControl.sendOrder("off");
    }

运行结果:
在这里插入图片描述
可以看到通过遥控器类的具体按钮参数,正确的调用到了具体的命令。本例仅以比较简单的遥控器为示例,如果是比较复杂的遥控器需要在封装map时梳理好对应关系。

总结:
命令模式的主要核心就是将命令封装为业务类,通过发送者,命令,接收者三者之间的逻辑关系(发送者能创建发送命令,命令中包含接收者的属性对象),以此关系来完成某些业务场景下的业务要求。

学海无涯苦作舟!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/609465.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VUE 或 Js封装通用闭包循环滚动函数

1、vue3 闭包滚动函数的使用 js 调用也基本雷同 // 滚动Tab组件const scoreTabRef ref()// 滚动的选项const scrollOption ref({// 滚动的Dom元素scrollDom: null,// 滚动的时间间隔scrollInterval: 1500,// 滚动的距离scrollSep: 100,// 滚动历时时间scrollDuration: 10…

BMJ英国医学杂志文献去哪里下载

《柳叶刀》The Lancet、《新英格兰医学期刊》NEJM、《美国医学会杂志》JAMA、《英国医学期刊》BMJ是世界四大医学顶尖期刊&#xff0c;今天有位医学同学求助一篇BMJ英国医学杂志文献&#xff0c;下面就用这篇文献演示一下在家获取BMJ文献的方法及过程。 文献名&#xff1a;Sur…

Flutter 首次亮相 Google Cloud Next 大会

作者 / Kelvin Boateng Flutter 团队在近期首次参加了 Google Cloud Next 大会&#xff0c;这意味着 Flutter 在开发社区中的影响力正在日益增长。 Google Cloud Next https://cloud.withgoogle.com/next 我们与 Google Cloud、Firebase、Very Good Ventures 和 Serverpod 的团…

【C++】类与对象(类章节)

面向过程和面向对象 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完 成。 一、类 1.类…

【算法】高精度乘法

前言 最近在参加某个比赛的时候遇到了这个问题&#xff0c;用字符串表示时&#xff0c;长度能达到15&#xff0c;所以针对大数乘法写一篇文章。 高精度 * 低精度 在这种场景下&#xff0c;一般都是给定一个无法用int或long long 存储的数&#xff0c;再给定一个能用int或lon…

c++11 标准模板(STL)本地化库 - 平面类别(std::money_get) - 从输入字符序列中解析并构造货币值

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 从输入字符序列中解析并构造货币值 std::money_get template<…

(二十九)深入理解蓝牙BLE之“5.1版本新特性”

回顾5.0新特性&#xff1a; 1.增加2Mbps LE PHY&#xff1a;但是只能用于连接。 2.增加LE Long range&#xff0c;S2&#xff08;500kbps&#xff09;&#xff0c;S8&#xff08;125kbps&#xff09;&#xff1a;可以实现更远的传输距离。 3.增加High duty cycle non-connec…

轮式机器人

迄今为止,轮子一般是移动机器人学和人造交通车辆中最流行的运动机构。它可达到很高的效率, 如图所示, 而且用比较简单的机械就可实现它的制作。 另外,在轮式机器人设计中,平衡通常不是一个研究问题。 因为在所有时间里,轮式机器人一般都被设计成在任何时间里所有轮子均与地接…

「短链接教程」如何使用自己的域名生成短链接

在当今数字化时代&#xff0c;短链接的应用越来越广泛。它们不仅能让链接更简洁美观&#xff0c;还便于分享和传播。 但很多时候想用自己的域名生成短链接&#xff1f;搭建短链接平台又比较麻烦&#xff0c;所以&#xff0c;这里以C1N短网址(c1n.cn)为例&#xff0c;介绍下如何…

MySQL——利用变量进行查询操作

新建链接&#xff0c;自带world数据库&#xff0c;里面自带city表格。 DQL # MySQL利用变量进行查询操作 set cityNameHaarlemmermeer; select * from city where NamecityName;# 多个结果查询 set cityName1Haarlemmermeer; set cityName2Breda; set cityName3Willemstad; s…

重生奇迹mu烈火剑带什么技能

在重生奇迹mu游戏中&#xff0c;35级是每个职业的分水岭&#xff0c;只要到了35级&#xff0c;三职业都可以学习自己的高级技能&#xff0c;道士可以召唤自己的大狗&#xff0c;法师拥有冰咆哮&#xff0c;战士就是咱们今天要说的烈火剑法&#xff0c;这三种技能都需要玩家自己…

Numpy求最大、最小值、求累乘、累和

Numpy求最大、最小值 代码举例&#xff1a; ​ 输出结果为&#xff1a; ​ 在这个例子中&#xff0c;我们首先导入了NumPy库&#xff0c;然后创建了一个3x3的矩阵A。接着&#xff0c;我们使用np.max()函数来求矩阵A的最大值&#xff0c;并将结果存储在变量max_value中&#xff…

树莓派搭建wordpress,上传主题时显示wordpress上传的文件大小超过 php.ini 文件中定义的 upload_max_filesize 值

问题&#xff1a;wordpress上传的文件大小超过 php.ini 文件中定义的 upload_max_filesize 值 解决方案&#xff1a;进入树莓派shell界面 输入指令查找php.ini文件 find / -name ‘php.ini’ 修改php.ini文件 sudo vim /etc/php/8.1/cli/php.ini 找到 upload max filesize…

异步时序电路的分析方法

异步时序电路的分析方法 在异步时序电路中&#xff0c;只有部分触发器由时钟脉冲 CP触发&#xff0c;其它触发器由电路内部信号触发。分析异步时序电路时需写出时钟方程&#xff0c;并特别注意各触发器的时钟条件在何时满足&#xff0c;其状态方程才能使用 Tips&#xff1a;在…

OpenHarmony 实战开发——3.1 Release + Linux 原厂内核Launcher起不来问题分析报告

1、关键字 Launcher 无法启动&#xff1b;原厂内核&#xff1b;Access Token ID&#xff1b; 2、问题描述 芯片&#xff1a;rk3566&#xff1b;rk3399 内核版本&#xff1a;Linux 4.19&#xff0c;是 RK 芯片原厂发布的 rk356x 4.19 稳定版内核 OH 版本&#xff1a;OpenHa…

5G NR 吞吐量计算 and 4G LTE 吞吐量计算

5G NR Throughput References • 3GPP TS 38.306 V15.2.0 (2018-06) ➤J : number of aggregated component carriers in a band or band combination ➤Rmax : 948/1024 • For the j-th CC, Vlayers(j) is the maximum number of layers ➤Qm(j) : Maximum modulation orde…

2024数维杯B题全保姆教程 生物质和煤共热解问题的研究

B题 生物质和煤共热解问题的研究 &#xff08;1&#xff09;基于附件一&#xff0c;请分析正己烷不溶物(INS)对热解产率&#xff08;主要 考虑焦油产率、水产率、焦渣产率&#xff09;是否产生显著影响&#xff1f;并利用图像 加以解释。 根据我视频的分析&#xff0c;这里采用…

阅读送书抽奖?玩转抽奖游戏,js-tool-big-box工具库新上抽奖功能

先讨论一个问题&#xff0c;你做软件工作是为了什么&#xff1f;从高中选专业&#xff0c;就喜欢上了软件开发&#xff1f;还是当初毕业不知道干啥&#xff0c;不喜欢自己的专业&#xff0c;投入软件开发的怀抱&#xff1f;还是干着干着别的&#xff0c;突然觉得互联网行业真不…

Springboot+Vue项目-基于Java+MySQL的毕业就业信息管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

什么是趋势交易?澳福无偿分享

盈利的本质就是能低买高卖&#xff0c;那么怎么能找到交易中的高点和低点呢&#xff1f;其实很简单&#xff0c;只需要运用趋势交易就能很快的找到交易中的高点和低点。那么什么是趋势交易呢&#xff1f;澳福外汇今天详解&#xff01; 趋势交易有3种趋势&#xff0c;如果其包含…