命令模式(面试版)
一、面试常考点
1. 命令模式解决什么问题
把“请求”封装为对象,便于排队、记录、撤销、重做。
2. 常见识别信号
需要操作历史、撤销重做、任务队列。
3. 常见追问
如何设计 undo/redo、命令持久化怎么做。
二、细节介绍
1. 核心角色
Invoker(触发者)、Command(命令)、Receiver(执行者)。
2. 优点
调用方与执行方解耦,扩展操作更稳定。
3. 代价
命令类增多,状态回滚设计复杂。
三、示例代码
class TextEditor {
constructor() {
this.content = ''
}
insert(text) {
this.content += text
}
removeLast(len) {
this.content = this.content.slice(0, -len)
}
}
class InsertCommand {
constructor(editor, text) {
this.editor = editor
this.text = text
}
execute() {
this.editor.insert(this.text)
}
undo() {
this.editor.removeLast(this.text.length)
}
}
const editor = new TextEditor()
const cmd = new InsertCommand(editor, 'hello')
cmd.execute()
cmd.undo()
四、常用应用场景
1. 编辑器撤销重做
输入、删除、格式化等操作命令化。
2. 任务队列
把任务包装为命令统一调度。
3. 操作审计
命令日志可用于回放与追踪。
五、高频追问标准答法(Q/A)
1. Q: 命令模式和责任链差异
A: 命令模式封装“一个请求”;责任链组织“多个处理节点”。
2. Q: undo 难点在哪里
A: 需要保存足够状态用于逆操作,尤其是跨对象操作。