Java设计模式之行为型-命令模式(UML类图+案例分析)

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析

1、基本实现

2、点餐案例 

五、总结


一、基础概念

1、将一个请求封装为一个对象,使您可以用不同的请求对客户进行参数化。

2、对请求排队或记录请求日志,以及支持可撤销的操作。

3、将命令对象与执行命令的对象分离,实现调用者和接收者的解耦。

其中命令对象是关键,它包含了一个接收者和一个执行操作的方法。该命令对象绑定一个接收者对象,并通过调用接收者相应的操作来完成执行请求的功能。

二、UML类图

三、角色设计

角色描述
抽象命令类定义命令的接口,声明执行的方法
具体命令角色具体命令类,实现了命令接口,绑定接收者,并实现执行命令的操作
接收者类知道如何实施与执行一个请求相关的操作
调用者类接收命令请求并执行命令
客户端类创建命令对象并设定它的接收者

四、案例分析

1、基本实现

主要包含以下几个部分:

1、Command抽象命令类:定义了命令的公共接口一般是一个execute()方法。

2、ConcreteCommand具体命令角色:实现了Command接口,是具体的命令类,包含对Receiver对象的引用。其execute()方法会调用Receiver的相应方法。

3、Receiver接收者类:命令对象Indirect调用的接收者对象。实现了具体的业务逻辑。

4、Invoker调用者类:请求的调用者。其持有Command对象的引用,并通过command.execute()间接调用Receiver。

5、Client客户端类:创建Command和Receiver对象,并创建Invoker传入Command对象,最后调用Invoker的invoke()方法触发执行。

这个实现让调用者Invoker和接收者Receiver解耦,Invoker只与Command接口发生依赖,不需要知道具体的命令与接收者。

抽象命令类:

public interface Command {
    /**
     * 执行方法
     */
    void execute();
}

 接收者类:

public class Receiver {
    /**
     * 真正执行命令相应的操作
     */
    public void action(){
        System.out.println("执行操作");
    }
}

具体命令角色类:

public class ConcreteCommand implements Command {

    //持有相应的接收者对象
    private Receiver receiver = null;
    /**
     * 构造方法
     */
    public ConcreteCommand(Receiver receiver){
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        //通常会转调接收者对象的相应方法,让接收者来真正执行功能
        receiver.action();
    }

}

调用者类:

public class Invoker {
    /**
     * 持有命令对象
     */
    private Command command = null;
    /**
     * 构造方法
     */
    public Invoker(Command command){
        this.command = command;
    }
    /**
     * 行动方法
     */
    public void action(){
        command.execute();
    }
}

客户端: 

public class Client {

    public static void main(String[] args) {
        //创建接收者
        Receiver receiver = new Receiver();
        //创建命令对象,设定它的接收者
        Command command = new ConcreteCommand(receiver);
        //创建请求者,把命令对象设置进去
        Invoker invoker = new Invoker(command);
        //执行方法
        invoker.action();
    }

}

运行结果如下:

2、点餐案例 

这个点餐的命令模式案例,主要演示了几个角色对象之间的关系:

1、Waiter是接收者对象,知道如何执行点餐操作。

2、OrderCommand是命令对象,它封装了一个点餐请求,绑定了接收者Waiter。可以调用execute()执行点餐。

3、Customer是调用者对象,它通过命令对象indirect地执行点餐请求。可以设定并触发命令。

4、Client是客户端,进行对象的创建和使用。

抽象命令类:

public interface Command {

    public void execute();

}

服务员(接收者类):

public class Waiter {

    public void takeOrder(String food) {
        System.out.println("服务员:收到点餐,食物是:" + food);
    }

}

点餐命令类(具体的命令类):

public class OrderCommand implements Command {

    private Waiter waiter;
    private String food;

    public OrderCommand(Waiter waiter, String food) {
        this.waiter = waiter;
        this.food = food;
    }

    @Override
    public void execute() {
        waiter.takeOrder(food);
    }

}

顾客(调用者类):

public class Customer {

    private Command command;

    public void setOrder(Command command) {
        this.command = command;
    }

    public void orderUp() {
        command.execute();
    }

}

客户端类: 

public class Client {
    
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        Command cmd = new OrderCommand(waiter, "番茄炒蛋");

        Customer customer = new Customer();
        customer.setOrder(cmd);
        customer.orderUp();
    }
    
}

运行结果如下:

整个执行流程是:

1、Client创建Waiter、OrderCommand、Customer对象。

2、Client把OrderCommand命令对象设置给Customer调用者。

3、Client请求Customer调用orderUp方法。

4、Customer的orderUp方法内部将调用OrderCommand的execute。

5、OrderCommand的execute会调用其内部绑定的Waiter的takeOrder方法。

6、这样客户的请求就通过命令对象传达给服务员,进行点餐。

这实现了调用者与接收者的解耦,并且使用命令对象可以方便实现撤销、重做、日志等功能。 

