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();
作者:『Stinchan』
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。