因爲最近一直在學習Golang,因此從本節起,全部設計模式學習筆記中的源碼都由Golang來完成~java
命令模式:將「請求」封裝成對象,以便使用不一樣的請求、隊列或者日誌來參數化其餘對象。命令模式也支持可撤銷的操做。編程
仔細看這個定義,咱們知道一個命令對象經過在特定接收者(receiver)上綁定一組動做來封裝一個請求。要達到這一點,命令對象將動做和接收者包進對象中。這個對象只暴露出一個execute()方法,當此方法被調用的時候,接收者就會進行這些動做。從外面看,其餘對象不知道究竟哪一個接收者進行了哪些動做,只知道若是調用了execute(),請求的目的就達到了。這些就實現了接收者和調用者的解耦合。設計模式
實現命令接口:ide
首先讓全部的命令對象實現相同的包含一個方法的接口:學習
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) //關燈 } }
咱們應當考慮面向接口編程,大部分接收者都有簡單的開關命令,故上述的代碼可改成:測試
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) //關閉 } }
最後,再來看看客戶端的代碼:
this
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() }
看看接收者們:spa
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} }
來測試下吧~:
設計
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() }