一、什么是命令(Command)模式

命令模式是行为型设计模式的一种,其目的是将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化。与另一种将每种命令与调用命令的对象结合形成一个专有类的方式相比,命令模式的优点有将调用操作的对象与知道如何实现该操作的对象解耦,增加新的命令不需要修改现有的类。

命令模式的结构如下:



参与者有:

1.Invoker请求者

要求该命令执行这个请求,即命令的调用者

2.Command接口

3.ConcreteCommand具体接口

4.Receiver接收者

命令的相关操作的实际实施者

5.Client

协作过程:

1.Client创建一个ConcreteCommand对象并指定它的Receiver对象

2.某Invoker对象存储该ConcreteCommand对象

3.该Invoker通过调用Command对象的Excute操作来提交一个请求。若该命令是可撤消的,ConcreteCommand就在执行Excute操作之前存储当前状态以用于取消该命令

4.ConcreteCommand对象对调用它的Receiver的一些操作以执行该请求

二、go-redis command相关代码

// commands.go

// Invoker请求者接口
type Cmdable interface {
Pipeline() Pipeliner
Pipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error)
TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error)
TxPipeline() Pipeliner
Command(ctx context.Context) *CommandsInfoCmd
ClientGetName(ctx context.Context) *StringCmd
// ...
// 和所有Redis命令的相关方法
} // cmdable实现了Cmdable接口
type cmdable func(ctx context.Context, cmd Cmder) error
func (c cmdable) Echo(ctx context.Context, message interface{}) *StringCmd {
cmd := NewStringCmd(ctx, "echo", message)
_ = c(ctx, cmd)
return cmd
}

这里值得一提的是cmdable是一个函数类型,func(ctx context.Context, cmd Cmder) error

并且每个cmdable方法里都会有_ = c(ctx, cmd),也就是如何去调用cmd在这里还没有明确写出

再回头看redis.go,会发现这样一段代码

type Client struct {
*baseClient
cmdable
hooks
ctx context.Context
} func NewClient(opt *Options) *Client {
opt.init() c := Client{
baseClient: newBaseClient(opt, newConnPool(opt)),
ctx: context.Background(),
}
c.cmdable = c.Process //划线 return &c
}

c.cmdable = c.Process这行指定了请求如何调用Command的

在ctrl+左键追踪几层后,会在redis.go里找到调用的具体过程

