ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GoLang设计模式08 - 命令模式

2022-01-26 18:36:02  阅读:204  来源: 互联网

标签:tv 08 GoLang go 指令 command Receiver device 设计模式


命令模式是一种行为型模式。它建议将请求封装为一个独立的对象。在这个对象里包含请求相关的全部信息,因此可以将其独立执行。

在命令模式中有如下基础组件:

  • Receiver:唯一包含业务逻辑的类,命令对象会将请求传递给它,请求的最终处理者
  • Command:组装了一个Receiver成员,并绑定实现了Receiver的一个特定行为
  • Invoker:请求的发送者,组装了Command成员,通过调用Command实例的execute()方法来触发对应的指令
  • Client:通过将Receiver实例传递给Command构造器来创建Command对象,之后会将创建的对象同Invoker绑定。

还是通过一个具体的场景来理解下命令模式是怎样运行的。以打开电视这个行为举例,我们可以通过如下方式打开电视:

  1. 通过遥控器开关打开电视
  2. 通过电视上的开关打开电视

在这个场景中,我们有一个指令(Command)是“打开电视”,指令的接收者(Receiver)当然就是电视(TV)了,当我们执行(execute)指令时,相关指令就会让电视打开(TV.on())。

再明确下这个场景中的所有组件:

  • ReceiverTV
  • Command只有一个,是打开电视:ON,这个指令需要组装TV成员
  • Invoker是遥控打开或开关打开这两种方式,它们会组装ON指令成员。

注意,这里我们将“打开电视”这个请求封装到了一个ON指令对象中,这个指令可以被不同的调用方调用。在ON指令中嵌入了TV实例,可以被独立执行。

再举个例子,想想PhotoShop这个软件,在PhotoShop中,要执行“保存”操作有三种方式:

  1. 从右键菜单中执行保存
  2. 从工具栏菜单中执行保存
  3. 使用Ctrl+S快捷键

这三种操作做的是同一件事情:保存正在编辑的图片。这三种操作的保存行为可以抽象为一个“Save”指令对象,而正在被编辑的图片就可以视为一个Receiver

现在总结下使用命令对象的好处:

  1. 抽象出了潜藏的真实业务逻辑,并将其和具体的操作解耦
  2. 不需要为每个调用者创建不同的处理器
  3. 指令对象包含了执行所需的全部信息,因此它也适用于需要延迟执行的场景

看下UML类图:

  1. 注意下Invoker是怎样嵌入指令对象的。当一个请求发送给Invoker的时候,Invoker会将这个请求传递给其嵌入的命令对象。
  2. 所有具体的指令类都会组装一个Receiver成员属性。

代码如下:

代码如下:

command.go(指令 interface)

1 2 3 type command interface {     execute() }

device.go(Receiver interface)

1 2 3 4 type device interface {     on()     off() }

tv.go(Receiver)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import "fmt"   type tv struct {     isRunning bool }   func (t *tv) on() {     t.isRunning = true     fmt.Println("Turning tv on") }   func (t *tv) off() {     t.isRunning = false     fmt.Println("Turning tv off") }

onCommand.go(指令)

1 2 3 4 5 6 7 type onCommand struct {     device device }   func (c *onCommand) execute() {     c.device.on() }

offCommand.go(指令)

1 2 3 4 5 6 7 type offCommand struct {     device device }   func (c *offCommand) execute() {     c.device.off() }

button.go(Invoker,开关打开电视)

1 2 3 4 5 6 7 type button struct {     command command }   func (b *button) press() {     b.command.execute() }

main.go(Client)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 func main() {       tv := &tv{}     onCommand := &onCommand{         device: tv,     }       offCommand := &offCommand{         device: tv,     }       onButton := &button{         command: onCommand,     }       onButton.press()       offButton := &button{         command: offCommand,     }     offButton.press() }

运行结果:

1 2 Turning tv on Turning tv off

代码已上传至GitHub:github / zhyea / command 

END!

 

 


仅是学习笔记,难免出错,望不吝指点   转 https://www.cnblogs.com/amunote/p/15362468.html

标签:tv,08,GoLang,go,指令,command,Receiver,device,设计模式
来源: https://www.cnblogs.com/wl-blog/p/15847761.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有