JS设计模式(13)状态模式
什么是状态模式?
定义:将事物内部的每个状态分别封装成类,内部状态改变会产生不同行为。
主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
何时使用:代码中包含大量与对象状态有关的条件语句。
如何解决:将各种具体的状态类抽象出来。
应用实例: 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)状态模式的更多相关文章
- js设计模式——5.状态模式
js设计模式——5.状态模式 代码演示 /*js设计模式——状态模式*/ // 状态(红灯,黄灯,绿灯) class State { constructor(color) { this.color = ...
- 【转】设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- JS设计模式——5.单体模式
JS设计模式——5.单体模式 http://www.cnblogs.com/JChen666/p/3610585.html 单体模式的优势 用了这么久的单体模式,竟全然不知!用它具体有哪些好处呢? ...
- 设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- 乐在其中设计模式(C#) - 状态模式(State Pattern)
原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...
- 折腾Java设计模式之状态模式
原文地址 折腾Java设计模式之状态模式 状态模式 在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式.在状态模式中,我们创建表示各种状态的对象 ...
- 北风设计模式课程---状态模式State(对象行为型)
北风设计模式课程---状态模式State(对象行为型) 一.总结 一句话总结: 状态模式 具体状态的行为在具体的状态类中就解决,不用交给外部做判断.实质是将多条件判断弄成了多个类,在不同的类中做判断 ...
- js设计模式——7.备忘录模式
js设计模式——7.备忘录模式 /*js设计模式——备忘录模式*/ // 备忘类 class Memento { constructor(content) { this.content = conte ...
- js设计模式——6.模板方法模式与职责链模式
js设计模式——6.模板方法模式与职责链模式 职责链模式
- js设计模式——4.迭代器模式
js设计模式——4.迭代器模式 代码演示 /*js设计模式——迭代器模式*/ class Iterator { constructor(container) { this.list = contain ...
随机推荐
- JBPM工作流(五)——执行流程实例
概念: ProcessInstance,流程实例:代表流程定义的一次执行.如:张三昨天按请假流程请了一次假.一个流程实例包括了所有运行阶段,其中最典型的属性就是跟踪当前节点的指针,如下图. Execu ...
- 【C++/类与对象总结】
1.以上是对本章知识的大致梳理,下面通过我自己在编程中遇到的问题再次总结. 私有成员必须通过get()函数访问吗?能不能直接调用? 私有成员必须通过公共函数接口去访问,比如设置set()修改成员内容, ...
- ArcGIS AddIN Sample学习笔记
1.AddInEditorExtension 功能描述:编辑器扩展,实现在编辑要素,对编辑事件的监听,及对新创建的要素的处理 核心代码: void Events_OnStartEditing() { ...
- Linux上传文件与执行
ls ——查看文件夹 mkdir——新建文件夹 cd:——进入文件 nohup python3 文件名.py & ——让代码在后台运行 ps -aux | grep 文件——查看进程 ps-a ...
- linux考试题改错
符号链接和硬链接有什么区别? 改:符号链接存储文件路径,可以指向不同分区文件,源文件删除后失效. 改:硬链接指向文件索引节点,仅能指向同一分区文件,源文件删除后可以访问. 请描述文件和目录9位权限位的 ...
- MySql的主从复制以及读写分离详解
MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践 Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过.但在实际的生产环境中, ...
- linux ---部署django项目篇
uWSGI + nginx+ django + virtualenv + supervisor发布web服务器 项目部署步骤 1.项目准备阶段 1.准备项目代码,从本地拷贝 2.将项目上传到linux ...
- Centos Linux 下Pycharm 安装
原文链接 :https://www.cnblogs.com/shaosks/p/9173806.html 可以通过浏览器访问http://www.jetbrains.com/pycharm/,选择需要 ...
- python的var_dump,打印对象内容
from __future__ import print_function from types import NoneType __author__ = "Shamim Hasnath&q ...
- html,CSS,javascript 做一个弹窗
弹窗的工作原理:在网页中写一个div ,布局到想要显示的位置,将display设为none,隐藏该div.然后通过点击事件或其他操作,利用Js代码,将display设置为block,将div 显示到网 ...