使用场景
1.需要通过操作来参数化对象, 可使用命令模式。
2.想要将操作放入队列中、 操作的执行或者远程执行操作, 可使用命令模式。
3.想要实现操作回滚功能, 可使用命令模式。
实现方式
1.声明仅有一个执行方法的命令接口。
2.抽取请求并使之成为实现命令接口的具体命令类。 每个类都必须有一组成员变量来保存请求参数和对于实际接收者对象的引用。 所有这些变量的数值都必须通过命令构造函数进行初始化。
3.找到担任发送者职责的类。 在这些类中添加保存命令的成员变量。 发送者只能通过命令接口与其命令进行交互。 发送者自身通常并不创建命令对象, 而是通过客户端代码获取。
4.修改发送者使其执行命令, 而非直接将请求发送给接收者。
5.客户端必须按照以下顺序来初始化对象:
① 创建接收者。
②创建命令, 如有需要可将其关联至接收者。
③创建发送者并将其与特定命令关联。
栗子
package main
import "fmt"
//命令接口
type Command interface {
execute()
}
type Button struct {
command Command
}
func (b *Button) press() {
b.command.execute()
}
//打开命令
type OnCommand struct {
device Device //命令应该关联接收者
}
func (c *OnCommand) execute() {
c.device.on()
}
//关闭命令
type OffCommand struct {
device Device
}
func (c *OffCommand) execute() {
c.device.off()
}
//接受者接口
//把接受者做成接口时因为不仅有电视遥控器,也可能有冰箱,空调遥控器
type Device interface {
on()
off()
}
type Tv struct {
isRunning bool
}
func (t *Tv) on() {
t.isRunning = true
fmt.Println("Turning tv on")
}
func (t *Tv) off() {
t.isRunning = false
fmt.Println("Turning tv off")
}
func main() {
//先创建接收者
tv := &Tv{}
//关联接收到到命令
onCommand := &OnCommand{
device: tv,
}
offCommand := &OffCommand{
device: tv,
}
onButton := &Button{
command: onCommand,
}
onButton.press()
offButton := &Button{
command: offCommand,
}
offButton.press()
}