鱼弦:CSDN内容合伙人、CSDN新星导师、全栈领域创作新星创作者 、51CTO(Top红人+专家博主) 、github开源爱好者(go-zero源码二次开发、游戏后端架构 https://github.com/Peakchen)
命令模式原理详细解释:
命令模式(Command Pattern)是一种行为型设计模式,用于将请求封装成一个对象,从而使得可以将不同的请求参数化、延迟执行或者将请求放入队列中等。
命令模式的核心思想是将请求的发送者(Client)与请求的接收者(Receiver)解耦,通过引入命令对象(Command)作为中介,将请求封装成一个对象,使得发送者和接收者不直接交互。命令对象包含了与请求相关的操作,可以通过调用命令对象的方法来触发请求的执行。
底层结构图:
以下是命令模式的经典结构图:
+-----------------------+ +-----------------+ +---------------------+
| Client | | Command | | Receiver |
+-----------------------+ +-----------------+ +---------------------+
| - command: Command |<>----->| + Execute() | | |
+-----------------------+ +-----------------+ +---------------------+
^
|
|
v
+-----------------+
| ConcreteCommand |
+-----------------+
| + receiver: Receiver | +---------------------+
+-----------------+ | ConcreteReceiver |
| + Execute() | + Action() |
+-----------------+ +---------------------+
在上述结构图中,Client
是命令的发送者,负责创建具体的命令对象,并设置命令对象的接收者。
Command
是命令的抽象类或接口,定义了命令对象的执行方法 Execute()
。
Receiver
是命令的接收者,负责执行实际的操作。
ConcreteCommand
是具体的命令类,继承自 Command
,并实现了 Execute()
方法。ConcreteCommand
中包含了对应的 Receiver
对象。
使用场景解释:
命令模式适用于以下场景:
-
当需要将请求发送者和请求接收者解耦时,可以使用命令模式。命令模式通过引入一个命令对象,将请求封装成一个对象,使得发送者和接收者不直接交互,从而实现解耦。
-
当需要将请求参数化或者延迟执行时,可以考虑使用命令模式。命令对象可以封装请求的参数,使得可以灵活地设置和修改请求的参数,并且可以在需要的时候执行请求。
-
当需要实现撤销、重做、事务等功能时,命令模式是一种常见的实现方式。命令对象可以记录请求的历史或者将多个请求组合成一个新的请求,从而实现撤销、重做、事务等功能。
代码示例实现:
以下是一个使用Go语言实现命令模式的示例:
package main
import "fmt"
// Command 命令接口
type Command interface {
Execute()
}
// Light 灯
type Light struct {
isOn bool
}
// OnCommand 开灯命令
type OnCommand struct {
light *Light
}
// Execute 执行命令
func (c *OnCommand) Execute() {
c.light.TurnOn()
}
// OffCommand 关灯命令
type OffCommand struct {
light *Light
}
// Execute 执行命令
func (c *OffCommand) Execute() {
c.light.TurnOff()
}
// TurnOn 开灯
func (l *Light) TurnOn() {
l.isOn = true
fmt.Println("Light is on")
}
// TurnOff 关灯
func (l *Light) TurnOff() {
l.isOn = false
fmt.Println("Light is off")
}
// RemoteControl 遥控器
type RemoteControl struct {
command Command
}
// SetCommand 设置命令
func (r *RemoteControl) SetCommand(command Command) {
r.command = command
}
// PressButton 按下按钮
func (r *RemoteControl) PressButton() {
r.command.Execute}
func main() {
light := &Light{}
onCommand := &OnCommand{light: light}
offCommand := &OffCommand{light: light}
remoteControl := &RemoteControl{}
remoteControl.SetCommand(onCommand)
remoteControl.PressButton()
remoteControl.SetCommand(offCommand)
remoteControl.PressButton()
}
上述示例中,Light
表示灯的对象,具有开灯和关灯的方法。OnCommand
和 OffCommand
分别表示开灯命令和关灯命令,实现了 Command
接口。RemoteControl
表示遥控器对象,可以设置命令并按下按钮执行命令。
文献材料链接:
以下是一些关于命令模式的文献材料链接:
- Design Patterns: Elements of Reusable Object-Oriented Software (GoF book) - Amazon.com
- Command Design Pattern - Command
- Command Pattern - Command Design Pattern
当前都有哪些产品在使用:
命令模式在软件开发中被广泛应用,以下是一些常见产品和框架中使用命令模式的实例:
- 图形界面应用程序中的撤销和重做功能。
- 计算机游戏中的键盘映射和快捷键功能。
- 操作系统中的命令行解释器(如Unix中的shell)。
- 文字处理软件中的菜单操作。
- 航空电子设备中的遥控器系统。
- 各种框架和库中的命令模式的实现,如.NET中的Command模式、Java Swing中的ActionListener等。