当前位置: 首页 > news >正文

设计模式使用场景实现示例及优缺点(行为型模式——命令模式)

从前,在一个美丽而神秘的王国里,住着一位智慧而仁慈的国王。他不仅以其公正和睿智著称,还因为他对知识的热爱和追求。他的王国繁荣昌盛,人们生活幸福安康。但即便如此,国王知道,要维持这种繁荣与和平,需要不断学习和改进。

一天,国王召集了他的三位最信任的大臣:战士将军艾里克、魔法师梅琳达和工程师菲利克斯。他告诉他们,他听说在遥远的东方,有一种古老的智慧,名为“命令模式”。这种智慧可以将复杂的请求转化为简洁有力的命令,从而使整个王国的管理更加高效。

将军艾里克是个果敢的人,他立刻提议亲自前往东方寻找这种智慧。梅琳达和菲利克斯也表示愿意一同前往。于是,三人开始了他们的冒险旅程。

他们跋山涉水,穿越了茂密的森林和险峻的山脉,终于来到了一个传说中的智慧之城。在那里,他们遇到了一位古老的智者。智者同意教他们命令模式的秘密,但前提是他们必须通过三个试炼。

第一个试炼是智慧试炼。智者给他们出了一个难题:如何将一个复杂的请求简化为一个简单的命令?梅琳达用她的魔法力量,展示了如何将繁琐的法术步骤封装在一个简单的魔法卷轴中,完美地解决了难题。

第二个试炼是勇气试炼。智者让他们面对一头凶猛的巨龙,并要求他们在不伤害巨龙的情况下,取回巨龙守护的宝物。将军艾里克利用他的勇气和智慧,使用命令模式中的“请求撤销”原理,指挥巨龙一步步离开宝物,最终成功取回宝物。

最后一个试炼是团队合作试炼。智者让他们设计一个系统,使得城市中的每个居民都能轻松发出请求,并能得到迅速响应。菲利克斯用他的工程知识,设计了一套基于命令模式的系统,每个请求都被封装成一个对象,并根据需要进行排队、记录和执行。三人齐心协力,完美地通过了试炼。

智者对他们的表现非常满意,将命令模式的所有秘密传授给了他们。三人带着智慧的结晶,回到了王国。他们将命令模式应用到王国的各个领域,管理变得更加高效,人民的生活也更加便利。

从那以后,这个王国不仅以其繁荣与和平著称,还以其先进的管理系统闻名于世。而将军艾里克、魔法师梅琳达和工程师菲利克斯,也被人们称颂为智慧与勇气的化身。他们的冒险故事,也成为了世代相传的美谈。

命令模式(Command Pattern)

命令模式(Command Pattern)是一种行为设计模式,它将请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化,队列或记录请求日志,以及支持可撤销的操作。在命令模式中,请求被封装为一个对象,这个对象包含了执行请求的方法,以及所有必要的参数。这样,客户端只需创建并传递一个命令对象给调用者,而无需关心具体的实现细节。

核心组件

  • Command(命令):定义了执行请求的接口。
  • ConcreteCommand(具体命令):实现了命令接口,负责调用请求的接收者来执行请求。
  • Receiver(接收者):知道如何实施与执行一个请求相关的操作。
  • Invoker(调用者):要求命令执行请求的对象。
  • Client(客户端):创建具体命令对象并设置其接收者。

适用场景

  1. 需要将请求发送者和请求接收者解耦
    • 命令模式允许请求发送者和接收者独立变化,互不影响。
  2. 需要支持命令的排队、记录请求日志、撤销操作等功能
    • 命令模式可以轻松地扩展这些功能。
  3. 需要将一组操作组合在一起形成一个命令
    • 命令模式可以将多个操作封装成一个命令对象。

实现实例

基于命令模式(Command Pattern)的遥控器控制家电的系统。

命令接口(Command Interface)

定义了执行命令的方法。

public interface Command {void execute(); // 执行命令的方法
}

具体命令(Concrete Command)

实现了命令接口,负责调用接收者执行具体操作。

LightOnCommand
public class LightOnCommand implements Command {private Light light; // 接收者对象public LightOnCommand(Light light) {this.light = light;}public void execute() {light.turnOn(); // 调用接收者的方法}
}
LightOffCommand
public class LightOffCommand implements Command {private Light light; // 接收者对象public LightOffCommand(Light light) {this.light = light;}public void execute() {light.turnOff(); // 调用接收者的方法}
}

接收者(Receiver)

知道如何实施与执行请求相关的操作。

public class Light {public void turnOn() {System.out.println("Light is on"); // 执行打开灯的操作}public void turnOff() {System.out.println("Light is off"); // 执行关闭灯的操作}
}

调用者(Invoker)

要求命令执行请求的对象。

public class RemoteControl {private Command command; // 当前命令对象public void setCommand(Command command) {this.command = command; // 设置命令对象}public void pressButton() {command.execute(); // 执行当前命令}
}

客户端代码(Client Code)

演示如何使用命令模式。

public class Client {public static void main(String[] args) {Light livingRoomLight = new Light(); // 创建接收者对象Command lightOn = new LightOnCommand(livingRoomLight); // 创建打开灯的命令Command lightOff = new LightOffCommand(livingRoomLight); // 创建关闭灯的命令RemoteControl remoteControl = new RemoteControl(); // 创建调用者对象remoteControl.setCommand(lightOn); // 设置打开灯的命令remoteControl.pressButton(); // 执行打开灯的命令remoteControl.setCommand(lightOff); // 设置关闭灯的命令remoteControl.pressButton(); // 执行关闭灯的命令}
}

解释

