状态模式,在大的范畴中的定义为当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。每种编程语言有不同的实现方式,运用的范围也多用于游戏之中。 这里我用javascript来模拟状态模式,主要思想是通过事件监听的效果来控制一个主要对象的状态。那么何为事件监听的 ...
状态模式,在大的范畴中的定义为当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。每种编程语言有不同的实现方式,运用的范围也多用于游戏之中。
这里我用javascript来模拟状态模式,主要思想是通过事件监听的效果来控制一个主要对象的状态。那么何为事件监听的效果呢?在其他语言中,可以通过多个对象的协作来完成状态模式,而我在javascript中可以通过对DOM节点进行事件操控来传递消息,使主要对象接收消息(当然不同状态接收到的消息所产生的反应是不一样的)。而在javascript中模拟状态模式的首要步骤,就是选出这个主要对象,并且对其他对象进行DOM控制,这听起来有些抽象,下面会有一个大致的状态转移图来让大家理解理解。
我们来详细地介绍下上图的相关对象及状态:
1.Leader : 这是这个状态模式例子中的主要对象,通过其他对象对他发送的消息来进行一些状态上的变化。
2.Player : 这是一个发送消息的对象,我们在下文把他称之为简单对象P,通过它来发送消息给主要对象。
3.Reporter : 这是一个发送消息的对象,我们在下文把他称之为简单对象R,通过它来发送小心给主要对象。
图中有一些箭头,代表的是消息发送,而矩形框里面代表着leader的状态。
可以看到当简单对象P向主要对象Leader发送一个PlayerWaveHands的消息时,Leader状态来到Leader_WaveHandsState。然后超时后返回原状态。
这里要说一点的是上图中的超时等会我们都会用一个点击事件给替代。
接着进入代码部分,没错,类与状态之间的关系确实有点难以下手。但是要理清楚的是"谁"收到了什么"消息",在条件允许的情况下,转换到另一个"状态",从而获取新状态下的方法。
"谁":指的是主要对象,也就是Leader。这个Leader需要能够接受消息,因此可以有一个能接受并反馈消息的方法,最重要的是这个消息必须在某种状态下才能对主要对象产生有效的影响,即状态转移。所以可以看出,Leader类需要有处理消息的外部接口,同时这个接口要保证消息与状态的对应,因此,Leader还需要有一个状态指针,指向某一个状态。
"消息":指的是其他简单对象向主要对象发送的消息,这个消息可以通过事件点击触发,上文也提到过,这里的简单对象用DOM实现。因此简单对象不需要有一个具体的类,这是鉴于js与html dom之间的特殊关系。不同于C++等其他语言。
"在条件允许的情况下":指的是对应的状态才能接受对应的消息,显然这里就必须要有一个基本状态类State类(里面有公共方法),和继承于这个State类的其他状态类。
"另一个状态":指的是收到正确的消息后转换后的一个状态,说明在一个状态中必定有转移到另一个状态的接口方法。
上述蓝色加深的字已经将整个类图说的很详细了。总结如下图:
同时我们再加上在主席走路的状态下有苍蝇骚扰,再其他状态下不能骚扰。若骚扰则主席将它赶跑。
有了完整的类图,我们就可以开始完成整个代码了。由于代码有500行之多,接下来我会在每段代码后进行相应的讲解注释。
main.html:
<!doctype html><html lang="en"><head> <meta charset="utf-8"></head><body> <input type="button" value="主席步行" id="walk" /> <input type="button" value="主席演讲" id="speech" /> <input type="button" value="群众们向主席挥手" id="waveHands" /> <input type="button" value="电视采访靠近毛主席" id="faceRe"/> <input type="button" value="电视采访向毛主席敬礼" id="SaluteToRe"/> <input type="button" value="主席命令整理队伍" id="command"/> <input type="button" value="主席开始跑步" id="run"/> <input type="button" value="苍蝇过来骚扰" id="come"/> <input type="button" value="赶走苍蝇" id="leave"/> <script type="text/javascript" src='/images/loading.gif' data-original="State.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="Leader.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="ReadyState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="WalkingState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="SpeechState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="WaveHandsState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="FaceReporterState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="SaluteToReportState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="CommandLineUpState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="RunState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="Fly.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="flyState.js"></script> <script type="text/javascript" src='/images/loading.gif' data-original="leaveState.js"></script> <script type="text/javascript"> var oLeader = new Leader(); var oFly = new Fly(oLeader); var $ = function(id){ return document.getElementById(id); } $("walk").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oLeader.Leader_WalkingState(); } $("speech").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oLeader.Leader_SpeechState(); } $("waveHands").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oLeader.Leader_WaveHandsState(); }; $("faceRe").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oLeader.Leader_FaceReporterState(); }; $("SaluteToRe").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oLeader.Leader_SaluteToReportState(); }; $("command").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oLeader.Leader_CommandLineUpState(); }; $("run").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oLeader.Leader_RunState(); }; $("come").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oFly.Fly_getFlys(); }; $("leave").onclick = function(){ console.log("触发的消息------"); console.log(this.value+":"); oFly.Fly_getLeaveS(); }; </script></body></html>
原标题:js中State模式的解析及运用
关键词:JS
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。