这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
命令模式
命令模式本质上是把对象的方法调用封装到对象中,方便传递、存储和调用。
命令模式是行为型设计模式的一种,目的是将调用操作的对象解耦,增加新的命令不影响现有的类。
命令模式是集那个请求封装成一个对象,使得我们可以用不同的请求进行参数化,
命令模式中的角色
- Command: 命令
- Invoker: 调用者
- Recevier: 接收者
- Client: 客户端
- ConcreteCommand: 命令具体实现
客户端通过调用者发送命令,命令接受者执行相关操作。
请求步骤如下:
- 客户端 Client 创建一个 ConcreteCommand 对象并且制定它的 Receiver 对象
- Invoker 对象设置 ConcreteCommand 对象
- Invoker 通过调用 Command 的 Execute 操作提交一个请求。
- ConcreteCommand 对象调用 Receiver 的一些操作执行该请求。
将函数作为一个参数传递给另外一个函数
package command
import (
"fmt"
"testing"
)
func Func(i func(int, int) int) int {
fmt.Printf("i type: %T\n", i)
return i(3, 2)
}
func TestFunc(t *testing.T) {
add := func(x, y int) int {
return x + y
}
fmt.Printf("add type: %T\n", add)
fmt.Println(Func(add))
}
执行结果:
=== RUN TestFunc
add type: func(int, int) int
i type: func(int, int) int
5
--- PASS: TestFunc (0.00s)
PASS
命令模式代码实现
命令接口
type Command interface {
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")
}
调用者接口
// 请求者(调用者)具体实现 调用者 Invoker
type button struct {
command Cmd
}
func (b *button) press() {
b.command.Execute()
}
测试代码
// 客户端
// 0. Receiver 对象
tv := &tv{
}
// 1. 客户端 Client 创建一个 ConcreteCommand 对象并且制定它的 Receiver 对象
onCmd := &onCommand{device: tv}
offCmd := &offCommand{
device: tv,
}
// 2. Invoker 对象设置 ConcreteCommand 对象
onButton := &button{
command: onCmd,
}
onButton.press()
offButton := &button{
command: offCmd,
}
offButton.press()
执行结果:
=== RUN TestExampleCommand
Turning tv on
Turning tv off
--- PASS: TestExampleCommand (0.00s)
PASS