JavaScript设计模式_06_命令模式

命令模式是比较简答的设计模式,它最常应用于以下场景:有时候需要向某些对象发送请求,但是并不知道请求接收者是谁,也不知道被请求的操作是什么。这时希望用一种松耦合的方式来设计程序,使得请求发送者和接受者能消除彼此之间的耦合关系。

/**
 * pre: 命令模式
 * 
 */
//-------------- 示例1 ---------------
/**
 * 例如页面上有三个按钮,对应的功能分别是:刷新菜单、增加子菜单和删除子菜单,
 * 我们将三个功能用命令的模式实现:
 * 
 */
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");

var setCommand = function(button, command) {
    button.onclick = function() {
        command.execute();
    };
};
var menuBar = {
    refresh: function() {
        console.log("刷新菜单栏目录.");
    }
};
var subMenu = {
    add: function() {
        console.log("增加子菜单.");
    },
    del: function() {
        console.log("删除子菜单.");
    }
};
var refreshMenuBarCmd = function(receiver) {
    this.receiver = receiver;
    return {
        execute: function() {
            receiver.refresh();
        }
    }
};
var addSubMenuCmd = function(receiver) {
    this.receiver = receiver;
    return {
        execute: function() {
            receiver.add();
        }
    }
};
var delSubMenuCmd = function(receiver) {
    this.receiver = receiver;
    return {
        execute: function() {
            receiver.del();
        }
    }
};
setCommand(btn1, refreshMenuBarCmd(menuBar));
setCommand(btn2, addSubMenuCmd(subMenu));
setCommand(btn3, delSubMenuCmd(subMenu));
/*
 * 命令模式的好处:将过程式的请求调用封装在command对象的execute方法中,可四处传递,客户端不需关系如何执行。
 */

//--------------- 示例2 -------------
/* 宏命令:一组命令集合
 *   比如到家开门后,自动打开电脑,登录QQ,
 * 我们将这一系列动作组合起来执行。
 */
var openDoorCmd = {
    execute: function() {
        console.log("开门.");
    }
};
var openPcCmd = {
    execute: function() {
        console.log("开电脑.");
    }
};
var loginQQCmd = {
    execute: function() {
        console.log("登录QQ.");
    }
};
var MarcoCmd = function() {
    var cmdList = [],
        add, execute;
    add = function(obj) {
        cmdList.push(obj);
    };
    execute = function() {
        if(!cmdList.length == 0) {
            for(var obj of cmdList) {
                obj.execute.apply(this);
            }
        }
    };
    return {
        add: add,
        execute: execute
    }
};
var marcoCmd = MarcoCmd();
marcoCmd.add(openDoorCmd);
marcoCmd.add(openPcCmd);
marcoCmd.add(loginQQCmd);
marcoCmd.execute();
posted @ 2017-06-19 17:02  Stinchan  阅读(170)  评论(0编辑  收藏  举报