Golang 設計模式 學習筆記(六)命令模式

因爲最近一直在學習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()
}


wKioL1LxtPqQtdEsAABXMRft1Bk710.jpg

相關文章
相關標籤/搜索