命令模式(Command Pattern)是一种行为型设计模式,它将请求封装为对象,从而允许用户使用不同的请求、队列或日志来参数化对象。命令模式还支持可撤销的操作。
Command(抽象命令):定义了执行操作的接口。
ConcreteCommand(具体命令):实现抽象命令接口,绑定一个接收者对象,并调用其方法。
Receiver(接收者):执行与命令相关的业务逻辑。
Invoker(调用者):负责调用命令对象的执行方法。
Client(客户端):创建具体命令对象,并设置其接收者。
解耦:将请求的发送者和接收者解耦,使两者不直接依赖。
扩展性:可以很容易地添加新的命令类,而无需修改现有代码。
支持撤销操作:通过保存命令对象的状态,可以实现撤销和重做功能。
队列请求:可以将多个命令放入队列中,按顺序执行。
GUI 应用程序:如按钮点击事件、菜单项选择等。
事务处理:需要支持撤销和重做的操作。
宏命令:将多个命令组合成一个命令。
远程调用:将请求封装为命令对象,通过网络传递到远程服务器执行。
以下是一个简单的例子,展示如何使用命令模式控制家用电器(如灯和电视)的开关。
package main
import "fmt"
// 接收者:家用电器
type Device interface {
TurnOn()
TurnOff()
}
// 具体接收者:灯
type Light struct{}
func (l *Light) TurnOn() {
fmt.Println("Light is ON")
}
func (l *Light) TurnOff() {
fmt.Println("Light is OFF")
}
// 具体接收者:电视
type TV struct{}
func (t *TV) TurnOn() {
fmt.Println("TV is ON")
}
func (t *TV) TurnOff() {
fmt.Println("TV is OFF")
}
// 抽象命令
type Command interface {
Execute()
Undo()
}
// 具体命令:打开设备
type OnCommand struct {
device Device
}
func (oc *OnCommand) Execute() {
oc.device.TurnOn()
}
func (oc *OnCommand) Undo() {
oc.device.TurnOff()
}
// 具体命令:关闭设备
type OffCommand struct {
device Device
}
func (ofc *OffCommand) Execute() {
ofc.device.TurnOff()
}
func (ofc *OffCommand) Undo() {
ofc.device.TurnOn()
}
// 调用者:遥控器
type RemoteControl struct {
onCommand Command
offCommand Command
}
func (rc *RemoteControl) SetCommand(onCommand, offCommand Command) {
rc.onCommand = onCommand
rc.offCommand = offCommand
}
func (rc *RemoteControl) PressOnButton() {
rc.onCommand.Execute()
}
func (rc *RemoteControl) PressOffButton() {
rc.offCommand.Execute()
}
func (rc *RemoteControl) PressUndoButton() {
if rc.onCommand != nil {
rc.onCommand.Undo()
} else if rc.offCommand != nil {
rc.offCommand.Undo()
}
}
func main() {
// 创建接收者
light := &Light{}
tv := &TV{}
// 创建命令
lightOn := &OnCommand{device: light}
lightOff := &OffCommand{device: light}
tvOn := &OnCommand{device: tv}
tvOff := &OffCommand{device: tv}
// 创建调用者
remote := &RemoteControl{}
// 设置灯的命令
remote.SetCommand(lightOn, lightOff)
fmt.Println("Pressing Light Buttons:")
remote.PressOnButton()
remote.PressOffButton()
remote.PressUndoButton()
fmt.Println("\nPressing TV Buttons:")
// 设置电视的命令
remote.SetCommand(tvOn, tvOff)
remote.PressOnButton()
remote.PressOffButton()
remote.PressUndoButton()
}