设计模式-命令模式

代码星河引
• 阅读 1612

当我们的代码中"方法的请求者" 和 "方法的实现者" 之间存在较为紧密的耦合的时候,这段代码的后续维护会变得很困难。如果我们想对方法进行回滚 撤销等操作的话就会很困难;使用命名模式可解决这一问题。

在现实生活中,这样的例子也很多,例如,电视机遥控器(命令发送者)通过按钮(具体命令)来遥控电视机(命令接收者),还有计算机键盘上的“功能键”等。

命令(Command)模式的定义如下:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。 命令模式的优点:

  • 降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。
  • 增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,对扩展比较灵活。
  • 可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。
  • 方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。

模式结构

命令模式包含以下主要角色:

  • 抽象命令类(Command)角色:声明执行命令的接口,拥有执行命令的抽象方法 execute()。
  • 具体命令角色(Concrete Command)角色:是抽象命令类的具体实现类,它拥有接收者对象,并通过调用接收者的功能来完成命令要执行的操作。
  • 实现者/接收者(Receiver)角色:执行命令功能的相关操作,是具体命令对象业务的真正实现者。
  • 调用者/请求者(Invoker)角色:是请求的发送者,它通常拥有很多的命令对象,并通过访问命令对象来执行相关请求,它不直接访问接收者。

源码导读

在springboot的redis客户端的redisTemplate类中就有使用到命令模式。 在命令模式中,有三个重要的角色,我们只要找到这三个重要的角色就能捋清命令模式的的脉络了,这三个角色是“客户端”,“命令”,“服务端”。 在RedisTemplate 中存在一个execute 方法,这个就是服务端执行命令的方法,而它的方法参数RedisCallback 就是命令类了,我们看看如何在客户端构造一个命令给RedisTemplate去执行。

public boolean lockByLua(String key, String value, Long expiredTime){
        String strExprie = String.valueOf(expiredTime);
        StringBuilder sb = new StringBuilder();
        sb.append("if redis.call(\"setnx\",KEYS[1],ARGV[1])==1 ");
        sb.append("then ");
        sb.append("    redis.call(\"pexpire\",KEYS[1],KEYS[2]) ");
        sb.append("    return 1 ");
        sb.append("else ");
        sb.append("    return 0 ");
        sb.append("end ");
        String script = sb.toString();
        RedisCallback<Boolean> callback = (connection) -> {
            return connection.eval(script.getBytes(), ReturnType.BOOLEAN, 2, key.getBytes(Charset.forName("UTF-8")),strExprie.getBytes(Charset.forName("UTF-8")), value.getBytes(Charset.forName("UTF-8")));
        };
        Boolean execute = stringRedisTemplate.execute(callback);
        return execute;
    }

以上代码是通过stringRedisTemplate执行一个lua脚本,lockByLua就是客户端的方法。对于命令模式而言,命令执行方法都是按照executeXXX这样的格式命名。
点击关注我的博客

