【Java设计模式】十五、命令模式

文章目录

  • 1、命令模式
  • 2、案例
  • 3、总结

1、命令模式

餐厅点餐:

在这里插入图片描述

创建一个厨师对象,让服务员对象调用厨师对象中的方法进行点餐通知,当后面厨师换人,服务员类的代码也要修改,耦合 + 不符合开闭。理想状态:服务员将订单放柜台,不用关注是哪个厨师去做。厨师照着订单做菜,不用关注哪个服务员放的。

将发出请求和责任 和 执行请求的责任分割开,并将请求封装成一个命令对象,二者通过命令对象进行沟通。

主要角色:

  • 抽象命令类
  • 具体命令类:聚合接收者对象
  • 接收者:执行命令的对象
  • 请求者:上面例子中的服务员对象,聚合抽象命令类的对象

2、案例

实现上面的点餐案例:

在这里插入图片描述

定义订单类,模拟一点业务信息,包含餐桌号、所下餐品的名字和份数

public class Order {

    // 餐桌号码
    private int diningTable;

    // 用来存储餐名并记录份数,key为餐名,value为份数
    private Map<String, Integer> foodDic = new HashMap<String, Integer>();

    public int getDiningTable() {
        return diningTable;
    }

    public void setDiningTable(int diningTable) {
        this.diningTable = diningTable;
    }

    public Map<String, Integer> getFoodDic() {
        return foodDic;
    }

	//直接往空map放数据
    public void setFoodDic(String name, int num) {
        foodDic.put(name,num);
    }
}

定义厨师类:

// 资深大厨类 是命令的Receiver
public class SeniorChef {
	
	//制作食物
    public void makeFood(int num,String foodName) {
        System.out.println(num + "份" + foodName);
    }
}

定义抽象命令类,定义一个执行命令的方法:

public interface Command {
    void execute();//只需要定义一个统一的执行方法
}

定义具体的命令类,聚合接收者对象(厨师对象),调用接收者类的方法来干活儿:

public class OrderCommand implements Command {

    //持有接受者对象
    private SeniorChef receiver;
    private Order order;

    public OrderCommand(SeniorChef receiver, Order order){
        this.receiver = receiver;
        this.order = order;
    }

	@Override
    public void execute()  {
        System.out.println(order.getDiningTable() + "桌的订单:");
        Set<String> keys = order.getFoodDic().keySet();
        for (String key : keys) {
            receiver.makeFood(order.getFoodDic().get(key),key);   //调用执行者的方法
        }

        try {
            Thread.sleep(100);//停顿一下 模拟做饭的过程
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        System.out.println(order.getDiningTable() + "桌的饭弄好了");
    }
}

定义服务员类(请求者),聚合多个命令对象:

public class Waitor {

    private ArrayList<Command> commands;//可以持有很多的命令对象

    public Waitor() {
        commands = new ArrayList();   //无参构造中直接初始化一个空集合
    }
    
    public void setCommand(Command cmd){
        commands.add(cmd);     //set时,不set一个List,直接往List存元素
    }

    // 发出命令 喊 订单来了,厨师开始执行
    public void orderUp() {
        System.out.println("美女服务员:叮咚,大厨,新订单来了.......");
        for (int i = 0; i < commands.size(); i++) {
            Command cmd = commands.get(i);
            if (cmd != null) {  //健壮性
                cmd.execute();   
            }
        }
    }
}

定义客户端:

public class Client {
    public static void main(String[] args) {
        //创建2个order
        Order order1 = new Order();
        order1.setDiningTable(1);  //1号桌
        order1.getFoodDic().put("西红柿鸡蛋面",1);
        order1.getFoodDic().put("小杯可乐",2);

        Order order2 = new Order();
        order2.setDiningTable(3);  //3号桌
        order2.getFoodDic().put("尖椒肉丝盖饭",1);
        order2.getFoodDic().put("小杯雪碧",1);

        //创建接收者
        SeniorChef receiver=new SeniorChef();
        //将订单和接收者封装成命令对象
        OrderCommand cmd1 = new OrderCommand(receiver, order1);
        OrderCommand cmd2 = new OrderCommand(receiver, order2);
        //创建调用者 waitor
        Waitor waitor = new Waitor();
        waitor.setCommand(cmd1);
        waitor.setCommand(cmd2);

        //将订单带到柜台 并向厨师喊 订单来了
        waitor.orderUp();
    }
}

运行:

在这里插入图片描述

3、总结

适用场景:

