finish cmd pattern

This commit is contained in:
Edward 2020-05-05 22:03:44 +08:00
parent 2bd8e1560b
commit fd36971c21
3 changed files with 101 additions and 79 deletions

View File

@ -1,20 +1,17 @@
# 命令模式
命令模式本质是把某个对象的方法调用封装到对象中,方便传递、存储、调用
命令模式也是一个响应模式,其主要作用是分离命令发出者和命令执行者,两者只要按照命令定义的约束交互,就可以各自变化
示例中把主板单中的启动(start)方法和重启(reboot)方法封装为命令对象,再传递到主机(box)对象中。于两个按钮进行绑定:
现实生活中的例子也很多比如告知店员买XX奶茶遥控器控制电视就是命令模式以及现在AI能力大部分情况下也是基于命令识别进行响应的还有军训的时候队列根据教官的各种口令进行变化更多典型的命令模式。
* 第一个机箱(box1)设置按钮1(buttion1) 为开机按钮2(buttion2)为重启。
* 第二个机箱(box1)设置按钮2(buttion2) 为开机按钮1(buttion1)为重启。
从而得到配置灵活性。
命令模式中中的一个特点是每个`命令`都是一个类型(struct)。
除了配置灵活外,使用命令模式还可以用作
命令模式的关键角色:
* 批处理
* 任务队列
* undo, redo
*接收者(Receiver): 执行请求相关的操作Execute()
*调用者(Invoker): 发出命令的一方
*命令接口(Command)
*具体命令的结构体(Command)
等把具体命令封装到对象中使用的场合

View File

@ -2,64 +2,75 @@ package command
import "fmt"
type Command interface {
////////////////////////////////
//这里使用军训的例子,使用队列向左转,向右转,向后转的口令
//命令发出者是教官,命令执行者是队列
//ICommand 命令接口,队列要进行响应
type ICommand interface {
Execute()
}
type StartCommand struct {
mb *MotherBoard
//Troop 队列
type Troop struct{ name string }
//Execute cmd
func (t *Troop) Execute() {
fmt.Println("cmd had been executed by", t.name)
}
func NewStartCommand(mb *MotherBoard) *StartCommand {
return &StartCommand{
mb: mb,
//TurnLeftCommand 向左转
type TurnLeftCommand struct {
//可以携带参数,每个命令有一个接收者,去执行
receiver ICommand
}
//Execute 执行向左转
func (t *TurnLeftCommand) Execute() {
fmt.Print("Troop Turn Left\n")
t.receiver.Execute()
}
//TurnRightCommand 向右转
type TurnRightCommand struct {
//可以携带参数
receiver ICommand
}
//Execute 执行向右转
func (t *TurnRightCommand) Execute() {
fmt.Print("Troop Turn Right\n")
t.receiver.Execute()
}
//TurnBackCommand 向后转
type TurnBackCommand struct {
//可以携带参数
holdTime int //保持时间
receiver ICommand
}
//Execute 执行向后转
func (t *TurnBackCommand) Execute() {
fmt.Print("Troop Turn Back\n")
t.receiver.Execute()
}
// Instructor 教官
type Instructor struct {
commands []ICommand
}
//AddCommand 教官喊口令一般都是一连串
func (i *Instructor) AddCommand(c ICommand) {
i.commands = append(i.commands, c)
}
//Execute 教官的Execute是发出命令
func (i *Instructor) Execute() {
for _, cmd := range i.commands {
cmd.Execute()
}
}
func (c *StartCommand) Execute() {
c.mb.Start()
}
type RebootCommand struct {
mb *MotherBoard
}
func NewRebootCommand(mb *MotherBoard) *RebootCommand {
return &RebootCommand{
mb: mb,
}
}
func (c *RebootCommand) Execute() {
c.mb.Reboot()
}
type MotherBoard struct{}
func (*MotherBoard) Start() {
fmt.Print("system starting\n")
}
func (*MotherBoard) Reboot() {
fmt.Print("system rebooting\n")
}
type Box struct {
buttion1 Command
buttion2 Command
}
func NewBox(buttion1, buttion2 Command) *Box {
return &Box{
buttion1: buttion1,
buttion2: buttion2,
}
}
func (b *Box) PressButtion1() {
b.buttion1.Execute()
}
func (b *Box) PressButtion2() {
b.buttion2.Execute()
}

View File

@ -1,20 +1,34 @@
package command
func ExampleCommand() {
mb := &MotherBoard{}
startCommand := NewStartCommand(mb)
rebootCommand := NewRebootCommand(mb)
import "testing"
box1 := NewBox(startCommand, rebootCommand)
box1.PressButtion1()
box1.PressButtion2()
func TestTroopCommand(t *testing.T) {
//教官
in := Instructor{}
//受训队伍1
tr1 := &Troop{name: "girl team"}
turnLeft := &TurnLeftCommand{receiver: tr1}
//受训队伍2
tr2 := &Troop{name: "boy team"}
turnRight := &TurnLeftCommand{receiver: tr2}
//准备命令发给不同的队伍
in.AddCommand(turnRight)
in.AddCommand(turnLeft)
turnback := &TurnBackCommand{receiver: tr2}
in.AddCommand(turnback)
turnback = &TurnBackCommand{receiver: tr1}
in.AddCommand(turnback)
//开始发布指令
in.Execute()
box2 := NewBox(rebootCommand, startCommand)
box2.PressButtion1()
box2.PressButtion2()
// Output:
// system starting
// system rebooting
// system rebooting
// system starting
}