点赞
收藏
评论区
推荐文章
3A网络 3A网络
2年前
Golang 常见设计模式之单例模式
之前我们已经看过了Golang常见设计模式中的装饰和选项模式,今天要看的是Golang设计模式里最简单的单例模式。单例模式的作用是确保无论对象被实例化多少次,全局都只有一个实例存在。根据这一特性,我们可以将其应用到全局唯一性配置、数据库连接对象、文件访问对象等。Go语言实现单例模式的方法有很多种,下面我们就一起来看一下。饿汉式饿汉式实现单例模式非
一分钟学会、三分钟上手、五分钟应用,快速上手责任链框架详解 | 京东云技术团队
责任链模式是开发过程中常用的一种设计模式,在SpringMVC、Netty等许多框架中均有实现。我们日常的开发中如果要使用责任链模式,通常需要自己来实现,但自己临时实现的责任链既不通用,也很容易产生框架与业务代码耦合不清的问题,增加CodeReview的成本。
Stella981 Stella981
3年前
Centos 7 忘记管理员root密码的解决办法
文章目录方法一:通过救援模式重置root密码方法二:使用单用户模式重置root密码当虚拟机多的时候经常可能会忘记root密码,这时候我们就会去虫子root密码这里介绍两种重置Centos7系统root密码的方法方法一:通过救援模式重置root密码1、在系统开机
Wesley13 Wesley13
3年前
vivo Y71的USB调试模式在哪里,开启vivo Y71USB调试模式的流程
就在我们使用安卓手机通过数据线连接到电脑的时候,如果手机没有开启usb开发者调试模式,电脑则没能成功识别我们的手机,部分工具也没能正常使用,此情况我们需要找解决方法将手机的usb开发者调试模式打开,以下内容我们讲解vivoY71如何开启usb开发者调试模式的方法。首先,在vivoY71应用程序界面点中“设置”ICON,进入vivoY71系统“设置”
Stella981 Stella981
3年前
Guava库学习:学习Guava EventBus(一)EventBus
  在软件开发过程中,对象信息的分享以及相互直接的协作是必须的,困难在于确保对象之间的沟通是有效完成的,而不是拥有成本高度耦合的组件。当对象对其他组件的责任有太多的细节时,它被认为是高度耦合的。当一个应用程序有高度的耦合,维护将变得非常具有挑战,任何变化都将带来涟漪效应。为了解决这一类的软件设计问题,我们就需要基于事件的编程。本篇,我们就来学习Guava
Wesley13 Wesley13
3年前
NO.147 维护禅道:初始化管理脚本。
禅道底层的zentaoPHP框架提供了命令行的操作入口,通过这个功能,可以通过命令行实现对禅道的各种配置或者维护工作。在继续阅读下面文章之前,请大家了解这篇文档:http://devel.cnezsoft.com/book/extension/34\_cli.html(https://www.oschina.net/action/GoToLink?url
Wesley13 Wesley13
3年前
C#设计模式 —— 工厂模式
。  工厂模式同样是项目中最常用的设计模式,工厂模式中又分为简单工厂,工厂方法,抽象工厂。下面我们由简单的开始逐一介绍。1.简单工厂模式  简单工厂又被称为静态工厂,在设计模式中属于创建型模式。主要解决的问题是封装了实例化的过程,通过传入参数来获不同实例。下面我们举一个项目中可能会用到的例子。  假设我们程序的数据保存在几个不同
Wesley13 Wesley13
3年前
4种常见的 PHP 设计模式
工厂模式在大型系统中,许多代码依赖于少数几个关键类。需要更改这些类时,可能会出现困难。例如,假设您有一个从文件读取的 User 类。您希望将其更改为从数据库读取的其他类,但是,所有的代码都引用从文件读取的原始类。这时候,使用工厂模式会很方便。_工厂模式_ 是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不直接使用 
Easter79 Easter79
3年前
SwiftUI 跨组件数据传递
作者:Cyandev,iOS和MacOS开发者,目前就职于字节跳动0x00前言众所周知,SwiftUI的开发模式与React、Flutter非常相似,即都是声明式UI,由数据驱动(产生)视图,视图也会与数据自动保持同步,框架层会帮你处理“绑定”的问题。在声明式UI中不存在命令式地让一个视图变成xxx
文盘Rust——子命令提示,提高用户体验 | 京东云技术团队
上次我们聊到CLI的领域交互模式。在领域交互模式中,可能存在多层次的子命令。在使用过程中如果全评记忆的话,命令少还好,多了真心记不住。频繁help也是个很麻烦的事情。如果每次按'tab'键就可以提示或补齐命令是不是很方便呢。这一节我们就来说说'autoco
看动画,轻松学习23种C++设计模式完结无密
C设计模式深度解析:提升代码质量与可维护性的关键在C软件开发中,设计模式作为一种经过验证的软件开发方法,被广泛用于解决常见的设计问题,提高代码的可读性、可维护性和可扩展性。本文将深入探讨C中几种常用的设计模式,分析其原理、应用场景及实现方式,以