什么是状态模式?

定义:将事物内部的每个状态分别封装成类,内部状态改变会产生不同行为。

主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

何时使用:代码中包含大量与对象状态有关的条件语句。

如何解决:将各种具体的状态类抽象出来。

应用实例: 1、打篮球的时候运动员可以有正常状态、不正常状态和超常状态。 2、曾侯乙编钟中,'钟是抽象接口','钟A'等是具体状态,'曾侯乙编钟'是具体环境(Context)。

优点: 1、封装了转换规则。 2、枚举可能的状态,在枚举状态之前需要确定状态种类。 3、将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 4、允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 5、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

缺点: 1、状态模式的使用必然会增加系统类和对象的个数。 2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。 3、状态模式对"开闭原则"的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码。

使用场景: 1、行为随状态改变而改变的场景。 2、条件、分支语句的代替者。

注意事项:在行为受状态约束的时候使用状态模式,而且状态不超过 5 个。

场景 demo

某某牌电灯,按一下按钮打开弱光,按两下按钮打开强光,按三下按钮关闭灯光。

// 将状态封装成不同类
const weakLight = function(light) {
this.light = light
} weakLight.prototype.press = function() {
console.log('打开强光')
this.light.setState(this.light.strongLight)
} const strongLight = function(light) {
this.light = light
} strongLight.prototype.press = function() {
console.log('关灯')
this.light.setState(this.light.offLight)
} const offLight = function(light) {
this.light = light
} offLight.prototype.press = function() {
console.log('打开弱光')
this.light.setState(this.light.weakLight)
} const Light = function() {
this.weakLight = new weakLight(this)
this.strongLight = new strongLight(this)
this.offLight = new offLight(this)
this.currentState = this.offLight // 初始状态
} Light.prototype.init = function() {
const btn = document.createElement('button')
btn.innerHTML = '按钮'
document.body.append(btn)
const self = this
btn.addEventListener('click', function() {
self.currentState.press()
})
} Light.prototype.setState = function(state) { // 改变当前状态
this.currentState = state
} const light = new Light()
light.init() // 打开弱光
// 打开强光
// 关灯

非面向对象实现的状态模式

借助于 JavaScript 的委托机制,可以像如下实现状态模式:

const obj = {
'weakLight': {
press: function() {
console.log('打开强光')
this.currentState = obj.strongLight
}
},
'strongLight': {
press: function() {
console.log('关灯')
this.currentState = obj.offLight
}
},
'offLight': {
press: function() {
console.log('打开弱光')
this.currentState = obj.weakLight
}
},
} const Light = function() {
this.currentState = obj.offLight
} Light.prototype.init = function() {
const btn = document.createElement('button')
btn.innerHTML = '按钮'
document.body.append(btn)
const self = this
btn.addEventListener('click', function() {
self.currentState.press.call(self) // 通过 call 完成委托
})
} const light = new Light()
light.init()

JS设计模式(13)状态模式的更多相关文章

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

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

  2. 【转】设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  3. JS设计模式——5.单体模式

    JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html   单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...

  4. 设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  5. 乐在其中设计模式(C#) - 状态模式(State Pattern)

    原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...

  6. 折腾Java设计模式之状态模式

    原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...

  7. 北风设计模式课程---状态模式State(对象行为型)

    北风设计模式课程---状态模式State(对象行为型) 一.总结 一句话总结: 状态模式 具体状态的行为在具体的状态类中就解决,不用交给外部做判断.实质是将多条件判断弄成了多个类,在不同的类中做判断 ...

  8. js设计模式——7.备忘录模式

    js设计模式——7.备忘录模式 /*js设计模式——备忘录模式*/ // 备忘类 class Memento { constructor(content) { this.content = conte ...

  9. js设计模式——6.模板方法模式与职责链模式

    js设计模式——6.模板方法模式与职责链模式 职责链模式

  10. js设计模式——4.迭代器模式

    js设计模式——4.迭代器模式 代码演示 /*js设计模式——迭代器模式*/ class Iterator { constructor(container) { this.list = contain ...

随机推荐

  1. gitlab的fork及源项目的同步

    此篇大部分貌似是cp其他地方的,也忘了出处,写到此处,权当保存,见谅. 测试代码master同步到生产代码master   #现有git@gitlab.home.com:root/fork.git项目 ...

  2. java基础编程

    java的类和常用编程模式还是要多练习,多手写java代码 return new String(filecontent, encoding); 看懂这个意思了吗?第一次见这个构造函数吧,而String ...

  3. 赶鸭子上架的cdq分治

    前置技能:归并排序,树状数组. cdq分治主要是用来离线解决一些奇怪的问题的.可以用来代替一些高级数据结构比如树套树或者KD-Tree之类的... 话说挑战2上的KD-Tree我到现在还没开始学... ...

  4. weblogic反序列化漏洞CVE-2018-2628-批量检测脚本

    #coding=utf-8 import socket import time import re,os,sys,codecs type = 'utf-8' reload(sys) sys.setde ...

  5. ArcGIS AddIn调用ArcMap自带的对话框

    ESRI.ArcGIS.Framework命名空间提供了ArcGIS常用的一些对话框,可以在开发时直接调用这些对话框,而不需要重新去写Form 主要对话框有 1.IColorBrowser/IColo ...

  6. python 字符类型

    1.整型 int 短整型在window中是2**30--2**39 长整型 long 在python中不区分长短 2.浮点数 float 一般是小数 3.复数 4.boolen类型(布尔类型) 运算结 ...

  7. jquery chrome中取select 的值一就返回了

    在 <div class="controls"> <select class="span2" data-val="true" ...

  8. hive on spark配置

    1.安装java.maven.scala.hadoop.mysql.hive 略 2.编译spark ./make-distribution.sh --name "hadoop2-witho ...

  9. 添加一个Activity

    #Android中增加一个Activity 1. 在AndroidManifest.xml中增加: <activity android:name="com.example.NewAct ...

  10. MAVEN day04 SSH之分模块开发

    一.创建父工程 1.选择>>"Maven Project"创建Maven工程.并且选择Packaging为 POM. 创建父工程主要是让子工程区继承父工程,减少冗余,多 ...