设计模式——命令模式

news2024/10/7 4:05:00

命令模式

定义

将一个请求封装成一个对象,从而让你使用不同的请求吧客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
命令模式是一个高内聚的模式。

优缺点、应用场景

优点

  1. 类间解耦。调用者与接收者之间没有任何依赖关系。调用者只需要调用execute()方法即可,不需要了解哪个接收者执行。
  2. 可拓展性。
  3. 命令模式结合其他模式会更优秀。例如与责任链模式结合,实现命令族解析任务;结合模板方法模式,可以减少Command子类膨胀问题。

缺点

  1. 类的膨胀问题。如果有N个命令,则子类的数量就为N个,这可能会导致类的膨胀,需要慎重使用。

代码模拟场景

项目组有三个小组需求组、美工组、编码组,客户的每个“命令”都有可能涉及到多个组的响应,使用命令模式一方面接收客户的“命令”,另一方面根据“命令”组合出小组之间的分工。

实验小结

  1. 你永远也不知道用户到底怎么定义他的需求,每次的修改都相当于命令
  2. 如果对于每个命令都需要new来处理,那么每次都需要创建一个场景类,而且是手动的执行命令中的每个细节
  3. 命令模式要求,将一个命令中所有的细节都交给Command的实现类来做,执行命令时由唯一执行人Invoker来执行,而客户的需求只跟Invoker说明,由Invoker发布命令

命令模式

UML图

在这里插入图片描述

部门抽象及部门实体

/**
 * 抽象组
 */
public abstract class Group {
	// 甲乙双方分开办公,如果要和某个组讨论,首先要找到这个组
	public abstract void find();
	// 被要求增加功能
	public abstract void add();
	// 被要求删除功能
	public abstract void delete();
	// 被要求修改功能
	public abstract void change();
	// 被要求给出所有的变更计划
	public abstract void plan();
}

/**
 * 需求组
 */
public class RequirementGroup extends Group {
	@Override
	public void find() {
		System.out.println("找到需求组。。。");
	}
	@Override
	public void add() {
		System.out.println("客户要求增加一项需求");
	}
	@Override
	public void delete() {
		System.out.println("客户要求删除一项需求");
	}
	@Override
	public void change() {
		System.out.println("客户要求修改一项需求");
	}
	@Override
	public void plan() {
		System.out.println("客户要求需求变更计划");
	}
}

/**
 * 美工组
 */
public class PageGroup extends Group {
	@Override
	public void find() {
		System.out.println("找到美工组。。。");
	}
	@Override
	public void add() {
		System.out.println("客户要求增加一个页面");
	}
	@Override
	public void delete() {
		System.out.println("客户要求删除一个页面");
	}
	@Override
	public void change() {
		System.out.println("客户要求修改一个页面");
	}
	@Override
	public void plan() {
		System.out.println("客户要求页面变更计划");
	}
}

/**
 * 代码组
 */
public class CodeGroup extends Group {
	@Override
	public void find() {
		System.out.println("找到代码组。。。");
	}
	@Override
	public void add() {
		System.out.println("客户要求增加一项功能");
	}
	@Override
	public void delete() {
		System.out.println("客户要求删除一项功能");
	}
	@Override
	public void change() {
		System.out.println("客户要求修改一项功能");
	}
	@Override
	public void plan() {
		System.out.println("客户要求代码变更计划");
	}
}

命令Command抽象与实现

/**
 * 抽象命令类
 */
public abstract class Command {
	// 定义好三个组,子类可以直接使用
	protected RequirementGroup requirementGroup = new RequirementGroup();
	protected PageGroup pageGroup = new PageGroup();
	protected CodeGroup codeGroup = new CodeGroup();
	// 只有一个方法:执行
	public abstract void execute();
}

/**
 * 需求组添加需求的命令
 */
public class AddRequirementCommand extends Command {
	@Override
	public void execute() {
		super.requirementGroup.find();
		super.requirementGroup.add();
		super.requirementGroup.plan();
	}
}

/**
 * 需求组添加需求的命令
 */
public class DeletePageCommand extends Command {
	@Override
	public void execute() {
		super.pageGroup.find();
		super.pageGroup.delete();
		super.pageGroup.plan();
	}
}

执行人(实施)

/**
 * 执行者
 */
public class Invoker {
	private Command command;
	// 客户发出命令
	public Invoker setCommand(Command command) {
		this.command = command;
		// 这个地方自己加的,为了方便设置命令后执行
		return this;
	}
	// 执行客户的命令
	public void action(){
		this.command.execute();
	}
}

