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

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

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

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

  • 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. 【Windows下DLL查找顺序 】

    一.写作初衷 在Windows下单个DLL可能存在多个不同的版本,若不特别指定DLL的绝对路径或使用其他手段指定,在应用程序加载DLL时可能会查找到错误的版本,进而引出各种莫名其妙的问题.本文主要考虑 ...

  2. CSS 关于让页面的高度达到电脑屏幕的底部

    .sidebar:before {content: "";display: block;width: 190px;position: fixed;bottom: 0;top: 0; ...

  3. Time-series Storage Layer Time Series Databases 时间序列

    w 关于时间序列数据库的思考-CSDN.NET  http://www.csdn.net/article/2015-07-13/2825192  存储和处理时间序列数据(“Time Series Da ...

  4. 洛谷 P3393 逃离僵尸岛

    洛谷 这道题目其实是最短路裸题. 首先看到题目,要求的到"被占点"距离不大于S的点,自然想到了以"被占点"为源点,求一遍最短路,处理出"危险点&quo ...

  5. 涉及到复制和二进制日志中的选项和变量-Replication and Binary Logging Options and Variables

    在搭建复制中,有些参数需要我们留意,在这里罗列出来,供大家参考一下,以GTID为基础 --server-id server-id:这是一个全局的可动态调整的变量,取值范围为0-4294967295,也 ...

  6. STL学习笔记— —容器map和multimap

    简单介绍 在头文件<map> 中定义 namespace std { template <typename Key, typename T, typename Compare = l ...

  7. Scilab 的画图函数(2)

    一幅图是由很多元素组成的. 包含图标题.x轴标签.y轴标签,刻度线等.图1给出了各个元素的一个示意图. 这些全部的元素在scilab中都是能够用代码控制的. 标题 上个笔记上介绍了用xtitle()函 ...

  8. hadoop学习第四天-Writable和WritableComparable序列化接口的使用&&MapReduce中传递javaBean的简单例子

    一. 为什么javaBean要继承Writable和WritableComparable接口? 1. 如果一个javaBean想要作为MapReduce的key或者value,就一定要实现序列化,因为 ...

  9. Loadrunder场景设计篇——手工场景设计

    概述 通过选择需要运行的脚本,分配运行脚本的负载生成器,在脚本中分配Vuser来建立手工场景 手工场景就是自行设置虚拟用户的变化,主要是通过设计用户的添加和减少过程,来模拟真实的用户请求模型,完成负载 ...

  10. 小程序学习第二天 认识框架WXML

    一.初级小程序HelloWorld 心得: (1)progect.config.json :app的个性化设置 (2)一个小程序至少包括两个文件 (2.1)app.json 小程序全局配置       ...