状态模式,当一个对象的内在状态改变时允许改变其行为,这个对象看起来是改变了其类。

状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

既然状态者模式是对已有对象的状态进行抽象,则自然就有抽象状态者类和具体状态者类,而原来已有对象需要保存抽象状态者类的引用,通过调用抽象状态者的行为来改变已有对象的行为。经过上面的分析,状态者模式的结构图也就很容易理解了,具体结构图如下图示。

从上图可知,状态者模式涉及以下三个角色:

  • Account类:维护一个State类的一个实例,该实例标识着当前对象的状态。
  • State类:抽象状态类,定义了一个具体状态类需要实现的行为约定。
  • SilveStater、GoldState和RedState类:具体状态类,实现抽象状态类的每个行为。

C#状态模式:

namespace 状态模式
{
class Program
{
static void Main(string[] args)
{
//紧急项目
Work emergencyProjects = new Work();
emergencyProjects.Hour = ;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = ;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = ;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = ;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = ;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = ; //emergencyProjects.WorkFinished = true;
emergencyProjects.TaskFinished = false; emergencyProjects.WriteProgram();
emergencyProjects.Hour = ;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = ;
emergencyProjects.WriteProgram(); Console.Read();
}
} //抽象状态
public abstract class State
{
public abstract void WriteProgram(Work w);
} //上午工作状态
public class ForenoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < )
{
Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", w.Hour);
}
else
{
w.SetState(new NoonState());
w.WriteProgram();
}
}
} //中午工作状态
public class NoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < )
{
Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", w.Hour);
}
else
{
w.SetState(new AfternoonState());
w.WriteProgram();
}
}
} //下午工作状态
public class AfternoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < )
{
Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", w.Hour);
}
else
{
w.SetState(new EveningState());
w.WriteProgram();
}
}
} //晚间工作状态
public class EveningState : State
{
public override void WriteProgram(Work w)
{
if (w.TaskFinished)
{
w.SetState(new RestState());
w.WriteProgram();
}
else
{
if (w.Hour < )
{
Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", w.Hour);
}
else
{
w.SetState(new SleepingState());
w.WriteProgram();
}
}
}
} //睡眠状态
public class SleepingState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("当前时间:{0}点 不行了,睡着了。", w.Hour);
}
} //下班休息状态
public class RestState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("当前时间:{0}点 下班回家了", w.Hour);
}
} //工作
public class Work
{
private State current;
public Work()
{
current = new ForenoonState();
} private double hour;
public double Hour
{
get { return hour; }
set { hour = value; }
} private bool finish = false;
public bool TaskFinished
{
get { return finish; }
set { finish = value; }
} public void SetState(State s)
{
current = s;
} public void WriteProgram()
{
current.WriteProgram(this);
}
}
}

状态者模式的应用场景

在以下情况下可以考虑使用状态者模式。

  • 当一个对象状态转换的条件表达式过于复杂时可以使用状态者模式。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。
  • 当一个对象行为取决于它的状态,并且它需要在运行时刻根据状态改变它的行为时,就可以考虑使用状态者模式。

javascript版本的状态机:

var Light = function(){
this.currState = FSM.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.buttonWasPressed.call(self); //把请求委托给FSM状态机
}
}; var FSM = {
off:{
buttonWasPressed:function(){
console.log('关灯');
this.button.innerHTML = '下一次按我是开灯';
this.currState = FSM.on;
}
},
on:{
buttonWasPressed:function(){
console.log('开灯');
this.button.innerHTML = '下一次按我是关灯';
this.currState = FSM.off;
}
}
}; var light = new Light();
light.init();

实际项目中的其他状态机:

var FSM = {
walk:{
attack:function(){
console.log('攻击');
},
defense:function(){
console.log('防御');
},
jump:function(){
console.log('跳跃');
}
}, attack:{
walk:function(){
console.log('攻击的时候不能行走');
},
defense:function(){
console.log('攻击的时候不能防御');
},
jump:function(){
console.log('攻击的时候不能跳跃');
}
}
};

状态模式的电灯程序:

var  Light = function(){
this.currState = FSM.off; //设置当前状态
}; Light.prototype.init = function(){
self = this; this.button.onclick = function(){
self.currState.buttonWasPressed.call(self); //把请求委托给FSM状态机
}
}; var FSM = {
off:{
buttonWasPressed:function(){
console.log('弱光');
this.currState = FSM.weak;
}
},
weak:{
buttonWasPressed:function(){
console.log('强光');
this.currState = FSM.strong;
}
},
strong:{
buttonWasPressed:function(){
console.log('关灯');
this.currState = FSM.off;
}
}
}; var light = new Light();
light.init();

状态模式-水的三态变化

用js模拟物理现象,实现水的三态变化,初中物理课我们都学过,物质具有三态变化,气态 -> 液态 -> 固态 或者 固态 -> 液态 -> 气态,但是不可以气态 -> 固态,或者固态 -> 气态,是需要经过液态过度的,否则就违反了自然规律。所以这种状态的变化非常适合用状态模式来实现。代码如下:

