We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
命令模式是一种行为型模式。把对象之间的请求封装在命令对象中,将命令的调用者和命令的接收者完全解耦。
当调用命令的 execute 方法时,不同的命令会做不同的事情,从而阐释不同的执行结果,此外还有 undo 和 redo 等操作。
execute
我们直接从代码入手,依次注释 命令的接收者、命令对象、命令的调用者
document.write(`<body> <button id="execute">execute</button> <button id="undo">undo</button> </body>`) // 命令的接收者 let Tv = { open() { console.log('open the tv') }, close() { console.log('close the tv') } } // 命令对象 class OpenTvCommand { constructor(receiver) { this.receiver = receiver } // 行为 => 请求 execute() { this.receiver.open() } undo() { this.receiver.undo() } } // 命令的调用者 let setCommand = (command) => { document.getElementById('execute').onclick = () => { command.execute() } document.getElementById('undo').onclick = () => { command.undo() } } // 实例化命令并解耦 setCommand(new OpenTvCommand(Tv))
上述的简单的例子可以直观的理解命令模式的原理。
我们接下看另外一个例子,通过控制小球的移动,本质的模式是相同的,只是增加了更多的逻辑,更接近我们的业务代码。
// 补充 Animate 类 let tween = { linear(t, b, c, d) { return c * t / d + b }, easeIn(t, b, c, d) { return c * (t /= d) * t + b } // ... } class Animate { constructor(dom) { this.dom = dom // 进行运动的dom节点 this.startTime = 0 // 动画开始时间 this.endTime = 0 this.startPos = 0 // 动画开始时,dom节点的位置,即dom的初始位置 this.endPos = 0 // 动画开始时,dom节点的位置,即dom的目标位置 this.propertyName = null // dom 节点需要被改变的 CSS 的属性名 this.easing = null // 缓动算法 this.duration = null // 动画持续时间 } start(propertyName, endPos, duration, easing) { this.startTime = +new Date this.startPos = this.dom.getBoundingClientRect()[propertyName] this.propertyName = propertyName this.endPos = endPos this.duration = duration this.easing = tween[easing] let timeId = setInterval(() => { if (this.step() === false) { clearInterval(timeId) } }, 19) } step() { let t = +new Date if (t >= this.startTime + this.duration) { this.update(this.endPos) return false } let pos = this.easing(t - this.startTime, this.startPos, this.endPos - this.startPos, this.duration) this.update(pos) } update(pos) { this.dom.style[this.propertyName] = `${pos}px` } } document.write(`<body> <div id="ball" style="position: absolute;top: 50px; left: 0; background: #000; width: 50px; height: 50px;"></div> 输入小球移动后的位置: <input id="pos"/> <button id="moveBtn">开始移动</button> <button id="cancelBtn">撤销移动</button> </body>`) let ball = document.getElementById('ball') let pos = document.getElementById('pos') let moveBtn = document.getElementById('moveBtn') let cancelBtn = document.getElementById('cancelBtn') // 控制小球的命令对象 class MoveCommand { constructor(receiver, pos) { this.receiver = receiver this.pos = pos this.oldPos = null } execute() { this.receiver.start('left', this.pos, 1000, 'linear') this.oldPos = this.receiver.dom.getBoundingClientRect()[this.receiver.propertyName] } undo() { this.receiver.start('left', this.oldPos, 1000, 'linear') } } var moveCommand moveBtn.onclick = () => { var animate = new Animate(ball) moveCommand = new MoveCommand(animate, pos.value) moveCommand.execute() } cancelBtn.onclick = () => { moveCommand.undo() }
比如 编辑器的实现、命令行的实现等等。
The text was updated successfully, but these errors were encountered:
命令模式
Sorry, something went wrong.
No branches or pull requests
命令模式是一种行为型模式。把对象之间的请求封装在命令对象中,将命令的调用者和命令的接收者完全解耦。
行为
当调用命令的
execute
方法时,不同的命令会做不同的事情,从而阐释不同的执行结果,此外还有 undo 和 redo 等操作。电视遥控器例子
我们直接从代码入手,依次注释 命令的接收者、命令对象、命令的调用者
上述的简单的例子可以直观的理解命令模式的原理。
我们接下看另外一个例子,通过控制小球的移动,本质的模式是相同的,只是增加了更多的逻辑,更接近我们的业务代码。
一个控制小球移动的例子
优点
缺点
使用场景
比如 编辑器的实现、命令行的实现等等。
总结
The text was updated successfully, but these errors were encountered: