type command interface { execute() } //开灯命令 type lightOnCommand struct { mLight *light //命令对象包含的特定接收者 } //返回一个开灯命令的实例对象 func NewLightOnCommand(light *light) command { return &lightOnCommand{mLight: light} } //实现接口方法捆绑接收者的动作 func (this *lightOnCommand) execute() { if !this.mLight.isOn() { this.mLight.setOn(true) //开灯 } } //关灯命令 type lightOffCommand struct { mLight *light } func NewLightOffCommand(light *light) command { return &lightOffCommand{mLight: light} } func (this *lightOffCommand) execute() { if this.mLight.isOn() { this.mLight.setOn(false) //关灯 } }@H_502_0@
@H_502_0@我们应当考虑面向接口编程,大部分接收者都有简单的开关命令,故上述的代码可改为:
type receiver interface { setOn(bool) //true:开/false:关 isOn() bool } //打开命令 type onCommand struct { receiver Receiver } //创建打开命令的实例,为该实例捆绑接收者 func NewOnCommand(receiver Receiver) command { return &onCommand{receiver} } //被封装的“请求” func (this *onCommand) execute() { if !this.receiver.isOn() { this.receiver.setOn(true) //打开 } } //关闭命令 type offCommand struct { receiver Receiver } func NewOffCommand(receiver Receiver) command { return &offCommand{receiver} } func (this *offCommand) execute() { if !this.receiver.isOn() { this.receiver.setOn(false) //关闭 } }@H_502_0@
@H_502_0@最后,再来看看客户端的代码:
type RemoteController struct { slot command } func (this *RemoteController) SetCommand(command command) { this.slot = command } func (this *RemoteController) ButtonPressed() { if this.slot == nil { panic("Do not assign command to Controller's slot!") } this.slot.execute() }@H_502_0@
@H_502_0@看看接收者们:
const ( LIGHT = " light" DOOR = " door" ) //接收者接口 type Receiver interface { setOn(bool) isOn() bool } type light struct { name string on bool } func (this *light) setOn(b bool) { if b { fmt.Println(this.name + LIGHT + " is on.") } else { fmt.Println(this.name + LIGHT + " is off.") } this.on = b } func (this *light) isOn() bool { return this.on } func NewRoomLight() Receiver { return &light{"Room",false} } func NewTableLampLight() Receiver { return &light{"Table Lamp",false} } type door struct { name string on bool } func (this *door) setOn(b bool) { if b { fmt.Println(this.name + DOOR + " is opened.") } else { fmt.Println(this.name + DOOR + " is closed.") } this.on = b } func (this *door) isOn() bool { return this.on } func NewGarageDoor() Receiver { return &door{"Garage",false} } func NewKitchenDoor() Receiver { return &door{"Kitchen",false} }@H_502_0@
@H_502_0@来测试下吧~:
func main() { ctrl := new(command.RemoteController) var roomLight,garageDoor command.Receiver roomLight = command.NewRoomLight() garageDoor = command.NewGarageDoor() cmdOn := command.NewOnCommand(roomLight) cmdOff := command.NewOffCommand(garageDoor) ctrl.SetCommand(cmdOn) ctrl.ButtonPressed() ctrl.SetCommand(cmdOff) ctrl.ButtonPressed() }@H_502_0@
@H_502_0@