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

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

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

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

  • 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. JavaScript正则中\1\2的作用

    一.示例 1. 验证6个相同的数字 var reg = new RegExp(/^(\d)\1{5}/g); var a = '333333'; if(reg.test(a)) { alert('ri ...

  2. 常用代码块:java使用系统浏览器打开url

    方法一:用于windows try { Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler "+url) ...

  3. 斯坦福大学Andrew Ng - 机器学习笔记(2) -- 逻辑回归 & 正则化

    大概用了一个月,Andrew Ng老师的机器学习视频断断续续看完了,以下是个人学习笔记,入门级别,权当总结.笔记难免有遗漏和误解,欢迎讨论. 鸣谢:中国海洋大学黄海广博士提供课程视频和个人笔记,在此深 ...

  4. 怎样使用Chrome模拟手机浏览器測试移动端网站

    作者:zhanhailiang 日期:2014-10-10 环境说明: Chrome 37.0.2062.124 m 1. 通过[菜单→工具→开发人员工具|Javascript控制台]或[快捷键Ctr ...

  5. 解决vsftp &quot;上传 553 Could not create file&quot;

    这个问题仅仅要:       1. setsebool -P ftpd_disable_trans 1       2. service vsftpd restart       太纠结了,呵呵

  6. ABAP锁,数据库锁

    原文出自 江正军 技术博客,博客链接:www.cnblogs.com/jiangzhengjun ABAP数据锁定 SM12锁查看与维护 通用加锁与解锁函数 ABAP程序锁定 数据库锁 锁的分类和兼容 ...

  7. Some day some time we will do

    Age has been reached the end of the beginning of the world,May be guilty in his seems to passing a l ...

  8. 基于CentOS的SSHD服务的Docker镜像

    原文地址 1.Dockerfile文件 FROM registry.aliyuncs.com/acs-sample/centos:6 MAINTAINER xuqh "xqh_163@163 ...

  9. 请写一个python逻辑,计算一个文件中的大写字母数量

    import os os.chdir(r'C:\Users\Administrator\Desktop')#os.chdir切换到指定目录 with open('a.txt') as today: c ...

  10. Git配置出现的问题

    git是代码版本同步工具,适用于团队开发,进公司第一堂课就是配置Git.接下来就把其中遇到的问题记录一下,与大家共享一下. 首先,在Bitbucket上注册账户,之后给管理员说一下,让他邀请你加入开发 ...