Go设计模式之命令模式

161 阅读2分钟

在Go语言中,命令模式是一种行为型设计模式,用于将一个操作请求与其相应的处理程序相分离。这种模式允许请求的发送者和接收者彼此独立,并能够从系统中移除命令的调用者。

命令模式的组成部分

命令模式主要包含如下部分:

  1. 命令接口(Command Interface):定义了执行命令所需要的操作
  2. 具体命令(Concrete Command):实现了命令接口,封装了命令的操作
  3. 命令发起者(Invoker):将请求封装为一个具体命令对象,并发出请求
  4. 命令接收者(Receiver):负责命令的实现,处理命令

示例:实现一个命令模式

假设我们正在开发一个简单的远程遥控器,这个遥控器可以控制多个设备,包括电视、音响和灯。我们要设计一个命令模式来实现这个遥控器的控制。

首先,我们需要定义命令接口 Command

type Command interface {
    Execute()
}

然后,我们实现具体的命令,例如控制电视的命令 TVOnCommandTVOffCommand

type TVOnCommand struct {
    TV *TV // 电视设备
}

func (c *TVOnCommand) Execute() {
    c.TV.On()
}

type TVOffCommand struct {
    TV *TV // 电视设备
}

func (c *TVOffCommand) Execute() {
    c.TV.Off()
}

接下来,我们实现命令接收者 TV

type TV struct {
    isOn bool
}

func (tv *TV) On() {
    tv.isOn = true
    fmt.Println("TV is On")
}

func (tv *TV) Off() {
    tv.isOn = false
    fmt.Println("TV is Off")
}

现在我们可以定义遥控器的命令发起者 RemoteControl

type RemoteControl struct {
    slot Command
}

func (r *RemoteControl) SetCommand(command Command) {
    r.slot = command
}

func (r *RemoteControl) PressButton() {
    r.slot.Execute()
}

我们可以在主函数中实现这些类的实例化,并设置控制电视的命令:

func main() {
    remoteControl := &RemoteControl{}

    tv := &TV{}
    tvOnCommand := &TVOnCommand{tv}
    tvOffCommand := &TVOffCommand{tv}

    remoteControl.SetCommand(tvOnCommand)
    remoteControl.PressButton()
    remoteControl.SetCommand(tvOffCommand)
    remoteControl.PressButton()
}

当运行这段代码时,我们可以看到遥控器成功地控制了电视的开关。

结论

命令模式是一种实现请求和操作解耦的设计模式。在Go语言中,这种模式能够简化代码结构,使代码更加可维护和可扩展。如果你在开发一个需要控制多种设备的应用程序,那么命令模式是一个非常有用的设计模式。

完整代码

package main

import "fmt"

type Command interface {
   Execute()
}

type TVOnCommand struct {
   TV *TV // 电视设备
}

func (c *TVOnCommand) Execute() {
   c.TV.On()
}

type TVOffCommand struct {
   TV *TV // 电视设备
}

func (c *TVOffCommand) Execute() {
   c.TV.Off()
}

type TV struct {
   isOn bool
}

func (tv *TV) On() {
   tv.isOn = true
   fmt.Println("TV is On")
}

func (tv *TV) Off() {
   tv.isOn = false
   fmt.Println("TV is Off")
}

type RemoteControl struct {
   slot Command
}

func (r *RemoteControl) SetCommand(command Command) {
   r.slot = command
}

func (r *RemoteControl) PressButton() {
   r.slot.Execute()
}

func main() {
   remoteControl := &RemoteControl{}

   tv := &TV{}
   tvOnCommand := &TVOnCommand{tv}
   tvOffCommand := &TVOffCommand{tv}

   remoteControl.SetCommand(tvOnCommand)
   remoteControl.PressButton()
   remoteControl.SetCommand(tvOffCommand)
   remoteControl.PressButton()
}