Command模式¶
设计模式中的Command模式是一种行为设计模式,它将一个请求或简单操作封装成一个对象。这种模式允许用户根据不同的请求、队列或日志请求来参数化其他对象。它也支持可撤销的操作。Command模式的核心在于四种角色:
- Command:定义执行操作的接口。
- ConcreteCommand:实现Command接口的具体类,它有一个接收者(Receiver)对象并调用接收者的功能来完成命令要执行的操作。
- Receiver:执行与请求相关的操作,具体执行命令的组件。
- Invoker:请求的发送者,持有Command对象,并在某个时间点调用Command对象的execute方法来提交请求。
使用Command模式可以很容易地将一连串独立的操作通过配置连成Command链或者invocation链,并针对执行结果实现分支,重试或回滚等。这样可以将复杂的系统集成场景解成不同的Command并分配在团队中开发实现,后期可以轻松地添加新的Command,调整配置,而保持最大的代码重用性。而这种模式称为责任链(Chain of Responsibilities)模式。Servlet Filter和Python开源库LangChain是责任链模式的绝佳例子。
Java¶
假设我们有一个简单的命令,打开电灯(Light On Command)。
Command Interface
public interface Command {
void execute();
}
ConcreteCommand
public class LightOnCommand implements Command {
Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
}
Receiver
public class Light {
public void on() {
System.out.println("Light is on");
}
public void off() {
System.out.println("Light is off");
}
}
Invoker
public class RemoteControl {
Command slot;
public RemoteControl() {}
public void setCommand(Command command) {
slot = command;
}
public void buttonWasPressed() {
slot.execute();
}
}
客户端代码
public class RemoteLoader {
public static void main(String[] args) {
RemoteControl remote = new RemoteControl();
Light light = new Light();
LightOnCommand lightOn = new LightOnCommand(light);
remote.setCommand(lightOn);
remote.buttonWasPressed();
}
}
Golang¶
Command Interface
package main
import "fmt"
type Command interface {
Execute()
}
ConcreteCommand
type LightOnCommand struct {
light *Light
}
func (c *LightOnCommand) Execute() {
c.light.On()
}
Receiver
type Light struct {}
func (l *Light) On() {
fmt.Println("Light is on")
}
func (l *Light) Off() {
fmt.Println("Light is off")
}
Invoker
type RemoteControl struct {
command Command
}
func (r *RemoteControl) SetCommand(command Command) {
r.command = command
}
func (r *RemoteControl) PressButton() {
r.command.Execute()
}
客户端代码
func main() {
light := &Light{}
lightOnCommand := &LightOnCommand{light}
remote := RemoteControl{}
remote.SetCommand(lightOnCommand)
remote.PressButton()
}
Python¶
Command Interface
from abc import ABC, abstractmethod
class Command(ABC):
@abstractmethod
def execute(self):
pass
ConcreteCommand
class LightOnCommand(Command):
def __init__(self, light):
self.light = light
def execute(self):
self.light.on()
Receiver
class Light:
def on(self):
print("Light is on")
def off(self):
print("Light is off")
Invoker
class RemoteControl:
def __init__(self):
self.command = None
def set_command(self, command):
self.command = command
def press_button(self):
self.command.execute()
客户端代码
if __name__ == "__main__":
light = Light()
light_on = LightOnCommand(light)
remote = RemoteControl()
remote.set_command(light_on)
remote.press_button()