  • 命令接口(Command Interface):定义了 execute() 方法,所有具体命令类都必须实现这个方法。
  • 具体命令(Concrete Command):实现 Command 接口,负责调用接收者对象的具体操作。LightOnCommandLightOffCommand 分别负责打开和关闭灯光。
  • 接收者(Receiver)Light 类知道如何执行具体操作,如打开和关闭灯光。
  • 调用者(Invoker)RemoteControl 类持有一个命令对象,通过 setCommand() 方法设置当前命令,并通过 pressButton() 方法执行命令。
  • 客户端代码(Client Code):客户端代码创建具体的接收者、命令和调用者对象,并通过设置和执行命令来控制灯光的开关。

这种设计模式的优势在于将请求的发送者和接收者解耦,使得系统更灵活,可以在不修改调用者代码的情况下新增或更改命令。

优缺点

优点
  1. 降低发送者和接收者之间的耦合
    • 发送者只需要知道如何发送命令,而不需要了解接收者的具体实现。
  2. 容易扩展新命令
    • 可以很容易地增加新的具体命令类。
  3. 支持撤销和重做操作
    • 可以通过保存历史命令实现撤销和重做功能。
缺点
  1. 可能会导致过多的具体命令类
    • 如果系统中命令较多,可能会导致类的数量增加。

类图

+----------------+         +------------------+
|   Command      |-------->|   ConcreteCommand|
+----------------+         +------------------+
| + execute()    |         | + execute()      |
+----------------+         +------------------+
|                |         |
+----------------+         ||+-------------------+--------+----------------+|                   |                 |                |
+---------------+ +-----------------+ +----------------+ +--------------+
|     Receiver  | |  LightOnCommand | |  LightOffCommand| | ...          |
+---------------+ +-----------------+ +----------------+ +--------------+
| + action()    | | + execute()      | | + execute()     | | + execute()   |
+---------------+ +-----------------+ +----------------+ +--------------+

总结

命令模式允许将请求封装成对象,使得请求的发送者和接收者解耦,并支持撤销、重做等操作。通过命令模式,可以轻松扩展新的命令,支持排队、记录日志等功能,是一种非常有用的设计模式。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Mac安装stable diffusion 工具
  • 封装网络请求 鸿蒙APP HarmonyOS ArkTS
  • 把关键字当作列名 不报错的方法 (数据库)
  • 大数据技术基础
  • Laravel表单验证的艺术:精细控制数据的入口
  • React遍历tree结构,获取所有的id,切换自动展开对应层级
  • Ajax从零到实战
  • Log4j的原理及应用详解(三)
  • 在GPU上运行PyTorch
  • MVC之 IHttpModule管道模型《二》
  • C++的关键字const
  • 飞睿智能UWB Tag蓝牙防丢器标签,宠物安全新升级,5cm精准定位测距不迷路
  • 杭州汽修元宇宙
  • 芋道项目发版后报错: jt is not a function...
  • VBA学习(20):一批简单的Excel VBA编程问题解答
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • Date型的使用
  • Flex布局到底解决了什么问题
  • Lsb图片隐写
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • 什么是Javascript函数节流?
  • 使用 @font-face
  • 一些css基础学习笔记
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • ​1:1公有云能力整体输出,腾讯云“七剑”下云端
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • (1)Nginx简介和安装教程
  • (C语言)fgets与fputs函数详解
  • (Java数据结构)ArrayList
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (十六)一篇文章学会Java的常用API
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • .DFS.
  • .net Signalr 使用笔记
  • @selector(..)警告提示
  • @vue/cli脚手架
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [Android Pro] AndroidX重构和映射
  • [C#]C# winform部署yolov8目标检测的openvino模型
  • [C#7] 1.Tuples(元组)
  • [C#学习笔记]LINQ
  • [C++] sqlite3_get_table 的使用
  • [C和指针].(美)Kenneth.A.Reek(ED2000.COM)pdf
  • [Docker]四.Docker部署nodejs项目,部署Mysql,部署Redis,部署Mongodb
  • [Enterprise Library]调用Enterprise Library时出现的错误事件之关闭办法
  • [E单调栈] lc2487. 从链表中移除节点(单调栈+递归+反转链表+多思路)
  • [Firefly-Linux] RK3568 pca9555芯片驱动详解
  • [GUET-CTF2019]encrypt
  • [GXYCTF2019]禁止套娃1
  • [hihocoder1395] 最大权闭合子图
  • [Linux]进程间通信(进程间通信介绍 | 匿名管道 | 命名管道)
  • [MySQL]视图索引以及连接查询案列