// redis.go
func (c *baseClient) process(ctx context.Context, cmd Cmder) error {
......
err := cn.WithWriter(ctx, c.opt.WriteTimeout, func(wr *proto.Writer) error {
eturn writeCmd(wr, cmd)
}) err = cn.WithReader(ctx, c.cmdTimeout(cmd), cmd.readReply)
......

然后再去找Command,这边就比较清晰了,都在command.go中

// command.go

// Command接口
type Cmder interface {
Name() string
FullName() string
Args() []interface{}
String() string
stringArg(int) string
firstKeyPos() int8
setFirstKeyPos(int8) readTimeout() *time.Duration
readReply(rd *proto.Reader) error SetErr(error)
Err() error
} // 还有许多Cmder的具体实现,其中一个实现的部分代码如下
type XPendingExtCmd struct {
baseCmd
val []XPendingExt
}
func (cmd *XPendingExtCmd) Val() []XPendingExt {
return cmd.val
}

在这里没有看到Receiver,是因为每个Cmder实现都自己实现了所有功能,根本不需要额外的接收者对象。

三、总结

有时必须向某对象提交请求,但并不知道关于被请求的操作或请求的接受者的任何信息。这个时候可以用到命令模式,通过将请求本身变成一个对象来使工具箱对象可向未指定的应用对象提出请求。

命令模式与go-redis command设计的更多相关文章

  1. c#设计模式系列:命令模式(Command Pattern)

    引言 命令模式,我感觉"命令"就是任务,执行了命令就完成了一个任务.或者说,命令是任务,我们再从这个名字上并不知道命令的发出者和接受者分别是谁,为什么呢?因为我们并不关心他们是谁, ...

  2. 设计模式---行为变化模式之命令模式(Command)

    前提:行为变化模式 在组件的构建过程中,组建行为的变化经常导致组件本身剧烈的变化.“行为变化”模式将组件的行为和组件本身进行解耦,从而支持组件的变化,实现两者之间的松耦合. 类中非虚函数和静态函数方法 ...

  3. 命令模式(head first 设计模式5)

    一.命令模式定义 命令大家都不会陌生,那么在开始命令模式之前,可以想象一下生活中的命令模式的特点: 如老板命令你完成一个OA项目是一个命令,接着看看其特点: 1.在上面的命令中,命令的执行者肯定是聪明 ...

  4. C#设计模式学习笔记:(14)命令模式

    本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7873322.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第二个模式--命 ...

  5. OOP设计模式[JAVA]——04命令模式

    命令模式 命令模式的意图 命令模式属于对象的行为模式.别名又叫:Action或Transaction. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请求 ...

  6. 设计模式(六):控制台中的“命令模式”(Command Pattern)

    今天的博客中就来系统的整理一下“命令模式”.说到命令模式,我就想起了控制台(Console)中的命令.无论是Windows操作系统(cmd.exe)还是Linux操作系统(命令行式shell(Comm ...

  7. (十三)WebGIS中工具栏的设计之命令模式

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 从这一章节开始我们将正式进入WebGIS的工具栏中相关功能的 ...

  8. C++设计模式-Command命令模式

    Command命令模式作用:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 由于“行为请求者”与“行为实现者”的紧耦合,使用命令模式 ...

  9. 深入浅出设计模式——命令模式(Command Pattern)

    模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请 ...

随机推荐

  1. 解决因缺少驱动程序,导致“未在本地计算机上注册microsoft.ace.12.0”异常

    写了一个winform程序,功能是选择一个excel表格,把里面的内容写进sqlite数据库中,在本地测试没问题,但是在其他电脑上就会报错"未在本地计算机上注册microsoft.ace.1 ...

  2. 我是如何用go-zero 实现一个中台系统的

    最近发现golang社区里出了一个新星的微服务框架,来自好未来,光看这个名字,就很有奔头,之前,也只是玩过go-micro,其实真正的还没有在项目中运用过,只是觉得 微服务,grpc 这些很高大尚,还 ...

  3. XSS攻击与防止

    1.XSS又称CSS, cross sitescript, 跨站脚本攻击,是web程序中常见的漏洞 XSS属于被动式且用于客户端的攻击方式 XSS攻击类似于SQL注入攻击,攻击之前,我们先找到一个存在 ...

  4. SQL注入----盲注总结

    参考文章:https://mp.weixin.qq.com/s?__biz=MzIzMTc1MjExOQ==&mid=2247490388&idx=1&sn=c677837d7 ...

  5. linux里用户权限:~$,/$,~#,/#的区别与含义

    $表明是非root用户登录,#表示是root用户登录,它们是终端shell的命令提示符几种常用终端的命令提示符 BASH:  root账户: # ,非root账户: $KSH:  root账户: # ...

  6. CVE-2019-2618任意文件上传漏洞复现

    CVE-2019-2618任意文件上传漏洞复现 漏洞介绍: 近期在内网扫描出不少CVE-2019-2618漏洞,需要复测,自己先搭个环境测试,复现下利用过程,该漏洞主要是利用了WebLogic组件中的 ...

  7. 拥抱云原生,如何将开源项目用k8s部署?

    微信搜索[阿丸笔记],关注Java/MySQL/中间件各系列原创实战笔记,干货满满. k8s以及云原生相关概念近年来一直比较火热,阿丸最近搞了个相关项目,小结一下. 本文将重点分享阿里开源项目otte ...

  8. 30G 上亿数据的超大文件,如何快速导入生产环境?

    Hello,大家好,我是楼下小黑哥~ 如果给你一个包含一亿行数据的超大文件,让你在一周之内将数据转化导入生产数据库,你会如何操作? 上面的问题其实是小黑哥前段时间接到一个真实的业务需求,将一个老系统历 ...

  9. 3.mysql小表驱动大表的4种表连接算法

    小表驱动大表 1.概念 驱动表的概念是指多表关联查询时,第一个被处理的表,使用此表的记录去关联其他表.驱动表的确定很关键,会直接影响多表连接的关联顺序,也决定了后续关联时的查询性能. 2.原则 驱动表 ...

  10. Spring Cloud 各个组件角色简介

    概述 SpringCloud 是一个全家桶式的技术栈,包含了很多组件:包含 Eureka.Ribbon.Feign.Zuul .Hystrix等.每个组件完成对应的功能 组件介绍 - 服务发现 Eur ...