模式定义
将一个请求(行为)封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作
类图
要点总结
- Command模式的根本目的在于将“行为请求者”与“行为实现者”解耦,在面向对象语言中,常见的实现手段是“将行为抽象为对象”
- 实现Command接口的具体命令对象ConcreteCommand有时候根据需要可能会保存一些额外的状态信息,通过使用Composite模式,可以将多个“命令”封装为一个“复合命令”MacroCommand
Go语言代码实现
命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化。该模式允许将请求的发送者和接收者解耦。
在命令模式中,请求发送者称为调用者(Invoker),请求接收者称为接收者(Receiver),将请求封装成对象的称为命令(Command)。通过将命令对象传递给调用者,调用者可以在需要的时候触发命令执行,而无需知道具体的接收者或执行细节。
以下是一个简单的例子来说明命令模式的应用:
package main
import "fmt"
// Command 命令接口
type Command interface {
Execute()
}
// Receiver 接收者
type Receiver struct {
name string
}
func NewReceiver(name string) *Receiver {
return &Receiver{
name: name,
}
}
func (r *Receiver) Action() {
fmt.Printf("%s is performing action\n", r.name)
}
// ConcreteCommand 具体命令
type ConcreteCommand struct {
receiver *Receiver
}
func NewConcreteCommand(receiver *Receiver) *ConcreteCommand {
return &ConcreteCommand{
receiver: receiver,
}
}
func (c *ConcreteCommand) Execute() {
c.receiver.Action()
}
// Invoker 调用者
type Invoker struct {
command Command
}
func NewInvoker() *Invoker {
return &Invoker{}
}
func (i *Invoker) SetCommand(command Command) {
i.command = command
}
func (i *Invoker) ExecuteCommand() {
i.command.Execute()
}
func main() {
receiver := NewReceiver("Receiver")
command := NewConcreteCommand(receiver)
invoker := NewInvoker()
invoker.SetCommand(command)
invoker.ExecuteCommand()
}
在上述示例中,我们定义了命令接口Command,其中包含一个Execute方法。
接收者类Receiver表示实际执行操作的对象。在本例中,接收者具有一个name属性和一个Action方法,用于执行特定的操作。
具体命令类ConcreteCommand实现了命令接口,它持有一个接收者对象。在命令的Execute方法中,调用接收者的Action方法执行实际操作。
调用者类Invoker持有一个命令对象,并通过SetCommand方法设置命令。调用者的ExecuteCommand方法触发命令的执行,无需知道具体的接收者和执行细节。
在main函数中,我们创建了一个接收者对象receiver和一个具体命令对象command,并将其传递给调用者对象invoker。
最后,通过调用调用者的ExecuteCommand方法,命令被执行,接收者执行相应的操作。
通过命令模式,我们将请求的发送者和接收者解耦,使得发送者无需知道具体的接收者和操作,只需通过命令对象进行请求的触发。这提供了更大的灵活性和可扩展性。