设计模式--命令(Command)模式

110 阅读1分钟

模式定义

将一个请求(行为)封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作

类图

在这里插入图片描述

要点总结

  • 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()
}