什么是命令模式?
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
实现
// 服务员,调用者角色
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
优点
- 类间耦合,调用者角色与接收者角色之间没有任何依赖关系;
- 可扩展性;
- 命令模式结合职责链模式可以实现命令族解析任务。
缺点
- 可能导致某些系统有过多的具体命令类;
使用场景
- 认为是命令的地方都可以使用;
- 系统需要支持命令的撤销/恢复操作时。
网友评论