入口类

public class CommandMain {
	public static void main(String[] args) {
//        硬核需求();
		command();
	}

	// 命令模式
	public static void command(){
		Invoker<Command> invoker = new Invoker<>();
		// 添加一个需求
		Command addRequirementCommand = new AddRequirementCommand();
		// 设置命令,在这里需要什么命令就直接new一个Command接口的实现类即可
		Command deletePageCommand = new DeletePageCommand();
		invoker.setCommand(addRequirementCommand);     // 执行
		invoker.setCommand(deletePageCommand);
		invoker.rollback(addRequirementCommand.getClass());     // 客户要求回滚
		invoker.action();
	}

	public static void 硬核需求(){
		System.out.println("-----客户要求增加一项需求-----");
		Group requirementGroup = new RequirementGroup();
		// 找到需求组
		requirementGroup.find();
		// 添加需求
		requirementGroup.add();
		// 要求变更计划
		requirementGroup.plan();
	}
}

结果

非命令模式
在这里插入图片描述

命令模式
在这里插入图片描述

参考书籍

秦小波《设计模式之禅》

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

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

相关文章

探索AI领域,AI图像安全技术助力行业健康发展

目录 一、AI时代降临二、AIOCR与传统OCR技术三、通过人工智能模型生成AI图片技术探索四、提前布局&#xff0c;合合信息AI图像安全技术助力行业健康发展1、识别医疗门诊发票和报告2、图像篡改检测升级&#xff0c;截图篡改检测3、AIGC判别&#xff0c;人脸伪造检测4、OCR对抗攻…

WebSocket使用记录

使用视频地址 1、添加前端使用文件 2、后端配置 2.1添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>2.2添加websocket配置类 import org.spri…

NETSDK1141 无法解析位于 global.json 中指定的 .NET SDK 版本

1. 使用cmd命令 dotnet --info 查看自己使用的SDK版本 3.直接找到项目中的 global.json 文件&#xff0c;右键打开&#xff0c;直接修改版本为本机的SDK版本&#xff0c;就可以用了 微软文档也有详细说明: ​​​​​​NETSDK1141&#xff1a;无法解析 global.json 中指定的…

浅析CAS

CAS基本使用 以ReentrantLock为例&#xff0c;观察CAS基本使用。 class ReentrantLockExample {int a 0;// 非公平锁ReentrantLock lock new ReentrantLock(false);public void writer() {// 获取锁lock.lock();try {a;} finally {// 释放锁lock.unlock();}}public void re…

生产环境 kafka 平滑迁移之旅

文章目录 背景分析测试环境验证现实很残酷两种抉择-----leader分区切换方案选择实施步骤手工副本集增加步骤手工leader分区切换步骤 总结 背景 线上kafka集群&#xff0c;3台机器&#xff0c;3个broker&#xff1b;其中某台机器因为硬件故障&#xff0c;需要停机维修&#xff…

MSP432学习笔记12:MSP432时钟源与定时器A时钟源配置

今日深入学习一下MSP432的时钟源与配置&#xff0c; 可以结合之前的滴答计时器相关文章&#xff1a; MSP432学习笔记4&#xff1a;时钟与滴答计时器_NULL指向我的博客-CSDN博客 目录 MSP432有关时钟源系统的性能&#xff1a; 七种时钟源&#xff1a; 五种时钟&#xff1a; …

创新实践,复合机器人采摘运输教育沙盘案例研究

引言 在之前我们已经介绍了水果采摘和分拣机器人的应用场景&#xff0c;今天我们来介绍复合机器人水果采摘运输的场景。 作为最热门的技术领域&#xff0c;机器人技术正在彻底改变各行各业&#xff0c;推动全球创新。为了满足这一快速发展领域对专业技术人才日益增长的需求&a…

【Matlab】智能优化算法_广义正态分布优化算法GNDO

【Matlab】智能优化算法_广义正态分布优化算法GNDO 1.背景介绍2.数学模型2.1 局部开采2.2 全局勘探 3.文件结构4.伪代码5.参考文献 1.背景介绍 GNDO受到正态分布理论的启发。正态分布也称为高斯分布&#xff0c;是描述自然现象的一个非常重要的工具。正态分布可以定义如下。假设…

NLP Transformer的Decoder的输入输出都是什么?能解释一下每个部分都是什么?

