首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Golang语言情怀-第27期 Go 语言设计模式 命令

Golang语言情怀-第27期 Go 语言设计模式 命令

作者头像
李海彬
发布2021-02-05 16:20:06
发布2021-02-05 16:20:06
5050
举报
文章被收录于专栏:Golang语言社区Golang语言社区

命令模式

命令模式是一种数据驱动的设计模式,它属于行为模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的何时的对象,并把该命令传给相应的对象,该对象执行命令。

介绍:

意图:将一个请求封装成一个对象,从而使得您可以用不同的请求对客户进行参数化。

主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合关系,但某些场合,比如需要对行为进行记录、撤销或重做、事物等处理时,这种无法抵御变化的紧耦合的设计就不太合适。

如何解决:通过调用者调用接受者执行命令,顺序:调用者➡️接收者➡️命令。

优点:降低了系统的耦合度、新的命令可以很容易添加到系统中去

缺点:使用命令模式可能会导致某些系统有过多的具体命令类。

使用场景:认为是命令的地方都可以使用命令模式。

实现

我们首先创建作为命令的接口Order,然后创建作为请求的Stock类。实体命令类BuyStock和SellStock,实现了Order接口,将执行实际的命令处理。创建作为调用对象的类Broker,它接受订单并能下订单。

Broker对象使用命令模式,基于命令的类型确定哪个对象执行哪个命令。CommandPatternDemo,我们的演示类使用Broker类来演示命令模式。

代码语言:javascript
复制
type command interface {
    execute()
}

//开灯命令
type lightOnCommand struct {
    mLight *light //命令对象包含的特定接收者
}

//返回一个开灯命令的实例对象
func NewLightOnCommand(light *light) command {
    return &lightOnCommand{mLight: light}
}

//实现接口方法捆绑接收者的动作
func (this *lightOnCommand) execute() {
    if !this.mLight.isOn() {
        this.mLight.setOn(true) //开灯
    }
}

//关灯命令
type lightOffCommand struct {
    mLight *light
}

func NewLightOffCommand(light *light) command {
    return &lightOffCommand{mLight: light}
}

func (this *lightOffCommand) execute() {
    if this.mLight.isOn() {
        this.mLight.setOn(false) //关灯
    }
}
代码语言:javascript
复制
type receiver interface {
    setOn(bool) //true:开/false:关
    isOn() bool
}

//打开命令                                                 
type onCommand struct {
    receiver Receiver
}

//创建打开命令的实例,为该实例捆绑接收者                          
func NewOnCommand(receiver Receiver) command {
    return &onCommand{receiver}
}

//被封装的“请求”                                          
func (this *onCommand) execute() {
    if !this.receiver.isOn() {
        this.receiver.setOn(true) //打开
    }
}

//关闭命令                                           
type offCommand struct {
    receiver Receiver
}

func NewOffCommand(receiver Receiver) command {
    return &offCommand{receiver}
}

func (this *offCommand) execute() {
    if !this.receiver.isOn() {
        this.receiver.setOn(false) //关闭
    }
}
代码语言:javascript
复制
type RemoteController struct {
    slot command
}

func (this *RemoteController) SetCommand(command command) {
    this.slot = command
}

func (this *RemoteController) ButtonPressed() {
    if this.slot == nil {
        panic("Do not assign command to Controller's slot!")
    }
    this.slot.execute()
}
代码语言:javascript
复制
const (
    LIGHT = " light"
    DOOR  = " door"
)

//接收者接口        
type Receiver interface {
    setOn(bool)
    isOn() bool
}

type light struct {
    name string
    on   bool
}

func (this *light) setOn(b bool) {
    if b {
        fmt.Println(this.name + LIGHT + " is on.")
    } else {
        fmt.Println(this.name + LIGHT + " is off.")
    }
    this.on = b
}

func (this *light) isOn() bool {
    return this.on
}

func NewRoomLight() Receiver {
    return &light{"Room", false}
}

func NewTableLampLight() Receiver {
    return &light{"Table Lamp", false}
}

type door struct {
    name string
    on   bool
}

func (this *door) setOn(b bool) {
    if b {
        fmt.Println(this.name + DOOR + " is opened.")
    } else {
        fmt.Println(this.name + DOOR + " is closed.")
    }
    this.on = b
}

func (this *door) isOn() bool {
    return this.on
}

func NewGarageDoor() Receiver {
    return &door{"Garage", false}
}

func NewKitchenDoor() Receiver {
    return &door{"Kitchen", false}
}
代码语言:javascript
复制
func main() {
        ctrl := new(command.RemoteController)
    var roomLight, garageDoor command.Receiver

    roomLight = command.NewRoomLight()
    garageDoor = command.NewGarageDoor()

    cmdOn := command.NewOnCommand(roomLight)
    cmdOff := command.NewOffCommand(garageDoor)

    ctrl.SetCommand(cmdOn)
    ctrl.ButtonPressed()
    ctrl.SetCommand(cmdOff)
    ctrl.ButtonPressed()
}

参考资料:

Go语言设计模式-命令

https://blog.csdn.net/weixin_40165163/article/details/90814345

设计模式

https://blog.51cto.com/liuxp0827/1356520

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言情怀 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 命令模式
  • 介绍:
  • 实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档