  • 需要将调用者和请求者解耦,使二者不直接交互(如服务员类调用命令类,命令类里调用接收者
  • 结合备忘录模式,支持命令的撤销和恢复操作

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

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

相关文章

java SSM农产品订购网站系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM农产品订购网站系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采…

Asp .Net Web Forms 系列:配置图片防盗链的几种方法

通过 URL Rewrite Module 组件 URL Rewrite Module 是一个用于在 ASP.NET Web Forms 或其他基于 IIS 的 Web 应用程序中重写 URL 的强大工具。这个模块允许你将复杂的、不易于记忆或不利于搜索引擎优化的 URL 转换为更简洁、更友好的格式。通过 URL 重写&#xff0c;你可以提高…

Opencv 插值方法 总结

一、概括 面试的时候问到了一个图&#xff0c;就是如何将一个算子放缩&#xff1f;&#xff1f;我第一反应是resize&#xff08;&#xff09;,但是后来我转念一想&#xff0c;人家问的是插值方式&#xff0c;今天来总结一下 最邻近插值法原理分析及c实现_最临近插值法-CSDN博…

050-WEB攻防-PHP应用文件包含LFIRFI伪协议编码算法无文件利用黑白盒

050-WEB攻防-PHP应用&文件包含&LFI&RFI&伪协议编码算法&无文件利用&黑白盒 #知识点&#xff1a; 1、文件包含-原理&分类&危害-LFI&RFI 2、文件包含-利用-黑白盒&无文件&伪协议 演示案例&#xff1a; ➢文件包含-原理&分类&am…

解决达梦集成 JPA 时表和字段注释注解不生效的问题

前言 最近在做达梦数据库集成 JPA 时&#xff0c;发现使用的表注解和字段注解均未生效&#xff08;MySQL、Oracle、PostgreSQL中均可以在建表时正常生成相应的注释&#xff09;&#xff0c;经过调试发现解决办法也很简单&#xff1a; 自定义方言类继承自org.hibernate.dialect…

vue3 动态路由及使用动态路由后刷新界面出现空白页或者404

最近编写vue3动态路由的功能遇到了一些问题&#xff0c;处理好了&#xff0c;总结出来&#xff0c;希望能帮助到你。正片开始 先写好本地缓存菜单的方法&#xff08;存储、删除、获取&#xff09; // utils/menu.jsconst getMenuList () > {return JSON.parse(localStorag…

C语言——简易版扫雷

目录 前言 ​编辑 游戏规则 游戏结构的分析 游戏的设计 使用多文件的好处有以下几点&#xff1a; 游戏代码实现 框架&#xff08;test.c&#xff09; game函数&#xff08;test.c&#xff09; InitBoard初始化&#xff08;game.c&#xff09; Print打印棋盘&#xff08;g…

【物联网设备端开发】FastBee Arduino固件开发指南

目录 一、收集数据 二、打开FastBeeArduino 源码 三、修改 Config.cpp 文件 四、修改物模型数据 五、小程序配网 本文以 WeMOS D1 R1&#xff08;8266WIFI 模块&#xff09;固件开发为例&#xff0c;实现以下功能&#xff1a; 设备认证设备 Mqtt 交互Wifi 类设备配网 一…

vue学习笔记23-组件事件⭐

组件事件 在组件的模板表达式中&#xff0c;可以直接使用$emit方法触发自定义事件&#xff1b;触发自定义事件的目的是组件之间传递数据 好好好今天又碰到问题了&#xff0c;来吧来吧 测试发现其他项目都可以 正常的run ,就它不行 搜索发现新建项目并进入以后&#xff0c;用指…

搭建mysql主从复制(主主复制)

1&#xff1a;设主库允许远程连接(注意&#xff1a;设置账号密码必须使用的插件是mysql_native_password&#xff0c;其他的会连接失败) #切换到mysql这个数据库&#xff0c;修改user表中的host&#xff0c;使其可以实现远程连接 mysql>use mysql; mysql>update user se…

使用C#创建服务端Web API

前言 C# Web API 是一种基于 .NET 平台&#xff08;包括但不限于.NET Framework 和 .NET Core&#xff09;构建 HTTP 服务的框架&#xff0c;用于创建 RESTful Web 服务。REST&#xff08;Representational State Transfer&#xff09;是一种软件架构风格&#xff0c;它利用HT…

linux中查看目录文件(ls)用法:

查看目录下的文件&#xff1a;ls&#xff08;list&#xff09; 作用 查看目录下的内容 格式 ls -参数 操作对象参数 参数功能-l以长格形式显示文件和目录的详细信息,ls命令默认只显示名称的短格式。-d显示指定目录本身的信息,而不显示目录下的各个文件和子目录的信息。-…

【机器学习】机器学习是什么?用在哪里?怎么用?

1.机器学习是什么&#xff1f; 机器学习&#xff08;Machine Learning&#xff09;是人工智能的一个分支&#xff0c;它是一种通过对数据进行训练和学习&#xff0c;让计算机系统从中获取知识并改善性能的方法。简而言之&#xff0c;机器学习使计算机具有从数据中学习并自动改…

信息系统项目管理师009:消费互联网(1信息化发展—1.3现代化创新发展—1.3.3 消费互联网)

文章目录 1.3.3 消费互联网1.基本属性2.应用新格局 1.3.3 消费互联网 消费互联网是以个人为用户&#xff0c;以日常生活为应用场景的应用形式&#xff0c;满足消费者在互联网中的消费需求而生的互联网类型。消费互联网以消费者为服务中心&#xff0c;针对个人用户提升消费过程的…

机器学习模型—支持向量机 (SVM)

机器学习模型—支持向量机 (SVM) 支持向量机 (SVM) 是一种强大的机器学习算法,用于线性或非线性分类、回归,甚至异常值检测任务。SVM 可用于各种任务,例如文本分类、图像分类、垃圾邮件检测、笔迹识别、基因表达分析、人脸检测和异常检测。SVM 在各种应用中具有适应性和高效…

Github上哪些好用的工具

专注于web漏洞挖掘、内网渗透、免杀和代码审计&#xff0c;感谢各位师傅的关注&#xff01;网安之路漫长&#xff0c;与君共勉&#xff01; Qexo-爱写博客的师傅强烈推荐 漂亮的 Hexo 静态博客编辑器。该项目是基于 Django 的 Hexo 静态博客管理后台&#xff0c;支持文章管理、…

【Linux杂货铺】操作系统

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 冯诺依曼体系结构 &#x1f4c2; 拓展问题&#xff1a;程序为什么要被加载到内存&#xff1f; &#x1f4c2; 主机与主机的交互 &#x1f4c1; 操作系统的概念 &#x1f4c2; 作用 &#x1f4c2; 理解“管理” &#x…

Hadoop学习3:问题解决

文章目录 问题解决1. ERROR: but there is no HDFS_NAMENODE_USER defined2. JAVA_HOME is not set and could not be found.3. Hadoop-DFS页面访问不了4. namenode格式化失败&#xff0c;或者dfs页面打开失败5. ERROR: but there is no YARN_RESOURCEMANAGER_USER defined. Ab…

YOLOv5独家改进:backbone改进 | 最新大卷积核CNN架构UniRepLKNet,ImageNet 88% | CVPR2024

💡💡💡本文独家改进:大核卷积一统多种模态!RepLK正统续作UniRepLKNet,代替YOLOv5 Backbone 改进结构图如下: 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_12511931.html 💡💡💡全网独家首发创新(原创),适合paper !!! 💡…

对于双列集合map的学习

双列集合 特点 1.双列集合一次需要存一对数据&#xff0c;分别是键和值。 2.键和值一一对应&#xff0c;键不能重复&#xff0c;值能重复。 3.键值这个整体我们称之为键值对或者键值对对象&#xff0c;在java中叫做Entry对象。 Map的常见API Map是双列集合的顶层接口&…