赞
踩
目录
状态模式的一个模型——有限状态机 Finite-state machine
状态模式的定义
状态模式:当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来像是改变了对象。
类型:对象行为型模式
用途:解决系统中复杂对象的状态转换以及不同状态下行为的封装问题
使用场景:
优点:
缺点:
状态模式的一个模型——有限状态机 Finite-state machine
日常开发中很多具有多种状态的对象,都可以用有限状态机模型来模拟,一般都具有以下特点:
github上有一个有限状态机的函数库javascript-state-machine,可以了解一下
https://github.com/jakesgordon/javascript-state-machine
演示范例1 —— 状态模式实现对话框的显示和隐藏
- var Dialog = function(){
- var _state = null;
-
- this.setState = function(state){
- _state = state;
- }
- this.getState = function(){
- return _state;
- }
- }
-
- var ShowState = function(){
- this.doAction = function(dialog){
- console.log("对Dialog设置显示状态:");
- dialog.setState(this);
- }
- this.toString = function(){
- console.log("显示中......");
- }
- }
-
- var HideState = function(){
- this.doAction = function(dialog){
- console.log("对Dialog设置隐藏状态:");
- dialog.setState(this);
- }
- this.toString = function(){
- console.log("已隐藏......");
- }
- }
-
- var dialog = new Dialog();
-
- var showState = new ShowState();
- var hideState = new HideState();
-
- showState.doAction(dialog);
- //对Dialog设置显示状态:
- dialog.getState().toString();
- //显示中......
- hideState.doAction(dialog);
- //对Dialog设置隐藏状态
- dialog.getState().toString();
- //已隐藏......

例子里Dialog对象有两种状态,显示和隐藏,我把两种状态提取出来,使得状态的管理更加灵活。在这个例子里面Dialog称之为环境类,环境类又称为上下文类,他拥有多种状态。环境类内部需要维护一个state对象用来定义当前状态。HideState,ShowState称之为状态类,对应环境类的一个具体状态,toString称之为状态类的行为,每一个状态类的行为都有所不同。
演示范例2 —— 状态模式实现角色扮演游戏(如魂斗罗)
- class Contra {
- constructor () {
- //存储当前待执行的动作 们
- this._currentstate = {};
- }
- //添加动作
- changeState (){
- //清空当前的动作集合
- this._currentstate = {};
- //遍历添加动作
- Object.keys(arguments).forEach(
- (i) => this._currentstate[arguments[i]] = true
- )
- return this;
- }
- //执行动作
- contraGo (){
- //当前动作集合中的动作依次执行
- Object.keys(this._currentstate).forEach(
- (k) => Actions[k] && Actions[k].apply(this)
- )
- return this;
- }
- };
-
- const Actions = {
- up : function(){
- //向上跳
- console.log('up');
- },
- down : function(){
- //趴下
- console.log('down');
- },
- forward : function(){
- //向前跑
- console.log('forward');
- },
- backward : function(){
- //往老家跑
- console.log('backward');
- },
- shoot : function(){
- //开枪吧
- console.log('shoot');
- },
- };
- var littlered = new Contra();
- littlered.changeState('shoot','up').contraGo();

控制台会输出: shoot up
状态模式,将条件判断的结果转化为状态对象内部的状态(代码中的up,down,backward,forward),内部状态通常作为状态对象内部的私有变量(this._currentState),然后提供一个能够调用状态对象内部状态的接口方法对象(changeState,contraGo),这样对状态的改变,对状态方法的调用的修改和增加也会很容易,方便了对状态对象中内部状态的管理。
同时,状态模式将每一个条件分支放入一个独立的类中,也就是代码中的Actions。这使得你可以根据对象自身的情况将对象的状态(动作——up,down,backward,forward)作为一个对象(Actions.up,Actions.down这样),这一对象可以不依赖于其他对象而独立变化(一个行为一个动作,互不干扰)。
可以看出,状态模式就是一种适合多种状态场景下的设计模式,改写之后代码更加清晰,提高代码的维护性和扩展性,不用再牵一发动全身
演示范例3 —— 状态模式实现红绿灯
- var trafficLight = (function () {
- var currentLight = null;
- return {
- change: function (light) {
- currentLight = light;
- currentLight.go();
- }
- }
- })();
-
- function RedLight() { }
- RedLight.prototype.go = function () {
- console.log("this is red light");
- }
- function GreenLight() { }
- GreenLight.prototype.go = function () {
- console.log("this is green light");
- }
- function YellowLight() { }
- YellowLight.prototype.go = function () {
- console.log("this is yellow light");
- }
-
- trafficLight.change(new RedLight());
- trafficLight.change(new YellowLight());

trafficLight是一个红绿灯的实例,传入一个构造函数,对象暴露change方法改变内部状态,也就是灯的颜色,change接收的同样是一个状态的对象,调用对象的方法触发响应的动作,这里的动作都叫go,不同颜色的灯对象有着不同的go的实现。
通过传入灯对象到change方法中,从而改变红绿灯的状态,触发其相应的处理程序,这就是一个典型的状态模式的应用。
更多设计模式详见——js设计模式【详解】总目录
https://blog.csdn.net/weixin_41192489/article/details/116154815
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。