日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解Javascript實踐中的命令模式

瀏覽:67日期:2023-06-04 17:34:05
定義

Encapsulate a request as an object, thereby letting you parameterize other objects with different requests, queue or log requests,and support undoable operations.“

「命令模式」將「請求」封裝成對象,以便使用不同的請求、隊列或者日志來參數化其他對象,同時支持可撤消的操作。

這里的「請求」的定義,并不是我們前端常說的「Ajax 請求」,而是一個「動作請求」,也就是發(fā)起一個行為。例如,通過遙控器關閉電視,這里的「關閉」就是一個請求。在命令模式中,我們將請求抽象成一個命令,這個命令是可復用的,它只關心它的接受者(電視);而對于動作的發(fā)起者(遙控器)來說,它只關心它所支持的命令有哪些,而不關心這些命令具體是做什么的。

結構

命令模式的類圖如下:

詳解Javascript實踐中的命令模式

在該類圖中,我們看到五個角色:

Client - 創(chuàng)建 Concrete Command 與 Receiver(應用層)。 Invoker - 命令的發(fā)出者,通常會持有命令對象,可以持有很多的命令對象。 Receiver - 命令接收者,真正執(zhí)行命令的對象。任何類都可能成為一個接收者,只要它能夠實現命令要求實現的相應功能。 Command - 命令接口。 ConcreteCommand - 命令接口的實現。

Reciver 與 Invoker 沒有耦合,當需要拓展功能時,通過新增 Command,因此命令模式符合開閉原則。

實例自定義快捷鍵

自定義快捷鍵是一個編輯器的最基本功能。通過命令模式,我們可以寫出一個將鍵位與鍵位邏輯解耦的結構。

interface Command { exec():void}type Keymap = { [key:string]: Command }class Hotkey { keymap: Keymap = {} constructor(keymap: Keymap) {this.keymap = keymap } call(e: KeyboardEvent) {const prefix = e.ctrlKey ? ’ctrl+’ : ’’const key = prefix + e.keythis.dispatch(key) } dispatch(key: string) {this.keymap[key].exec() }}class CopyCommand implements Command { constructor(clipboard: any) {} exec() {}}class CutCommand implements Command { constructor(clipboard: any) {} exec() {}}class PasteCommand implements Command { constructor(clipboard: any) {} exec() {}}const clipboard = { data: ’’ }const keymap = { ’ctrl+x’: new CutCommand(clipboard), ’ctrl+c’: new CopyCommand(clipboard), ’ctrl+v’: new PasteCommand(clipboard)}const hotkey = new Hotkey(keymap)document.onkeydown = (e) => { hotkey.call(e)}

在本例中,hotkey是 Invoker,clipboard是 Receiver。當我們需要修改已有的 keymap 時,只需要新增或替換已有的key或Command即可。

是不是覺得這個寫法似曾相識?沒錯Redux 也是應用了命令模式,Store 相當于 Receiver,Action 相當于 Command,Dispatch 相當于 Invoker。

撤銷與重做

基于命令模式,我們可以很容易拓展,使它支持撤銷與重做。

interface IPerson { moveTo(x: number, y: number): void}class Person implements Person { x = 0 y = 0 moveTo(x: number, y: number) {this.x = xthis.y = y }}interface Command { exec(): void undo(): void}class MoveCommand implements Command { prevX = 0 prevY = 0 person: Person constructor(person: Person) {this.person = person } exec() {this.prevX = this.person.xthis.prevY = this.person.ythis.person.moveTo(this.prevX++, this.prevY++) } undo() {this.person.moveTo(this.prevX, this.prevY) }}const ezio = new Person()const moveCommand = new MoveCommand(ezio)moveCommand.exec()console.log(ezio.x, ezio.y)moveCommand.undo()console.log(ezio.x, ezio.y)錄制與回放

想想我們在游戲中的錄制與回放功能,如果將角色的每個動作都作為一個命令的話,那么在錄制時就能夠得到一連串的命令隊列。

