状态模式,从老生常谈的开关案例说起

状态模式,指的是事物内部状态的变化,会导致事物具体行为的变化。并且,状态的切换可以是循环的。最简单的例子是生活中的开关,基本都是状态模式的使用。

image.png

一、利用实例对象的切换

// 定义灯类
var Light = function () {
    this.currState = stateManager.off; // 灯的状态
    this.button = null; // 开关
};
Light.prototype.init = function () {
    var button = document.createElement('button'),
        self = this;
    button.innerHTML = '关灯';
    this.button = document.body.appendChild(button);
    this.button.onclick = function () {
        self.currState.changeState.call(self); // 把请求委托给 stateManager 状态机
    }
};
// 定义灯的状态管理对象
var stateManager = {
    off: {
        changeState: function () {
            this.button.innerHTML = '开灯';
            this.currState = stateManager.on;
        }
    },
    on: {
        changeState: function () {
            this.button.innerHTML = '关灯';
            this.currState = stateManager.off;
        }
    }
};
// 实例化灯
var light = new Light();
// 登初始化
light.init();

在当前例子中,首先定义灯类Light,其中有属性currState表示当前状态,button表示开关。定义的init方法会首先创建开关,再为开关绑定切换开关状态的函数changeState

定义的状态管理对象中包含属性offon的具体行为对象,每个行为的执行都是通过其中的changeState函数来实现,该函数触发时就会将当前灯的状态进行切换。

2、利用数组的有序性

// 定义灯的类
var Light = function () {
    this.currentIndex = 0; // 设置初始索引
    this.button = null; // 开关
};
Light.prototype.init = function () {
    var button = document.createElement('button'),
        self = this;
    button.innerHTML = '关灯';
    this.button = document.body.appendChild(button);
    this.button.onclick = function () {
        excuteStateFn(self);
    }
};
// 定义状态状态切换列表
var stateList = [
    function changeState(light) {
        light.button.innerHTML = '开灯';
    },
    function changeState(light) {
        light.button.innerHTML = '关灯';
    }
]
// 定义状态切换执行函数
function excuteStateFn(light) {
    light.currentIndex >= stateList.length && (light.currentIndex = 0); // 进行边界状态的控制
    stateList[light.currentIndex++](light) // 切换状态

}
// 实例化灯
var light = new Light();
// 灯进行初始化
light.init();

在当前例子中,首先定义灯类Light,其中有属性currentIndex表示行为对应的索引,button表示开关。定义的init方法会首先创建开关,再为开关绑定切换开关状态的函数excuteStateFn(self)

定义的状态切换列表中stateList包含数组元素offon的具体行为函数。

再定义行为切换执行函数excuteStateFn,每个行为的执行都是通过执行当前索引对应的行为函数stateList[light.currentIndex++](light)来实现的,通过修改当前索引的值来切换下一次执行的状态索引。

总结

状态模式的实现不止一种实现思路,可以利用行为函数执行时修改当前实例对象的状态实现,也可以利用数组天然的有序性通过索引的改变指向对应的执行函数,当然,还可能有其他实现方式。只要遵循状态模式状态的切换可以是循环的,任何实现都是正确的。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容