模式定义
将一个请求(行为)封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作
类图
要点总结
- Command模式的根本目的在于将“行为请求者”与“行为实现者”解耦,在面向对象语言中,常见的实现手段是“将行为抽象为对象”
- 实现Command接口的具体命令对象ConcreteCommand有时候根据需要可能会保存一些额外的状态信息,通过使用Composite模式,可以将多个“命令”封装为一个“复合命令”MacroCommand
Go语言代码实现
工程目录
command.go
package Command
import "fmt"
type Person struct {
name string
cmd Command
}
type Command struct {
person *Person
method func()
}
func NewCommand (p *Person, method func()) Command {
return Command{
person: p,
method: method,
}
}
func (c *Command) Execute(){
c.method()
}
func NewPerson (name string, cmd Command) Person{
return Person{
name: name,
cmd: cmd,
}
}
func (p *Person) Buy() {
fmt.Println(fmt.Sprintf("%s is buying ", p.name))
p.cmd.Execute()
}
func (p *Person) Cook() {
fmt.Println(fmt.Sprintf("%s is cooking ", p.name))
p.cmd.Execute()
}
func (p *Person) Wash() {
fmt.Println(fmt.Sprintf("%s is washing ", p.name))
p.cmd.Execute()
}
func (p *Person) Listen() {
fmt.Println(fmt.Sprintf("%s is listening ", p.name))
p.cmd.Execute()
}
func (p *Person) Talk() {
fmt.Println(fmt.Sprintf("%s is talking ", p.name))
p.cmd.Execute()
}
command_test.go
package Command
import "testing"
func TestCommand_Execute(t *testing.T) {
laowang := NewPerson("wang", NewCommand(nil, nil))
laozhang := NewPerson("zhang", NewCommand(&laowang, laowang.Listen))
laofeng := NewPerson("feng", NewCommand(&laozhang, laozhang.Buy))
laoding := NewPerson("ding", NewCommand(&laofeng, laofeng.Cook))
laoli := NewPerson("li", NewCommand(&laoding, laoding.Wash))
laoli.Talk()
}