var Water = function(){
this.currState = FSM.gas; //设置当前状态
this.h3 = null;
}; Water.prototype.init = function(){
var button1 = document.createElement('button'),
button2 = document.createElement('button'),
button3 = document.createElement('button'),
h3 = document.createElement('h3'),
self = this; button1.innerHTML = '100度以上';
button1.onclick = function(){
self.currState.gas.call(self);
} button2.innerHTML = '0-100度';
button2.onclick = function(){
self.currState.liquid.call(self);
} button3.innerHTML = '0度以下';
button3.onclick = function(){
self.currState.solid.call(self);
} document.body.appendChild(button1);
document.body.appendChild(button2);
document.body.appendChild(button3);
this.h3 = document.body.appendChild(h3);
}; var FSM = {
gas:{ //气态
liquid:function(){
console.log('液态');
this.h3.innerHTML = '液态';
this.currState = FSM.liquid;
},
solid:function(){
console.log('气态不能变化为固态');
alert('气态不能变化为固态');
}
},
liquid:{ //液态
solid:function(){
console.log('固态');
this.h3.innerHTML = '固态';
this.currState = FSM.solid;
},
gas:function(){
console.log('气态');
this.h3.innerHTML = '气态';
this.currState = FSM.gas;
}
},
solid:{ //固态
gas:function(){
console.log('固态不能变化为气态');
alert('固态不能变化为气态');
},
liquid:function(){
console.log('液态');
this.h3.innerHTML = '液态';
this.currState = FSM.liquid;
}
}
};
var water = new Water();
water.init();

js状态模式的更多相关文章

  1. JS常用的设计模式(17)—— 状态模式

    状态模式主要可以用于这种场景 1 一个对象的行为取决于它的状态 2 一个操作中含有庞大的条件分支语句 回想下街头霸王的游戏. 隆有走动,攻击,防御,跌倒,跳跃等等多种状态,而这些状态之间既有联系又互相 ...

  2. js策略模式vs状态模式

    一.策略模式 1.定义:把一些小的算法,封装起来,使他们之间可以相互替换(把代码的实现和使用分离开来)2.利用策略模式实现小方块缓动 html代码: <div id="containe ...

  3. js设计模式——5.状态模式

    js设计模式——5.状态模式 代码演示 /*js设计模式——状态模式*/ // 状态(红灯,黄灯,绿灯) class State { constructor(color) { this.color = ...

  4. 8.js模式-状态模式

    1. 状态模式 var offLightState = function(light){ this.light = light; } offLightState.prototype.buttonWas ...

  5. 大熊君说说JS与设计模式之------状态模式State

    一,总体概要 1,笔者浅谈 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为模式. 状态模式主要解决的是当控制一个对象状态的条件表达式过于 ...

  6. JS设计模式(13)状态模式

    什么是状态模式? 定义:将事物内部的每个状态分别封装成类,内部状态改变会产生不同行为. 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为. 何时使用:代码中包含大 ...

  7. js 设计模式——状态模式

    状态模式 允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类. 简单的解释一下: 第一部分的意思是将状态封装成独立的类,并将请求委托给当前的状态对象,当对象的内部状态改变时,会带来 ...

  8. js之状态模式

    level01:电灯程序 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&q ...

  9. Javascript设计模式理论与实战:状态模式

    在软件开发中,很大部分时候就是操作数据,而不同数据下展示的结果我们将其抽象出来称为状态,我们平时开发时本质上就是对应用程序的各种状态进行切换并作出相应处理.状态模式就是一种适合多种状态场景下的设计模式 ...

随机推荐

  1. iOS反射:把对象直接转化成NSDictionary

    在IOS的网络编程中,通常我们需要将一些实体数据保存到NSDictionary,在获得NSDictionary后即可直接使用iOS 5后的NSJSONSerialization类型的dataWithJ ...

  2. webpack安装和简单配置

    1.webpack是一个基于node的项目,所以先装好node和npm       参考我的随笔:https://www.cnblogs.com/jtnote/p/6230384.html 2.先创建 ...

  3. Python3.6全栈开发实例[005]

    5.接收两个数字参数,返回比较大的那个数字. def compare(a,b): return a if a > b else b # 三元表达式 print(compare(20,100))

  4. 我的Android进阶之旅------>ListView中android:cacheColorHint,android:listSelector属性作用 .

    ( 本文转载于:http://blog.csdn.net/stonecao/article/details/6216449) 自定义listview的时候,当你不使用android:cacheColo ...

  5. ubuntu安装deb文件

    install the deb-package, e.g. using the Terminal command$ sudo apt install <path-to-smartgit-deb- ...

  6. Linux中vim命令出现E325错误解决方法

    出现该问题的原因是: vim在编辑文件的时候会创建一个swp file来保证文件的安全性,如果没有正常退出vim的,下次打开这个文件就会报E325的错误,提示swp文件已经存在. 解决方法也简单:把这 ...

  7. 003-ARP地址解析协议

    一.概念 地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议.主机发送信息时将包含目标IP地址的ARP请求广播到网络上的 ...

  8. 常用mongo语句

    只列出指定字段db.getCollection('PUBLICACCOUNTS').find({},{NickName:1,UserName:1,FID:1,_id:0})获取微信公众号列表db.ge ...

  9. jquery mobile 带参数跳转收集(紧个人使用,测试完会补全)

    //临时存储 var TempCache = { cache:function(value){ localStorage.setItem("EasyWayTempCache",va ...

  10. 06 Spring框架 依赖注入(三)多配置文件

    在Spring前几节的学习中我们都使用了一个配置文件,就像struts2中可以包含其他的配置文件,我们能不能使用多个配置文件呢(在工程比庞大,配置比较多的时候)? Spring多配置文件分为两种: 平 ...