美文网首页
设计模式——命令模式

设计模式——命令模式

作者: DevilRoshan | 来源:发表于2020-10-29 23:04 被阅读0次

什么是命令模式?

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

实现

// 服务员,调用者角色
type Waiter struct {
    orders []Command
}

func NewWaiter() *Waiter {
    return &Waiter{}
}

// 设置订单
func (this *Waiter) SetOrder(command Command, isSoldOut bool) {
    // 如果卖完了
    if isSoldOut {
        fmt.Println("改东西卖完了,请点别的!!!", command.GetBarbecuer())
        //this.CancelOrder(command)
    } else {
        this.orders = append(this.orders, command)
    }
}
// 取消订单
//func (this *Waiter) CancelOrder(command Command) {
//  for idx, cmd := range this.orders {
//      if cmd == command {
//          this.orders = append(this.orders[:idx], this.orders[idx+1:]...)
//          break
//      }
//  }
//  fmt.Println("取消订单:" + command.GetBarbecuer())
//}

// 通知全部执行
func (this *Waiter) notifyExecute() {
    fmt.Println("----------------------订单--------------------------")
    for _, order := range this.orders {
        order.ExcuteCommand()
    }
}

// 命令角色
type Command interface {
    // 执行命令
    ExcuteCommand()
    // 获取名称
    GetBarbecuer() string
}

// 接收者角色,烧烤师傅
type Barbecuer struct {
}

func NewBarbecuer() Barbecuer {
    return Barbecuer{}
}

func (this *Barbecuer) bakeMutton() {
    fmt.Println("烤羊肉串")
}

func (this *Barbecuer) bakeChickenWing() {
    fmt.Println("烤鸡翅")
}

// 具体命令,羊肉串
type BakeMuttonCommand struct {
    Receiver  Barbecuer
    Barbecuer string
}

func NewBakeMuttonCommand(receiver Barbecuer) *BakeMuttonCommand {
    return &BakeMuttonCommand{Receiver: receiver, Barbecuer: "烤羊肉串"}
}

func (this *BakeMuttonCommand) ExcuteCommand() {
    this.Receiver.bakeMutton()
}

func (this *BakeMuttonCommand) GetBarbecuer() string {
    return this.Barbecuer
}

// 具体命令,鸡翅
type BakeChickenWing struct {
    Receiver  Barbecuer
    Barbecuer string
}

func NewBakeChickenWing(receiver Barbecuer) *BakeChickenWing {
    return &BakeChickenWing{Receiver: receiver, Barbecuer: "烤鸡翅"}
}

func (this *BakeChickenWing) ExcuteCommand() {
    this.Receiver.bakeChickenWing()
}

// 获取名称
func (this *BakeChickenWing) GetBarbecuer() string {
    return this.Barbecuer
}
func TestNewWaiter(t *testing.T) {
    // 开店前准备
    barbecuer := NewBarbecuer()
    bakeMuttonCommand1 := NewBakeMuttonCommand(barbecuer)
    bakeMuttonCommand2 := NewBakeMuttonCommand(barbecuer)
    bakeChickenWingCommand1 := NewBakeChickenWing(barbecuer)
    bakeChickenWingCommand2 := NewBakeChickenWing(barbecuer)
    waiter := NewWaiter()

    // 开门营业,顾客点菜
    waiter.SetOrder(bakeMuttonCommand1, false)
    waiter.SetOrder(bakeMuttonCommand2, false)
    waiter.SetOrder(bakeChickenWingCommand1, false)
    waiter.SetOrder(bakeChickenWingCommand2, true)
    waiter.notifyExecute()
}
// === RUN   TestNewWaiter
// 改东西卖完了,请点别的!!! 烤鸡翅
// ----------------------订单--------------------------
// 烤羊肉串
// 烤羊肉串
// 烤鸡翅
// --- PASS: TestNewWaiter (0.00s)
// PASS

优点

  • 类间耦合,调用者角色与接收者角色之间没有任何依赖关系;
  • 可扩展性;
  • 命令模式结合职责链模式可以实现命令族解析任务。

缺点

  • 可能导致某些系统有过多的具体命令类;

使用场景

  • 认为是命令的地方都可以使用;
  • 系统需要支持命令的撤销/恢复操作时。

相关文章

网友评论

      本文标题:设计模式——命令模式

      本文链接:https://www.haomeiwen.com/subject/wzifvktx.html