首页 > 其他 > 详细

Golang 设计模式 学习笔记(六)命令模式

时间:2014-02-07 04:43:38      阅读:359      评论:0      收藏:0      [点我收藏+]

由于最近一直在学习Golang,所以从本节起,所有设计模式学习笔记中的源码都由Golang来完成~

命令模式:将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

仔细看这个定义,我们知道一个命令对象通过在特定接收者(receiver)上绑定一组动作来封装一个请求。要达到这一点,命令对象将动作和接收者包进对象中。这个对象只暴露出一个execute()方法,当此方法被调用的时候,接收者就会进行这些动作。从外面看,其他对象不知道究竟哪个接收者进行了哪些动作,只知道如果调用了execute(),请求的目的就达到了。这些就实现了接收者和调用者的解耦合。

实现命令接口:

首先让所有的命令对象实现相同的包含一个方法的接口:

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) //关闭
    }
}


最后,再来看看客户端的代码:

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()
}


看看接收者们:

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()
}


bubuko.com,布布扣

本文出自 “Programming in XMU” 博客,请务必保留此出处http://liuxp0827.blog.51cto.com/5013343/1356520

Golang 设计模式 学习笔记(六)命令模式

原文:http://liuxp0827.blog.51cto.com/5013343/1356520

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!