要弄清楚Decoder的输入输出&#xff0c;关键在于图示三个箭头的位置&#xff1a; 以翻译为例&#xff1a; 输入&#xff1a;我爱中国输出&#xff1a; I Love China 因为输入&#xff08;“我爱中国”&#xff09;在Encoder中进行了编码&#xff0c;这里我们具体讨论Decoder的…

【工具推荐】企业微信、企业飞书接口调用工具

github地址: GitHub - fasnow/idebug: 企业微信、企业飞书接口调用工具。 简介 企业微信、企业飞书接口调用工具。 使用方法 wechat模块 使用use wechat 选择模块。 首先设置corpid和corpsecret&#xff0c;如有需要可以设置代理&#xff0c;之后再执行run命令。 导出通信…

飞行动力学 - 第6节-part3-风对航程的影响 之 基础点摘要

飞行动力学 - 第6节-part3-风对航程的影响 之 基础点摘要 1. 风对航程的影响2. 典型飞机航程3. 世界上最长航线4. 参考资料 1. 风对航程的影响 可以认为风移动的距离相当于飞机在静止空间移动的距离加上风移动的距离。 在物理上可以简单的理解为两个矢量叠加和。 回顾喷气式&…

WebGPU实战3D电商

在过去的几年里&#xff0c;我们一直在为 WebGPU 编写新版本的 Babylon.js 引擎。 随着下一代 Web 3D 即将在Chrome 102~103版本上公开WebGPU 1.0 &#xff0c;人们的兴奋情绪与日俱增。 在这篇博文中&#xff0c;我将快速概述这个新的 Babylon.js WebGPU 引擎&#xff0c;并将…

100种思维模型之安全边际思维模型-92

安全边际&#xff0c; 简而言之即距离某一件糟糕的事件发生&#xff0c;还有多大的空间&#xff0c;安全边际越高&#xff0c;我们就越安全&#xff01; 安全边际思维模型一个 让生活变得更从容 的 思维模型。 01、何谓安全边际思维模型 一、安全边际思维 安全边际 源于…

千云探探监测到7月4日法国Facebook社交网络异常

针对法国近期出现的骚乱游行&#xff0c;法国司法部长莫雷蒂7月1日时候表示&#xff0c;法国检察官要求互联网运营商提供在社交平台Snapchat上号召骚乱年轻人的IP地址。 法国总统马克龙7月4日表示&#xff1a;“如果事态失控&#xff0c;我们可能需要监管或关闭它们&#xff0…

idea 添加类库

打开项目中的独立环境文件夹&#xff0c;右键打开终端输入安装类库的命令&#xff1a; pip install requests pip3 install BeautifulSoup4 检查这里是否把类库加进来了&#xff0c;加进来就完成&#xff01;

第十二章 kafka

Producer:Producer即生产者,消息的产生者,是消息的入口。 kafka cluster: Broker:Broker是kafka实例,每个服务器上有一个或多个kafka的实例,我们姑且认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0、broker-1等…… 主…

Windows如何恢复已删除的Word文档?

案例&#xff1a;可以恢复已删除的Word文档吗&#xff1f; “大家好&#xff0c;我遇到了一个问题&#xff0c;需要大家的帮助。昨天我编辑了一个Word文档并保存到了桌面上&#xff0c;但当我今天再次打开电脑时&#xff0c;它就不见了&#xff01;昨天工作完成后&#xff…

mysql数据库以及管理流程

目录 1.基本概念 2.DBMS工作模式 3.关系型数据库和非关系型数据库 4.数据库管理 sql语句 5.一些命令 6.增删改查命令 DDL DML 7.案例 创建表 删除 DML管理表中内容 增加内容 改内容 删内容 DCL具体应用 1.基本概念 1.数据 描述事物的符号记录(数字 文字 图像等) …

【报错记录】解决CentOS免密失败的问题,以及解决免密问题的排查流程

前言 本文相当于对之前的文章进行的补充【原创】三台CentOS7非root用户间实现相互间的免密登录_DCTANT的博客-CSDN博客 现场遇到一台旧服务器与其他服务器免密失败的问题&#xff0c;明明.ssh目录中authorized_keys中的公钥设置都是正确的&#xff0c;但是别的服务器连它都得…

基础篇--STM32原理图设计

学会查看数据手册 芯片数据手册获取方式 ST官网&#xff1a;https://www.st.comST中文社区网&#xff1a;https://www.stmcu.org.cn/ 数据手册内容概要 芯片的基本参数&#xff08;STM32F103ZET6为例&#xff09; 主频/FLASH/SRAM &#xff1a; 72MHz/512KB/64KB工作电压/…