• JavaScript设计模式_13_状态模式


    状态模式是一种根据事物内部状态的改变,从而改变事物行为的一种模式。

    /**
     * pre:状态模式
     */
    //---------- 示例1 ----------------
    /**
     * 模拟电灯开关
     */
    var Light = function() {
        this.state = "off";
        this.button = null;
    };
    Light.prototype.init = function() {
        var button = document.createElement("button");
        var _self = this;
        button.innerHTML = "开关";
        this.button = document.body.appendChild(button);
        this.button.onclick = function() {
            _self.buttonWasPressed();
        };
    };
    Light.prototype.buttonWasPressed = function() {
        var _self = this;
        var onEvent = function() {
            _self.state = "on";
            console.log("开灯");
        };
        var offEvent = function() {
            _self.state = "off";
            console.log("关灯");
        };
        var operations = {
            "off": onEvent,
            "on": offEvent
        }
        return operations[_self.state]();
    };
    var light = new Light();
    light.init();
    //----------- 示例2 --------
    /**
     * [分析]:有另外一种电灯,按一次打开弱光,按两次打开强光,按三次关闭电灯。
     * 实现这一功能,我们需要对buttonWasPressed方法内部进行改造,增加另外一种状态事件。
     * 试想,如果在程序中,有N多种状态的切换,我们是不是要定义N多种状态,以及每种状态切换所发生的事件。
     * 若其中一个状态发生改变,还得去修改buttonWasPressed方法,使得复用性和可维护性大大降低。
     * 使用状态模式改写代码:
     */
    var offLightState = function(light) {
        this.light = light;
    };
    offLightState.prototype.buttonWasPressed = function() {
        console.log("弱光");
        this.light.setCurrentState(this.light.weakLightState);
    };
    var weakLightState = function(light) {
        this.light = light;
    };
    weakLightState.prototype.buttonWasPressed = function() {
        console.log("强光");
        this.light.setCurrentState(this.light.strongLightState);
    };
    var strongLightState = function(light) {
        this.light = light;
    };
    strongLightState.prototype.buttonWasPressed = function() {
        console.log("超级强光");
        this.light.setCurrentState(this.light.superStrongLightState);
    };
    var superStrongLightState = function(light) {
        this.light = light;
    };
    superStrongLightState.prototype.buttonWasPressed = function() {
        console.log("关灯");
        this.light.setCurrentState(this.light.offLightState);
    };
    var Light = function() {
        this.offLightState = new offLightState(this);
        this.weakLightState = new weakLightState(this);
        this.strongLightState = new strongLightState(this);
        this.superStrongLightState = new superStrongLightState(this);
        this.currentState = null; // 当前状态
        this.button = null; // 开关
    };
    Light.prototype.setCurrentState = function(state) {
        this.currentState = state;
    };
    Light.prototype.init = function() {
        var _self = this;
        var button = document.createElement("button");
        button.innerHTML = "开关";
        this.button = document.body.appendChild(button);
        this.currentState = this.offLightState;
        this.button.onclick = function() {
            _self.currentState.buttonWasPressed();
        };
    };
    var light = new Light();
    light.init();
    //---------------- 示例3 ----------------
    /**
     * 使用对象字面量重写
     */
    var Light = function() {
        this.currentState = FSM.off;
        this.button = null;
    };
    var FSM = {
        "off": {
            buttonWasPressed: function() {
                console.log("弱光");
                this.currentState = FSM.weak;
            }
        },
        "weak": {
            buttonWasPressed: function() {
                console.log("强光");
                this.currentState = FSM.strong;
            }
        },
        "strong": {
            buttonWasPressed: function() {
                console.log("关灯");
                this.currentState = FSM.off;
            }
        }
    };
    Light.prototype.init = function() {
        var _self = this;
        var button = document.createElement("button");
        button.innerHTML = "开关";
        this.button = document.body.appendChild(button);
        this.button.onclick = function() {
            _self.currentState.buttonWasPressed.call(_self);
        };
    };
    var light = new Light();
    light.init();
    //------------- 示例4 --------------
    /**
     * 使用委托进行重写
     */
    var delegate = function(client, delegation) {
        return {
            "buttonWasPressed": function() {
                delegation.buttonWasPressed.apply(client, arguments);
            }
        };
    };
    var Light = function() {
        this.button = null;
        this.offLightState = delegate(this, FSM.off);
        this.weakLightState = delegate(this, FSM.weak);
        this.strongLightState = delegate(this, FSM.strong);
        this.currentState = this.offLightState;
    };
    var FSM = {
        "off": {
            "buttonWasPressed": function() {
                console.log("弱光");
                this.currentState = this.weakLightState;
            }
        },
        "weak": {
            "buttonWasPressed": function() {
                console.log("强光");
                this.currentState = this.strongLightState;
            }
        },
        "strong": {
            "buttonWasPressed": function() {
                console.log("关灯");
                this.currentState = this.offLightState;
            }
        }
    };
    Light.prototype.init = function() {
        var _self = this;
        var button = document.createElement("button");
        button.innerHTML = "开关";
        this.button = document.body.appendChild(button);
        this.button.onclick = function() {
            _self.currentState.buttonWasPressed.call(_self);
        };
    }
    var light = new Light();
    light.init();
  • 相关阅读:
    luogu P1382 楼房
    luogu P1908 逆序对
    5.28 模拟赛
    POJ 2991 Crane
    残(矩阵快速幂)
    AC日记——拍照 洛谷 P3410
    AC日记——[CQOI2014]危桥 洛谷 P3163
    AC日记——【模板】二分图匹配 洛谷 P3386
    AC日记——[ZJOI2009]假期的宿舍 cogs 1333
    AC日记——城市 洛谷 P1401
  • 原文地址:https://www.cnblogs.com/stinchan/p/7065432.html
Copyright © 2020-2023  润新知