欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript設(shè)計(jì)模式之命令模式

 更新時(shí)間:2022年01月15日 16:58:58   作者:石頭山_S  
這篇文章主要為大家介紹了javascript命令模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

一. 認(rèn)識(shí)命令模式

所謂命令,也就是指執(zhí)行某些特定事情的指令,就拿喝水的例子來說,喝水執(zhí)行的指令就是將水倒在杯子里,然后端起杯子送入口中,這就是一條命令,無論誰喝水都是這個(gè)步驟,我們不關(guān)心是誰端起了杯子,也不關(guān)心杯子中的水到底是水還是其他東西。我們只關(guān)心這個(gè)過程,將水倒在杯子中,然后端起杯子送入口中,最后誰喝掉了,喝掉的是飲料還是水不重要。

大家可能聽的有點(diǎn)混,而命令模式最常見的應(yīng)用場景就是:有時(shí)候需要向某些對象發(fā)送請求,但是并不知道請求的接收者是誰,也不知道被請求的操作是什么。此時(shí)我們用一種松耦合的方式來設(shè)計(jì)程序,使得請求發(fā)送者和接收者能夠消除彼此間的耦合關(guān)系。

二. 代碼實(shí)現(xiàn)-實(shí)際應(yīng)用場景

在實(shí)際開發(fā)中團(tuán)隊(duì)協(xié)作是最重要的環(huán)節(jié),假如兩個(gè)人分別得到兩個(gè)不同的任務(wù),一個(gè)人負(fù)責(zé)頁面中所有的 button 按鈕的美化,另一個(gè)人負(fù)責(zé)實(shí)現(xiàn)這些 button 的邏輯,我們在寫 button 邏輯時(shí)不知道該 button 最終綁定的是頁面中的哪一個(gè)按鈕,也不知道具體點(diǎn)擊該按鈕會(huì)發(fā)生什么,此時(shí)我們用命令模式來設(shè)計(jì),來解開按鈕和負(fù)責(zé)具體行為對象間的耦合,代碼如下所示。

    <script>
        let btns = document.querySelectorAll('button');
        // 寫一個(gè)刷新命令
        let refreshCommand = {
            execute () {
                console.log("刷新頁面");
            }
        }
        // 寫一個(gè)登錄按鈕命令
        let loginCommand = {
            execute () {
                console.log("執(zhí)行登錄操作");
            }
        }
        let setCommand = function( button, command) {
            button.onclick = function() {
                command.execute();
            }
        }
        // 假如第三個(gè)按鈕用來負(fù)責(zé)刷新頁面,第五個(gè)用來負(fù)責(zé)登錄操作
        setCommand( btns[2], refreshCommand);
        setCommand( btns[4], loginCommand);  

分析:我們將點(diǎn)擊按鈕后可能會(huì)發(fā)生的事件分別封裝起來,它們中各自有自己的 execute 函數(shù),我們將安裝按鈕功能的函數(shù)封裝到了 setCommand 中,最后根據(jù)需求對應(yīng)安裝各個(gè)按鈕的功能便可。

三. 命令模式的撤銷操作

下達(dá)一個(gè)命令后,我們可能不需要了,想回到下達(dá)命令之前的狀態(tài),就需要用到撤銷操作,撤銷操作的實(shí)現(xiàn)一般是給命令對象增加一個(gè) undo 或者 unexecute 方法,在其中執(zhí)行 execute 的反向操作。

// 假如寫一個(gè)人物向左移的命令
let moveLeftCommand = {
    execute() {
        console.log("人物向左移動(dòng)");
}
    undo (){
        console.log("人物向又移動(dòng)");
}
}

這種是簡單的邏輯實(shí)現(xiàn),假如有些撤銷行為無法用執(zhí)行他的反向操作來實(shí)現(xiàn),那我們應(yīng)該怎么辦呢?

