JavaScript设计模式——状态模式
状态和行为:
所谓对象的状态,通常指的就是对象实例的属性的值;而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上。
状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的不同功能。也就是说,状态和行为是相关联的,它们的关系可以描述为:状态决定行为。
由于状态是在运行期被改变的,因此行为也会在运行期根据状态的改变而改变。
环境和状态处理对象:
在状态模式中,环境(Context)是持有状态的对象,但是环境(Context)自身并不处理跟状态相关的行为,而是把处理状态的功能委托给了状态对应的状态处理类来处理。
在具体的状态处理类中经常需要获取环境(Context)自身的数据,甚至在必要的时候会回调环境(Context)的方法,因此,通常将环境(Context)自身当作一个参数传递给具体的状态处理类。
看一个具体的实例:
1.State抽象类(当做接口):
var State = function () { }; State.prototype.download = function () {
throw new Error("该方法必须被重载!");
}; State.prototype.pause = function () {
throw new Error("该方法必须被重载!");
}; State.prototype.fail = function () {
throw new Error("该方法必须被重载!");
}; State.prototype.finish = function () {
throw new Error("该方法必须被重载!");
};
2.Download类:(所谓的环境类,存有状态属性)
var Download = function () {
this.oState = new ReadyState(this);
}; Download.prototype.setState = function (oState) {
this.oState = oState;
}; // 对外暴露的四个公共方法,以便外部调用 Download.prototype.download = function () {
this.oState.download();
}; Download.prototype.pause = function () {
this.oState.pause();
}; Download.prototype.fail = function () {
this.oState.fail();
}; Download.prototype.finish = function () {
this.oState.finish();
};
3.6种不同的状态(每种状态都会调用Download类的改变状态的方法,进行状态切换)
(1)准备状态:
var ReadyState = function (oDownload) {
State.apply(this);
this.oDownload = oDownload;
}; ReadyState.prototype = new State(); ReadyState.prototype.download = function () {
this.oDownload.setState(this.oDownload.getDownloadingState());
// Ready以后,可以开始下载,所以设置了Download函数里的状态获取方法
console.log("Start Download!");
}; ReadyState.prototype.pause = function () {
throw new Error("还没开始下载,不能暂停!");
}; ReadyState.prototype.fail = function () {
throw new Error("文件还没开始下载,怎么能说失败呢!");
}; ReadyState.prototype.finish = function () {
throw new Error("文件还没开始下载,当然也不能结束了!");
};
(2)
var DownloadingState = function (oDownload) {
State.apply(this);
this.oDownload = oDownload;
}; DownloadingState.prototype = new State(); DownloadingState.prototype.download = function () {
throw new Error("文件已经正在下载中了!");
}; DownloadingState.prototype.pause = function () { this.oDownload.setState(this.oDownload.getDownloadPausedState());
console.log("暂停下载!");
}; DownloadingState.prototype.fail = function () { this.oDownload.setState(this.oDownload.getDownloadedFailedState());
console.log("下载失败!");
}; DownloadingState.prototype.finish = function () {
this.oDownload.setState(this.oDownload.getDownloadedState());
console.log("下载完毕!");
};
(3)
var DownloadPausedState = function (oDownload) {
State.apply(this);
this.oDownload = oDownload;
}; DownloadPausedState.prototype = new State(); DownloadPausedState.prototype.download = function () {
this.oDownload.setState(this.oDownload.getDownloadingState());
console.log("继续下载!");
}; DownloadPausedState.prototype.pause = function () {
throw new Error("已经暂停了,咋还要暂停呢!");
}; DownloadPausedState.prototype.fail = function () { this.oDownload.setState(this.oDownload.getDownloadedFailedState());
console.log("下载失败!");
}; DownloadPausedState.prototype.finish = function () {
this.oDownload.setState(this.oDownload.getDownloadedState());
console.log("下载完毕!");
};
(4)
var DownloadedState = function (oDownload) {
State.apply(this);
this.oDownload = oDownload;
}; DownloadedState.prototype = new State(); DownloadedState.prototype.download = function () {
this.oDownload.setState(this.oDownload.getDownloadingState());
console.log("重新下载!");
}; DownloadedState.prototype.pause = function () {
throw new Error("对下载完了,还暂停啥?");
}; DownloadedState.prototype.fail = function () {
throw new Error("都下载成功了,咋会失败呢?");
}; DownloadedState.prototype.finish = function () {
throw new Error("下载成功了,不能再为成功了吧!");
};
(5)
var DownloadFailedState = function (oDownload) {
State.apply(this);
this.oDownload = oDownload;
}; DownloadFailedState.prototype = new State(); DownloadFailedState.prototype.download = function () {
this.oDownload.setState(this.oDownload.getDownloadingState());
console.log("尝试重新下载!");
}; DownloadFailedState.prototype.pause = function () {
throw new Error("失败的下载,也不能暂停!");
}; DownloadFailedState.prototype.fail = function () {
throw new Error("都失败了,咋还失败呢!");
}; DownloadFailedState.prototype.finish = function () {
throw new Error("失败的下载,肯定也不会成功!");
};
4.首页:
<body>
<input type="button" value="开始下载" id="download_button" />
<input type="button" value="暂停" id="pause_button" />
<input type="button" value="重新下载" id="resume_button" />
<script> var oDownload = new Download();
$("#download_button").click(function () {
oDownload.download();
}); $("#pause_button").click(function () {
oDownload.pause();
}); $("#resume_button").click(function () {
oDownload.download();
});
</script>
</body>
JavaScript设计模式——状态模式的更多相关文章
- JavaScript设计模式 - 状态模式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- javascript设计模式--状态模式(State)
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 【设计模式】Javascript设计模式——状态模式(行为型)
注:这个模式是非常聪明的,很有点数学中组合的意思,现在,来看下这个模式是怎么个思想. 问题提出:假如某个操作有三种可能,分别为1,2,3,还可能是组合,比如先执行1,再执行2或者先执行2再执行3或者1 ...
- 14. 星际争霸之php设计模式--状态模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- JavaScript设计模式 - 代理模式
代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问 代理模式的用处(个人理解):为了保障当前对象的单一职责(相对独立性),而需要创建另一个对象来处理调用当前对象之前的一些逻辑以提高代码的效 ...
- [Head First设计模式]生活中学设计模式——状态模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- javascript 设计模式-----策略模式
在<javascript设计模式>中,作者并没有向我们介绍策略模式,然而它却是一种在开发中十分常见的设计模式.最常见的就是当我们遇到一个复杂的表单验证的时候,常常需要编写一大段的if和el ...
- JAVA 设计模式 状态模式
用途 状态模式 (State) 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式是一种行为型模式. 结构
- 深入浅出设计模式——状态模式(State Pattern)
模式动机 在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的 (stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的.当一个这样的 ...
随机推荐
- python中的编码问题:以ascii和unicode为主线
1.unicode.gbk.gb2312.utf-8的关系 http://www.pythonclub.org/python-basic/encode-detail 这篇文章写的比较好,utf-8 ...
- ios tableview 适配横竖屏
tableview.autoresizingMask=UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
- [Android] 关于getinstalledpackages参数的分析
reference to : http://blog.csdn.net/luojiusan520/article/details/47696891 getinstalledpackages()的方法 ...
- php单双引号
1.定义字符串 定义字符串时,只有一种引号被视为定义符,即单引号或双引号.于是,如果一个字符串由双引号开始,那么只有双引号被分析器解析.这样,你就可以在双引号串中包含任何其他字符,甚至单引号.下面的引 ...
- CLR via C#(05)- 访问限定、数据成员
今天跟大家分享一下关于访问限定和数据成员的知识.主要包括以下两点: Abstract, sealed, virtual, new, override怎么用? Const 和 readonly好像都表示 ...
- Error parsing 'file:///media/RHEL_5.5\\ x86_64\\ DVD/Server'
Error parsing 'file:///media/RHEL_5.5\\ x86_64\\ DVD/Server' http://lindows.iteye.com/blog/456637 ht ...
- ExcelReport第一篇:使用ExcelReport导出Excel
导航 目 录:基于NPOI的报表引擎——ExcelReport 下一篇:ExcelReport源码解析 概述 本篇将通过导出学生成绩的示例演示“使用ExcelReport导出Excel”的步骤. ...
- [LeetCode] Isomorphic Strings
Isomorphic Strings Total Accepted: 30898 Total Submissions: 120944 Difficulty: Easy Given two string ...
- 缓慢变化维 (Slowly changing dimension)
维度建模的数据仓库中,有一个概念叫Slowly Changing Dimensions,中文一般翻译成"缓慢变化维",经常被简写为SCD.缓慢变化维的提出是因为在现实世 ...
- Codeforces Round #363 LRU(概率 状压DP)
状压DP: 先不考虑数量k, dp[i]表示状态为i的概率,状态转移方程为dp[i | (1 << j)] += dp[i],最后考虑k, 状态表示中1的数量为k的表示可行解. #incl ...