设计模式——命令模式

命令模式

定义

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

优缺点、应用场景

优点

  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();
	}
}

结果

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

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

参考书籍

秦小波《设计模式之禅》

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

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

相关文章

Linux系统使用(超详细)

目录 Linux操作系统简介 Linux和windows区别 Linux常见命令 Linux目录结构 Linux命令提示符 常用命令 ls cd pwd touch cat echo mkdir rm cp mv vim vim的基本使用 grep netstat Linux面试题 Linux操作系统简介 Linux操作系统是和windows操作系统是并列…

Github Pages使用自定义域名

Github Pages使用自定义域名 部署好网站后默认访问地址是xxx.github.io,我们想要自定义为自己的域名 1.DNS解析 这里我使用的是腾讯云,DNS解析DNSPod 添加两条解析记录: 第一个解析记录的记录类型为A&#xff0c;主机记录为&#xff0c;记录值为ping 你的github用户名.githu…

【Java】单例模式

单例模式 设计模式概述单例模式实现思路饿汉式懒汉式饿汉式 vs 懒汉式 设计模式概述 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。就像是经典的棋谱&#xff0c;不同的棋局&#xff0c;我…

【unity之IMGUI实践】单例模式管理面板对象【一】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

electron globalShortcut 快捷键与系统全局快捷键冲突

用 electron 开发自己的接口测试工具&#xff08;Post Tools&#xff09;&#xff0c;在设置了 globalShortcut 快捷键后&#xff0c;发现应用中的快捷键与系统全局快捷键冲突了&#xff0c;导致系统快捷键不可正常使用。 快捷键配置 export function initGlobalShortcut(main…

【宝塔】宝塔部署ThinkPHP项目

最近搞了个培训教育的小程序&#xff0c;后端服务用的是ThinkPHP。使用的过程中&#xff0c;发现对于这种小项目用php还是很不错的选择&#xff0c;开发便捷&#xff0c;轻量级。宝塔神器也是很不错的&#xff0c;值得推荐使用。 下面介绍一下项目中用宝塔部署ThinkPHP项目&…

【菜鸟の笔记_利用Excel自动总结表格数据_自动链接word文本】

自动更新总结表格数据 1. 撰写原因2. 解决的问题3. Excel自动总结表格数据内容&#xff08;一段话&#xff09;。3.1问题引出3.2解决方式 4.Excel数据、总结内容&#xff0c;自动链接更新Word文本 1. 撰写原因 【GPT的答案】利用Excel自动总结表格数据有以下好处&#xff1a; …

redis浅析

一 什么是NoSQL&#xff1f; Nosql not only sql&#xff08;不仅仅是SQL&#xff09; 关系型数据库&#xff1a;列行&#xff0c;同一个表下数据的结构是一样的。 非关系型数据库&#xff1a;数据存储没有固定的格式&#xff0c;并且可以进行横向扩展。 NoSQL泛指非关系…

RocketMQ 为何性能高

本文主要从性能角度考虑 RocketMQ 的实现。 整体架构 这是网络上流行的 RocketMQ 的集群部署图。 RocketMQ 主要由 Broker、NameServer、Producer 和 Consumer 组成的一个集群。 **NameServer&#xff1a;整个集群的注册中心和配置中心&#xff0c;管理集群的元数据。包括 T…

解析Android VNDK/VSDK Snapshot编译框架

1.背景 背景一&#xff1a; 为解决Android版本碎片化问题&#xff0c;引入Treble架构&#xff0c;它提供了稳定的新SoC供应商接口&#xff0c;引入HAL 接口定义语言&#xff08;HIDL/Stable AIDL&#xff0c;技术栈依然是Binder)&#xff0c;它指定了 vendor HAL 和system fr…

容器化背后的魔法之Docker底层逻辑解密

Docker内部工作原理是怎样的&#xff1f; 现在我们知道了Docker是什么以及它提供了哪些好处&#xff0c;让我们逐个重要的细节来了解。 什么是容器&#xff1f;它们是如何工作的&#xff1f; 在深入研究Docker的内部机制之前&#xff0c;我们首先要了解容器的概念。简单地说…

从2023中国峰会,看亚马逊云科技的生成式AI战略

“生成式AI的发展就像一场马拉松比赛&#xff0c;当比赛刚刚开始时&#xff0c;如果只跑了三四步就断言某某会赢得这场比赛&#xff0c;显然是不合理的。我们现在还处于非常早期的阶段。” 近日&#xff0c;在2023亚马逊云科技中国峰会上&#xff0c;亚马逊云科技全球产品副总裁…

JSX的基础使用

1. JSX嵌入变量作为子元素的使用 ①当变量是Number、String、Array类型时&#xff0c;可以直接显示&#xff1b; ②当变量是null、undefined、Boolean类型时&#xff0c;内容为空&#xff1b; 若想要展示nul、undefined、Boolean类型&#xff0c;转字符串&#xff1b;转换方式…

增强型视觉系统 (EVS)

增强型视觉系统 EVS 1、增强型视觉系统概览2、车载相机 HAL2.1 EVS 应用2.2 EVS 管理器2.3 EVS HIDL 接口2.4 内核驱动程序 《增强型视觉系统 (EVS) 1.1 集成指南》 车载相机 HAL 1、增强型视觉系统概览 为了增强视频串流管理和错误处理&#xff0c;Android 11 更新了车载相机…

图像处理之图像灰度化

图像灰度化 将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有R、G、B三个分量决定&#xff0c;而每个分量有255中值可取&#xff0c;这样一个像素点可以有1600多万 (255255255)的颜色的变化范用。而灰度图像是R、G、B三个分量相同的一种特…

纯css3实现小鸡从鸡蛋破壳而出动画特效

实现一个使用纯css3实现小鸡破壳的效果 示例效果如下所示 示例代码 <template><div><div class"eggWrapper"><div class"chickHead"><div class"eyeDiv"></div><div class"eyeDiv"></di…

vue3+mapboxgl鼠标浮动显示cgcs2000

一、需求 鼠标在地图中浮动展示地图的经纬度&#xff0c;cgcs2000 xy 还有显示带号 二、实现效果 展示经度&#xff0c;纬度&#xff0c;x值&#xff0c;y值显示的是带号和y值 三、思路 3.1、mapbox获取经纬度方法 初始化地图后.on方法中有个mousemove方法 mapboxUtil._m…

故障排错篇之OSPF协议

一、OSPF邻居建立不成功 1、从理论上判断问题的所在 1.1、检查邻居两端的接口物理和协议状态是否UP&#xff0c;状态是否稳定&#xff0c;接口是否有丢包&#xff0c;两边互ping大包是否能通 若物理接口不Up或是不稳定&#xff08;有振荡现象&#xff09;&#xff0c;请排查…

lvs使用

1.前言 LVS&#xff08;Linux Virtual Server&#xff09;是一个基于 Linux 内核的负载均衡器&#xff0c;用于分发网络流量和将请求转发给后端服务器。LVS 提供了多种负载均衡算法和转发模式&#xff0c;以满足不同场景和需求的负载均衡需求&#xff0c;在LVS中定义虚拟服务的…

2023- itwangyang - mac mysql 终端启动命令

在mac上使用mysql终端进行操作时&#xff0c;需要先启动mysql服务。以下是启动mysql服务的命令&#xff1a; sudo /usr/local/mysql/support-files/mysql.server start执行该命令后&#xff0c;会出现一些提示信息&#xff0c;等待一段时间后mysql服务就启动成功了。 接下来&…