五、总结

优点:

1、解耦了命令的发出者和执行者:发出命令的对象只需要知道命令接口,不需要知道具体的命令执行者。

2、可以较容易地设计一个命令队列和宏命令:通过命令队列可以对命令进行排队,而宏命令可以执行一系列的命令。

3、可以较容易实现命令的撤销和重做:通过保存执行过的命令对象,可以方便地实现回退。

缺点:

1、可能产生很多具体的命令类:因为每一个命令都需要一个具体的命令类,所以如果命令种类很多,会导致类的个数增加很多。

2、系统可能要慢一点,因为每次执行命令时,都需要先创建命令对象。

应用场景:

1、需要对操作进行记录、撤销/重做、事务等处理的场景。命令模式可以方便实现这些功能。

2、需要将请求调用者和请求接收者解耦的场景。命令模式可以使两者独立变化。

3、需要把操作封装成对象传递和存储的场景。命令模式可以把操作转换为对象。

4、需要对操作进行排队或记录日志、支持事务等功能的场景。可以用命令队列实现排队,用命令对象记录日志。

5、需要支持向组合系统中添加新命令的场景。命令模式使新增命令比较方便。

6、需要对系统进行状态恢复的场景。可以利用命令对象实现状态恢复。

7、需要实现宏命令、也就是组合命令的场景。命令模式可以方便实现宏命令。 

符合的设计原则:

1、开闭原则(Open-Closed Principle)

命令模式中,命令的执行者与发出者是解耦的,发出者只知道命令接口,具体的实现执行者可以新增而不需要修改发出者。这样就满足了开闭原则。

2、单一职责原则(Single Responsibility Principle)

命令模式把请求的发出者和执行者进行了分离,发出者负责发出命令请求,执行者负责具体执行,职责划分明确,都满足单一职责原则。

3、组合复用原则(Composite Reuse Principle)

命令模式可以方便地将多个命令组合成一个组合命令,满足组合复用原则。

4、里氏替换原则(Liskov Substitution Principle)

命令模式中抽象命令类规定了接口,具体命令类都遵循这个接口,满足里氏替换原则。

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

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

相关文章

JAVA动态代理

动态代理是在运行时动态生成类字节码,并加载到 JVM 中 你通过Proxy 类的 newProxyInstance() 创建的代理对象在调用方法的时候,实际会调用到实现InvocationHandler 接口的类的 invoke()方法. 运行时的动作由invoke()方法决定控制。 其中运用了反射的相…

(vue)整个页面添加背景视频

(vue)整个页面添加背景视频 App.vue <template><div id"app" :class"[platform]"><video src"./assets/images/top/bg-video-711.mp4" autoplay muted loop class"bg"></video><router-view /></di…

关于Java的网络编程

网络的一些了解 网络通信协议 链路层&#xff1a;链路层是用于定义物理传输通道&#xff0c;通常是对某些网络连接设备的驱动协议&#xff0c;例如针对光纤、网线提供的驱动。网络层&#xff1a;网络层是整个TCP/IP协议的核心&#xff0c;它主要用于将传输的数据进行分组&…

你的隐私被泄漏了吗

近日&#xff0c;某高校毕业生在校期间窃取学校内网数据&#xff0c;收集全校学生个人隐私信息的新闻引发了人们对互联网生活中个人信息安全问题的再度关注。在大数据时代&#xff0c;算法分发带来了隐私侵犯&#xff0c;在享受消费生活等便捷权利的同时&#xff0c;似乎又有不…

按关键词全网采集

简数采集器支持按关键词全网采集&#xff0c;只需输入对应关键词&#xff0c;即可在全网采集相关数据&#xff0c;类似搜索引擎&#xff0c;无需用户配置采集规则。 简数采集器按关键词泛采集可用于舆情监控、市场研究分析等。 使用方法如下&#xff1a; 目录 1. 创建关键词…

MySQL为什么采用B+树作为索引底层数据结构?

索引就像一本书的目录&#xff0c;通过索引可以快速找到我们想要找的内容。那么什么样的数据结构可以用来实现索引呢&#xff1f;我们可能会想到&#xff1a;二叉查找树&#xff0c;平衡搜索树&#xff0c;或者是B树等等一系列的数据结构&#xff0c;那么为什么MySQL最终选择了…

【框架篇】对象注入的三种实现方式

对象注入的实现 一&#xff0c;实现方式的使用 对象注入也可被称为对象装配&#xff0c;是把Bean对象获取出来放到某个类中。 对象注入的实现方式有3种&#xff0c;分别为属性注入&#xff0c;Setter注入和构造方法注入。 为了更好地理解对象注入的实现方式&#xff0c;搞个…

Spring管理事务知识