帶著這個(gè)問題我們學(xué)習(xí)一種新的達(dá)到撤銷的方式,我們用一個(gè)棧來記錄每一步命令,想要撤銷,我們只需要重頭開始,從棧中拿出命令來分別執(zhí)行,將最后一次命令刪除即可。如果不刪除最后一次命令依次執(zhí)行,我們又實(shí)現(xiàn)了一個(gè)新的功能,重播。

這是一個(gè)通過 WASD 來控制小球移動(dòng)的代碼實(shí)現(xiàn),我們每次按下一個(gè)有效命令時(shí),便會(huì)將該命令推入 commandStack 中來記錄小球的變化,當(dāng)點(diǎn)擊重播時(shí)小球會(huì)按照之前同樣的軌跡運(yùn)動(dòng)。

        let role = document.getElementById('role');
        
        let move = {
            dom: role,
            leftt:0,
            top: 0,
            up() {
                console.log("向上");
                this.top -= 10;
                this.dom.style.top = this.top + 'px';
            },
            down(){
                console.log("向下");
                this.top += 10;
                this.dom.style.top = this.top + 'px';
            },
            left() {
                console.log("向左");
                this.leftt -= 10;
                this.dom.style.left = this.leftt + 'px';
            },
            right() {
                console.log("向右");
                this.leftt += 10;
                this.dom.style.left = this.leftt + 'px';
            }
        }
        commands = {
            "119": "up",      // W
            "115": "down",    // S
            "97": "left",    // A
            "100": "right"     // D
        };
        commandStack = []; // 保存命令的堆棧
        let setCommand = function (receiver, state) {
            return function() {
                receiver[state]();
            }
        }
        document.addEventListener('keypress', (e) => {
            let code = e.charCode;
            if(!commands[code]) {
                return ;
            }
            let command = setCommand(move, commands[code]);
            if( command ) {
                command();
                commandStack.push( command );
            }
        })
        // 設(shè)置重播按鈕
        document.getElementById('replay').onclick = function() {
            let command;
            while(command = commandStack.shift()) {
                command();
            }
        }

四. 宏命令

宏命令就是一組命令的集合,通過執(zhí)行宏命令可以一次執(zhí)行一批命令。

通俗來說就是,有一件事你需要重復(fù)做,并且做這件事的每一步都是固定不變的,那么我們可以將做這件事情的所有步驟打包起來,只需要啟動(dòng),便可以自動(dòng)完成所有步驟。

需求:實(shí)現(xiàn)一個(gè)游戲自動(dòng)刷副本的腳本

?        let MacroCommand = function() {
            return {
                commandList: [],
                add( command ) {
                    this.commandList.push(command);
                },
                execute () {
                    for(let i = 0,command; command = this.commandList[i++];){
                        command.execute();
                    }
                }
            }
        }
        let startGameCommand = {
            execute() {
                console.log('開始游戲')
            }
        }
        let killGhostCommand = {
            execute() {
                console.log('打怪')
            }
        }
        let giftCommand = {
            execute() {
                console.log("領(lǐng)取獎(jiǎng)勵(lì)")
            }
        }
        let outGameCommand = {
            execute() {
                console.log("退出游戲")
            }
        }
        let Game = MacroCommand();
        Game.add(startGameCommand);
        Game.add(killGhostCommand);
        Game.add(giftCommand);
        Game.add(outGameCommand);
        Game.execute();  

我們只需要為宏命令對列中添加命令,它會(huì)自動(dòng)執(zhí)行里邊的所有命令。我們只負(fù)責(zé)啟動(dòng),其他的就不需要我們管了,我們可以放心的去做其他事情,等待它自己完成。

五. 總結(jié)

命令模式中也提到了傻瓜命令智能命令,它兩的區(qū)別在于傻瓜命令中含有命令的接收者,而智能命令沒有,它直接提供請求。智能命令與策略模式十分相近,只是在使用上不同,策略模式中對象的目標(biāo)相同,只是實(shí)現(xiàn)目標(biāo)的算法不同,而命令模式的目標(biāo)更具有散發(fā)性。命令模式還可以完成撤銷、排隊(duì)的功能。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

最新評(píng)論