class Control { commands: Command[] = []exec(command) {this.commands.push(command)command.exec(this.person) }}const ezio = new Person()const control = new Control()control.exec(new MoveCommand(ezio))control.exec(new MoveCommand(ezio))console.log(control.commands)

當我們有了命令隊列,我們又能夠很容易得進行多次的撤銷和重做,實現一個命令的歷史記錄。只需要移動當前命令隊列的指針即可。

class CommandHistory { commands: Command[] = []index = 0get currentCommand() {return this.commands[index] }constructor(commands: Command[]) {this.commands = commands }redo() {this.index++this.currentCommand.exec() }undo() {this.currentCommand.undo()this.index-- }}

同時,如果我們將命令序列化成一個對象,它便可以用于保存與傳遞。這樣我們將它發(fā)送到遠程計算機,就能實現遠程控制ezio移動的功能。

[{ type: ’move’, x: 1, y: 1,}, { type: ’move’, x: 2, y: 2,}]宏命令

對Command進行一些簡單的處理就能夠將已有的命令組合起來執(zhí)行,將其變成一個宏命令。

class BatchedCommand implements Command { commands = []constructor(commands) {this.commands = commands }exec() {this.commands.forEach(command => command.exec()) }}const batchedMoveCommand = new BatchedCommand([ new MoveCommand(ezio), new SitCommand(ezio),])batchedMoveCommand.exec()總結

通過以上幾個例子,我們可以看出命令模式有一下幾個特點:

低耦合,徹底消除了接受者與調用者之間的耦合。 易拓展,只需要增加新的命令便可拓展出新功能。 支持序列化,易于實現保存與傳遞。 容易導致 Command 類龐大。

