电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

詳解Javascript實踐中的命令模式

瀏覽:26日期: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 請求」,而是一個「動作請求」,也就是發起一個行為。例如,通過遙控器關閉電視,這里的「關閉」就是一個請求。在命令模式中,我們將請求抽象成一個命令,這個命令是可復用的,它只關心它的接受者(電視);而對于動作的發起者(遙控器)來說,它只關心它所支持的命令有哪些,而不關心這些命令具體是做什么的。

結構

命令模式的類圖如下:

詳解Javascript實踐中的命令模式

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

Client - 創建 Concrete Command 與 Receiver(應用層)。 Invoker - 命令的發出者,通常會持有命令對象,可以持有很多的命令對象。 Receiver - 命令接收者,真正執行命令的對象。任何類都可能成為一個接收者,只要它能夠實現命令要求實現的相應功能。 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-- }}

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

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

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

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
相關文章:
主站蜘蛛池模板: 滚塑PE壳体-PE塑料浮球-警示PE浮筒-宁波君益塑业有限公司 | 扫地车厂家-山西洗地机-太原电动扫地车「大同朔州吕梁晋中忻州长治晋城洗地机」山西锦力环保科技有限公司 | 电镀电源整流器_高频电解电源_单脉双脉冲电源 - 东阳市旭东电子科技 | 杭州中策电线|中策电缆|中策电线|杭州中策电缆|杭州中策电缆永通集团有限公司 | 高效节能电机_伺服主轴电机_铜转子电机_交流感应伺服电机_图片_型号_江苏智马科技有限公司 | 活性氧化铝球|氧化铝干燥剂|分子筛干燥剂|氢氧化铝粉-淄博同心材料有限公司 | 运动木地板价格,篮球馆体育运动木地板生产厂家_欧氏地板 | 宁夏档案密集柜,智能密集柜,电动手摇密集柜-盛隆柜业宁夏档案密集柜厂家 | 江苏全风,高压风机,全风环保风机,全风环形高压风机,防爆高压风机厂家-江苏全风环保科技有限公司(官网) | 十二星座查询(性格特点分析、星座运势解读) - 玄米星座网 | 最新范文网_实用的精品范文美文网| 粉丝机械,粉丝烘干机,粉丝生产线-招远市远东粉丝机械有限公司 | 数控走心机-走心机价格-双主轴走心机-宝宇百科 | 碳钢法兰厂家,非标法兰,定制异型,法兰生产厂家-河北九瑞管道 | 无线联网门锁|校园联网门锁|学校智能门锁|公租房智能门锁|保障房管理系统-KEENZY中科易安 | 广州小程序开发_APP开发公司_分销商城系统定制_小跑科技 | 膏剂灌装旋盖机-眼药水灌装生产线-西林瓶粉剂分装机-南通博琅机械科技 | 西点培训学校_法式西点培训班_西点师培训_西点蛋糕培训-广州烘趣西点烘焙培训学院 | 东莞猎头公司_深圳猎头公司_广州猎头公司-广东万诚猎头提供企业中高端人才招聘服务 | 慢回弹测试仪-落球回弹测试仪-北京冠测精电仪器设备有限公司 | 塑料检查井_双扣聚氯乙烯增强管_双壁波纹管-河南中盈塑料制品有限公司 | 天助网 - 中小企业全网推广平台_生态整合营销知名服务商_天助网采购优选 | 粉末包装机-给袋式包装机-全自动包装机-颗粒-液体-食品-酱腌菜包装机生产线【润立机械】 | 色谱柱-淋洗液罐-巴罗克试剂槽-巴氏吸管-5ml样品瓶-SBS液氮冻存管-上海希言科学仪器有限公司 | VOC检测仪-甲醛检测仪-气体报警器-气体检测仪厂家-深恒安科技有限公司 | 广州印刷厂_广州彩印厂-广州艺彩印务有限公司 | 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 - 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 | 伺服电机维修、驱动器维修「安川|三菱|松下」伺服维修公司-深圳华创益 | TPE_TPE热塑性弹性体_TPE原料价格_TPE材料厂家-惠州市中塑王塑胶制品公司- 中塑王塑胶制品有限公司 | 经济师考试_2025中级经济师报名时间_报名入口_考试时间_华课网校经济师培训网站 | 二氧化碳/活性炭投加系统,次氯酸钠发生器,紫外线消毒设备|广州新奥 | 铝箔袋,铝箔袋厂家,东莞铝箔袋,防静电铝箔袋,防静电屏蔽袋,防静电真空袋,真空袋-东莞铭晋让您的产品与众不同 | 杭州网络公司_百度SEO优化-外贸网络推广_抖音小程序开发-杭州乐软科技有限公司 | 铸钢件厂家-铸钢齿轮-减速机厂家-淄博凯振机械有限公司 | 淋巴细胞分离液_口腔医疗器材-精欣华医疗器械(无锡)有限公司 | 精密线材测试仪-电线电缆检测仪-苏州欣硕电子科技有限公司 | ◆大型吹塑加工|吹塑加工|吹塑代加工|吹塑加工厂|吹塑设备|滚塑加工|滚塑代加工-莱力奇塑业有限公司 | 哈尔滨发电机,黑龙江柴油发电机组-北方星光 | 120kv/2mA直流高压发生器-60kv/2mA-30kva/50kv工频耐压试验装置-旭明电工 | 加气混凝土砌块设备,轻质砖设备,蒸养砖设备,新型墙体设备-河南省杜甫机械制造有限公司 | 成都离婚律师|成都结婚律师|成都离婚财产分割律师|成都律师-成都离婚律师网 |