Golang 设计模式 学习笔记(六)命令模式

前端之家收集整理的这篇文章主要介绍了Golang 设计模式 学习笔记(六)命令模式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

由于最近一直在学习Golang,所以从本节起,所有设计模式学习笔记中的源码都由Golang来完成~

命令模式:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

仔细看这个定义,我们知道一个命令对象通过在特定接收者(receiver)上绑定一组动作来封装一个请求。要达到这一点,命令对象将动作和接收者包进对象中。这个对象只暴露出一个execute()方法,当此方法调用的时候,接收者就会进行这些动作。从外面看,其他对象不知道究竟哪个接收者进行了哪些动作,只知道如果调用execute(),请求的目的就达到了。这些就实现了接收者和调用者的解耦合。

实现命令接口:

首先让所有的命令对象实现相同的包含一个方法的接口:

  1. type command interface {
  2. execute()
  3. }
  4. //开灯命令
  5. type lightOnCommand struct {
  6. mLight *light //命令对象包含的特定接收者
  7. }
  8. //返回一个开灯命令的实例对象
  9. func NewLightOnCommand(light *light) command {
  10. return &lightOnCommand{mLight: light}
  11. }
  12. //实现接口方法捆绑接收者的动作
  13. func (this *lightOnCommand) execute() {
  14. if !this.mLight.isOn() {
  15. this.mLight.setOn(true) //开灯
  16. }
  17. }
  18. //关灯命令
  19. type lightOffCommand struct {
  20. mLight *light
  21. }
  22. func NewLightOffCommand(light *light) command {
  23. return &lightOffCommand{mLight: light}
  24. }
  25. func (this *lightOffCommand) execute() {
  26. if this.mLight.isOn() {
  27. this.mLight.setOn(false) //关灯
  28. }
  29. }


我们应当考虑面向接口编程,大部分接收者都有简单的开关命令,故上述的代码可改为:

  1. type receiver interface {
  2. setOn(bool) //true:开/false:关
  3. isOn() bool
  4. }
  5. //打开命令
  6. type onCommand struct {
  7. receiver Receiver
  8. }
  9. //创建打开命令的实例,为该实例捆绑接收者
  10. func NewOnCommand(receiver Receiver) command {
  11. return &onCommand{receiver}
  12. }
  13. //被封装的“请求”
  14. func (this *onCommand) execute() {
  15. if !this.receiver.isOn() {
  16. this.receiver.setOn(true) //打开
  17. }
  18. }
  19. //关闭命令
  20. type offCommand struct {
  21. receiver Receiver
  22. }
  23. func NewOffCommand(receiver Receiver) command {
  24. return &offCommand{receiver}
  25. }
  26. func (this *offCommand) execute() {
  27. if !this.receiver.isOn() {
  28. this.receiver.setOn(false) //关闭
  29. }
  30. }


最后,再来看看客户端的代码

  1. type RemoteController struct {
  2. slot command
  3. }
  4. func (this *RemoteController) SetCommand(command command) {
  5. this.slot = command
  6. }
  7. func (this *RemoteController) ButtonPressed() {
  8. if this.slot == nil {
  9. panic("Do not assign command to Controller's slot!")
  10. }
  11. this.slot.execute()
  12. }


看看接收者们:

  1. const (
  2. LIGHT = " light"
  3. DOOR = " door"
  4. )
  5. //接收者接口
  6. type Receiver interface {
  7. setOn(bool)
  8. isOn() bool
  9. }
  10. type light struct {
  11. name string
  12. on bool
  13. }
  14. func (this *light) setOn(b bool) {
  15. if b {
  16. fmt.Println(this.name + LIGHT + " is on.")
  17. } else {
  18. fmt.Println(this.name + LIGHT + " is off.")
  19. }
  20. this.on = b
  21. }
  22. func (this *light) isOn() bool {
  23. return this.on
  24. }
  25. func NewRoomLight() Receiver {
  26. return &light{"Room",false}
  27. }
  28. func NewTableLampLight() Receiver {
  29. return &light{"Table Lamp",false}
  30. }
  31. type door struct {
  32. name string
  33. on bool
  34. }
  35. func (this *door) setOn(b bool) {
  36. if b {
  37. fmt.Println(this.name + DOOR + " is opened.")
  38. } else {
  39. fmt.Println(this.name + DOOR + " is closed.")
  40. }
  41. this.on = b
  42. }
  43. func (this *door) isOn() bool {
  44. return this.on
  45. }
  46. func NewGarageDoor() Receiver {
  47. return &door{"Garage",false}
  48. }
  49. func NewKitchenDoor() Receiver {
  50. return &door{"Kitchen",false}
  51. }


来测试下吧~:

  1. func main() {
  2. ctrl := new(command.RemoteController)
  3. var roomLight,garageDoor command.Receiver
  4. roomLight = command.NewRoomLight()
  5. garageDoor = command.NewGarageDoor()
  6. cmdOn := command.NewOnCommand(roomLight)
  7. cmdOff := command.NewOffCommand(garageDoor)
  8. ctrl.SetCommand(cmdOn)
  9. ctrl.ButtonPressed()
  10. ctrl.SetCommand(cmdOff)
  11. ctrl.ButtonPressed()
  12. }


wKioL1LxtPqQtdEsAABXMRft1Bk710.jpg

猜你在找的Go相关文章