目录 1.什么是事务 2.事务的特性ACID 3.Spring 管理事务的方式 4.Spring管理事务的体现&#xff1a;JDBCTemplate 5.声明式事务的属性有哪些 6.声明式事务属性---只读 7.声明式事务属性---超时 8.声明式事务属性---回滚策略 9.声明式事务属性---事务隔离级别 10.声明…

1、Kubernetes 概述和架构

目录 一、基本介绍 二、kubernetes功能和架构 2.1、 概述 2.2 、功能 &#xff08;1&#xff09;自动装箱 &#xff08;2&#xff09;自我修复(自愈能力) &#xff08;3&#xff09;水平扩展 &#xff08;4&#xff09;服务发现 &#xff08;5&#xff09;滚动更新 &a…

【Vue】给 elementUI 中的 this.$confirm、this.$alert、 this.$prompt添加按钮的加载效果

文章目录 主要使用 beforeClose 方法实现 loading 的效果beforeClose MessageBox 关闭前的回调&#xff0c;会暂停实例的关闭 function(action, instance, done)1. action 的值为confirm, cancel或close。 2. instance 为 MessageBox 实例&#xff0c;可以通过它访问实例上的属…

C语言中定义和声明的区别

声明(declaration)与定义(definition) 为了使不同的文件都可以访问同一个变量&#xff0c;C会区 分变量的声明和定义。 变量的定义会为这个变量分配存储空间&#xff0c;并且 可能 会为其指定一个初始化的值&#xff0c; 一个变量的定义有且 仅有一处。 定义实际上是一种特殊…

【网络】HTTPS协议原理

目录 “加密”相关概念 为什么要加密 常见加密方式 对称加密 非对称加密 HTTPS工作过程探究 方案1-只使用对称加密 方案2-只使用非对称加密 方案3-客户端和服务端双方都使用非对称加密 方案4-非对称加密 对称加密 上述方案问题分析 方案5-证书认证 非对称加密对…

Kafka传输数据到Spark Streaming通过编写程序java、scala程序实现操作

一、案例说明 现有一电商网站数据文件&#xff0c;名为buyer_favorite1&#xff0c;记录了用户对商品的收藏数据&#xff0c;数据以“\t”键分割&#xff0c;数据内容及数据格式如下&#xff1a; 二、前置准备工作 项目环境说明 Linux Ubuntu 16.04jdk-7u75-linux-x64scal…

C++的switch函数用法

一个 switch 语句允许测试一个变量等于多个值时的情况。每个值称为一个 case&#xff0c;且被测试的变量会对每个 switch case 进行检查。 语法 C 中 switch 语句的语法&#xff1a; switch(expression){ case constant-expression : statement(s); break; // 可选的 case c…

解决MAC IDEA终端每次都要source ~/.zshrc

安装nvm之后&#xff0c;发现每隔一段时间&#xff08;不清楚是新打开一个终端还是会定时刷新&#xff09;就要重新执行source ~/zshrc&#xff0c;才能执行nvm命令。找了一圈发现idea默认使用的shell是bash&#xff0c;将默认的shell改成zsh就可以&#xff0c;更改位置&#x…

多模态系列论文--CoCa 详细解析

论文地址&#xff1a;CoCa: Contrastive Captioners are Image-Text Foundation Models 代码地址&#xff1a;CoCa CoCa 1 摘要2 网络结构3 损失函数4 实验结果5 总结 1 摘要 CoCa代表Contrastive Captioners的缩写&#xff0c;代表模型用两个目标函数训练出来的&#xff0c;一…

selenium怎么使用代理IP

什么是selenium Selenium 是一个自动化测试框架&#xff0c;用于测试 Web 应用程序的功能性。它支持多个编程语言&#xff08;如Java&#xff0c;Python&#xff0c;C#等&#xff09;并且可以在操作系统和不同浏览器上运行测试。Selenium 可以模拟用户在浏览器中的操作&#x…

PyTorch从零开始实现Transformer

文章目录 自注意力Transformer块编码器解码器块解码器整个Transformer参考来源全部代码&#xff08;可直接运行&#xff09; 自注意力 计算公式 代码实现 class SelfAttention(nn.Module):def __init__(self, embed_size, heads):super(SelfAttention, self).__init__()self.e…

RDS-Tools RDS-Knight Crack

RDS 高级安全性 利用全面的网络安全工具箱中有史以来最强大的安全功能集来保护您的 RDS 基础架构。 全方位 360 保护 无与伦比的功能集 无与伦比的物有所值 企业远程桌面安全。现代工作空间的智能解决方案。 办公室正在权力下放。远程办公室和移动员工数量创历史新高。随…

机器学习技术(四)——特征工程与模型评估

机器学习技术&#xff08;四&#xff09;——特征工程与模型评估(1️⃣) 文章目录 机器学习技术&#xff08;四&#xff09;——特征工程与模型评估(:one:)一、特征工程1、标准化2、特征缩放3、缩放有离群值的数据4、非线性转换5、样本归一化6、特征二值化7、标称特征编码(one-…