以上就是詳解Javascript實踐中的命令模式的詳細內容,更多關于Javascript命令模式的資料請關注好吧啦網其它相關文章!

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
亚洲免费观看高清完整版在线观| 国产综合亚洲精品一区二| 欧美1区免费| 美女av在线免费看| 在线一区av| 国产精品av一区二区| 欧美日韩一区二区三区视频播放| 精品伊人久久| 久久精品理论片| 色婷婷综合网| 国户精品久久久久久久久久久不卡| 91精品在线观看国产| 欧美大黑bbbbbbbbb在线| 99国产成+人+综合+亚洲欧美| 噜噜噜久久亚洲精品国产品小说| 免费成人性网站| 欧美有码在线| 福利一区二区免费视频| 久久三级福利| 偷拍亚洲精品| 日本免费一区二区三区四区| 午夜精品婷婷| 鲁大师影院一区二区三区| 香蕉久久一区| 97精品中文字幕| 视频在线在亚洲| 精品国产乱码久久久| 欧美不卡高清| 国产麻豆精品| 亚洲精品123区| 欧美黑人巨大videos精品| 亚洲国内精品| 国产精品视频首页| 亚洲在线国产日韩欧美| 欧美国产小视频| 亚洲综合福利| 久久理论电影| 国产精品片aa在线观看| 99视频一区| 亚洲v在线看| 麻豆精品在线| 日韩一区二区三区在线看| 免费精品国产| 中文字幕在线免费观看视频| 青青草精品视频| 爽好多水快深点欧美视频| 色婷婷久久久| 日产午夜精品一线二线三线| 亚洲精品第一| 性欧美长视频| 伊人久久婷婷| 欧美日韩亚洲在线观看| 精品视频一区二区三区在线观看| 亚洲精选久久| 蜜桃免费网站一区二区三区| 欧美日韩国产亚洲一区| 欧美日韩激情| 免费成人网www| 在线亚洲观看| 夜夜嗨一区二区| 老鸭窝亚洲一区二区三区| 国精品一区二区三区| 久久久久蜜桃| 夜夜嗨av一区二区三区网站四季av| 99久久久久国产精品| 国产综合精品| 中文视频一区| 国产精品普通话对白| 一区视频在线| 亚洲精品三级| 国产欧美一区二区三区精品观看 | 日韩一区电影| 国产99久久| 亚洲综合专区| 国产探花在线精品| 国产欧美欧美| 成人国产精选| 久久国产精品成人免费观看的软件| 日韩欧美少妇| 亚洲一区二区三区久久久| 一级欧美视频| 久久wwww| 亚洲一级特黄| 日韩精品中文字幕一区二区| 欧美a级一区二区| 国产综合色产| 国产日本亚洲| 久久精品欧美一区| 亚洲区第一页| 色综合五月天| 综合欧美精品| 欧美国产偷国产精品三区| aa亚洲婷婷| 国产成人精品一区二区三区免费 | 久久99高清| 蜜桃视频第一区免费观看| 国产欧美啪啪| 性欧美精品高清| 精品不卡一区| 亚洲精品看片| 女人天堂亚洲aⅴ在线观看| 欧美成人精品一级| 日本亚洲欧洲无免费码在线| 久久中文视频| 麻豆成人在线观看| 亚洲视频国产精品| 欧美日韩水蜜桃| 国产在线一区不卡| 久久亚洲精品伦理| 精品国产成人| 欧美亚洲免费| 婷婷久久免费视频| 国产精品女主播一区二区三区| 国产精品xx| 国产在线不卡一区二区三区| 91精品国产自产观看在线| 老司机久久99久久精品播放免费| 日韩不卡一区| 91综合网人人| av中文资源在线资源免费观看| 国产精品任我爽爆在线播放| 亚欧洲精品视频在线观看| 亚洲免费影视| 久久亚洲欧美| 五月天激情综合网| 亚洲一级黄色| 欧美自拍一区| 五月激激激综合网色播 | 亚洲精品欧洲| 亚洲精品护士| 亚洲3区在线| 四虎精品一区二区免费| 午夜天堂精品久久久久| 亚洲18在线| 欧美日本三区| 国产精品欧美在线观看| 国产精品扒开腿做爽爽爽软件| 日韩av不卡在线观看| 亚洲久久一区| 国产精品3区| 91亚洲国产| 亚洲午夜在线| 天堂久久一区| 久久久国产精品入口麻豆| 高清av不卡| 九九在线精品| 亚洲人成毛片在线播放女女| 亚洲精品中文字幕99999| 欧美激情视频一区二区三区免费| 色在线视频观看| 久久最新视频| 欧美1区2区3| 免费精品一区| 国产在线日韩| 国产福利一区二区三区在线播放| 超级白嫩亚洲国产第一| 欧美aa国产视频| 欧美日韩夜夜| 成人免费网站www网站高清| 日韩啪啪电影网| 欧美影院视频| 99视频精品| 日韩精品午夜| 免费一级欧美在线观看视频| 久久婷婷激情| 国产精品天天看天天狠| 国产视频亚洲| 国产精品视频一区二区三区综合| 国产一区二区三区四区二区| 三级一区在线视频先锋| 成人影视亚洲图片在线| 日韩一区中文| 亚洲一区不卡| 日韩高清欧美| 欧美日韩1区2区3区| 今天的高清视频免费播放成人| 欧美激情99| 日韩高清中文字幕一区| 99国产精品久久久久久久| 91欧美在线| 国产一区二区三区探花| 国产精品欧美在线观看| 亚洲一卡久久| 国产韩日影视精品| 岛国av在线播放| 国产精品一区二区三区www| 石原莉奈在线亚洲三区| 不卡中文字幕| 日本免费一区二区三区四区| 精品一区二区三区中文字幕视频| 日韩精品导航| 婷婷综合成人| 丝袜脚交一区二区| 99国产精品视频免费观看一公开| 99tv成人| 狠狠干综合网| 黄色成人91| 免费的成人av| 性欧美长视频| 亚洲ab电影|