15. 命令模式(Command)
15. 命令模式(Command)
问题:想把「操作」封装成对象,支持撤销、队列、日志等。
核心:每个操作是一个命令对象,包含执行和撤销方法。
class Light {
#state = false;
on() { this.#state = true; console.log('灯开了'); }
off() { this.#state = false; console.log('灯关了'); }
}
class LightOnCommand {
#light;
constructor(light) { this.#light = light; }
execute() { this.#light.on(); }
unexecute() { this.#light.off(); }
}
class RemoteControl {
#history = [];
execute(command) {
command.execute();
this.#history.push(command);
}
undo() {
this.#history.pop()?.unexecute();
}
}
const remote = new RemoteControl();
const light = new Light();
remote.execute(new LightOnCommand(light)); // 灯开了
remote.undo(); // 灯关了package command
import "fmt"
type Command interface {
Execute()
Unexecute()
}
type Light struct{ state bool }
func (l *Light) On() { l.state = true; fmt.Println("灯开了") }
func (l *Light) Off() { l.state = false; fmt.Println("灯关了") }
type LightOnCommand struct{ light *Light }
func (c LightOnCommand) Execute() { c.light.On() }
func (c LightOnCommand) Unexecute() { c.light.Off() }
type RemoteControl struct {
history []Command
}
func (r *RemoteControl) Execute(cmd Command) {
cmd.Execute()
r.history = append(r.history, cmd)
}
func (r *RemoteControl) Undo() {
if len(r.history) == 0 {
return
}
cmd := r.history[len(r.history)-1]
r.history = r.history[:len(r.history)-1]
cmd.Unexecute()
}