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

news2024/10/5 3:12:10

目录

一、基础概念

二、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)

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

赛效:如何在线将多图合为GIF动图

1:点击多图合成GIF。 2:点击页面中间的上传按钮,将图片上传到页面上去。 3:动图参数调整好后,点击下方“生成GIF并下载”,就可以将GIF文件保存到电脑本地了。 如果你想了解更多办公软件及其对应的使用教程&…

.net core 2.1 简单部署IIS运行

netcore的项目不像netFramework那么方便部署到iis还是要费点功夫的 比如我想把这个netcore2.1的项目部署到iis并运行: 按照步骤走: 一、确认自己的netcore环境 1、需要安装下面3个环境包(如果电脑已安装请忽略) 检查是否安装cmd命令:cmd&…

这么看,项目经理根本不可能失业

早上好,我是老原。 不知道做项目经理的朋友们有没有这种感觉,明明项目经理是一个高大上的管理岗位,但为何总觉得自己的工作是一个打杂的? 最近就有一个粉丝朋友来和我吐槽:明明是升职,为啥感觉被坑了。 …

Bard!谷歌对 ChatGPT 的最强反击,悄咪咪的支持中文了!

“ ChatGPT、Bard,哪个是更好的AI人工智能大语言模型。” 01 — ChatGPT 这么火,而且这款产品是 OpenAI 以谷歌的大模型架构 transformer 为基础迭代的。谷歌自然不甘落后,早在3月份推出自家的人工智能大语言模型 Bard,只是当时还…

学科知识图谱学习平台项目 :技术栈Java、Neo4j、MySQL等超详细教学

项目设计集合(人工智能方向):助力新人快速实战掌握技能、自主完成项目设计升级,提升自身的硬实力(不仅限NLP、知识图谱、计算机视觉等领域):汇总有意义的项目设计集合,助力新人快速实…

Drools用户手册翻译——第三章 构建,部署,应用和运行(五)可执行规则模型

这应该是Drools的新东西,我之前使用的时候都没注意到还有这么一个东西,据说是可以让Drools变得更高更快更强,这里面有比较详细的介绍,感兴趣就去来看看。 甩锅声明:本人英语一般,翻译只是为了做个笔记&…

N天爆肝数据库——MySQL(4)

本篇文章,主要对多表查询,事务以及体系结构进行知识总结和学习。 期待和大家一起学习进步。标量子查询 子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称标量子查询。常用的操作…

面试题更新之-DOCTYPE html相关问题

文章目录 <!DOCTYPE html>是什么&#xff1f;为什么要在html文件开头加上一个<!DOCTYPE html>DOCTYPE的作用&#xff0c;严格与混杂模式的区别&#xff0c;有何意义HTML5为什么只需要写<!DOCTYPE HTML> 是什么&#xff1f; 是HTML文档的文档类型声明&#xf…

SpringSecurity--权限管理架构介绍

目录 介绍 认证 授权 解决⽅案 Shiro 开发者⾃定义 Spring Security 整体架构 认证 AuthenticationManager&#xff08;认证管理器&#xff09; Authentication SecurityContextHolder 授权 AccessDecisionManager AccessDecisionVoter ConfigAttribute 总结 …

Python在安装包时出现ValueError: check_hostname requires server_hostname和Read timed out

一、ValueError: check_hostname requires server_hostname 出现这个问题基本上是因为开了vpn等网络代理软件造成&#xff0c;关掉代理软件即可解决。 二、Read timed out 在安装python包的时候&#xff0c;出现 Read timed out. 尽管添加了镜像源头py.ini&#xff0c;也添加…

游戏程序员的核心竞争力是什么?

看了题主的描述。你的心迷离&#xff0c;仿佛躲避着梦想的曙光&#xff0c;然而在那一片昏暗的迷雾背后&#xff0c;隐藏的不过是懒散的借口。 编程技能 编程语言掌握&#xff1a; C&#xff1a;C是游戏开发中最常用的编程语言之一。了解C的核心语法、面向对象编程和泛型编程…

使用 jmeter 进行审批类接口并发测试

目录 前言&#xff1a; 背景&#xff1a; 难点&#xff1a; 场景 a&#xff1a; 场景 b&#xff1a; 前言&#xff1a; 使用JMeter进行审批类接口的并发测试是一种有效的方法&#xff0c;可以模拟多个用户同时对接口进行审批操作&#xff0c;以评估系统在高负载情况下的性…

APP开发中的数据安全:你需要知道的一切

APP开发中的数据安全&#xff0c;是指 APP开发过程中&#xff0c;所有的数据都会经过严格的安全处理。因为目前 APP开发公司的技术、资质良莠不齐&#xff0c;很多企业在开发过程中不注重对数据安全的保护。 在如今大数据时代&#xff0c; APP开发过程中&#xff0c;会产生大量…

2023-7-14-第十九式中介者模式

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

linux history 命令 ssh log

history命令可以查看最近Linux中执行的命令。 一、history常用命令 1 2 3 4 history n# 只显示最近的 n 条历史记录 history -c# 清除缓存区中的历史记录 history -w# 将缓存区的历史记录保存到文件 history -d N# 删除第 N 条历史记录 比如# 查看最近的5条命令 1 2 3 4 5 …

【DC-DC】AP5193 DC-DC宽电压LED降压恒流驱动器 LED电源驱动IC

产品 AP5193是一款PWM工作模式,高效率、外围简单、内置功率MOS管&#xff0c;适用于4.5-100V输入的高精度降压LED恒流驱动芯片。最大电流2.5A。AP5193可实现线性调光和PWM调光&#xff0c;线性调光脚有效电压范围0.55-2.6V.AP5193 工作频率可以通过RT 外部电阻编程来设定&…

定西扶贫惠农推介系统(ssm+jsp+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的定西扶贫惠农推介系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java …

21.JavaWeb-RBAC访问控制模型

1.RBAC RBAC&#xff08;Role-Based Access Control&#xff09;是一种基于角色的访问控制模型&#xff0c;用于管理系统中的权限控制。它是一种广泛应用的访问控制策略&#xff0c;可以确保用户只能访问其所需的资源&#xff0c;从而保证系统的安全性和完整性。 RBAC核心是将…

连接一个JavaScript文件

● 首先&#xff0c;本章我们会使用一个起始文件&#xff0c;代码如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0&qu…

LAXCUS分布式操作系统存在的意义和价值

总有一些新用户不能理解LAXCUS分布式操作系统&#xff0c;以及它存在的意义和价值&#xff0c;我这样说吧。 下图是一个图形桌面&#xff08;LAXCUS的图形桌面&#xff0c;不是Windows、也不是Macintosh&#xff09;&#xff0c;在它后面&#xff0c;连着一个计算机集群&#…