状态和行为:

所谓对象的状态,通常指的就是对象实例的属性的值;而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上。

状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的不同功能。也就是说,状态和行为是相关联的,它们的关系可以描述为:状态决定行为。

由于状态是在运行期被改变的,因此行为也会在运行期根据状态的改变而改变。

环境和状态处理对象:

在状态模式中,环境(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设计模式——状态模式的更多相关文章

  1. JavaScript设计模式 - 状态模式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. javascript设计模式--状态模式(State)

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 【设计模式】Javascript设计模式——状态模式(行为型)

    注:这个模式是非常聪明的,很有点数学中组合的意思,现在,来看下这个模式是怎么个思想. 问题提出:假如某个操作有三种可能,分别为1,2,3,还可能是组合,比如先执行1,再执行2或者先执行2再执行3或者1 ...

  4. 14. 星际争霸之php设计模式--状态模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  5. JavaScript设计模式 - 代理模式

    代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问 代理模式的用处(个人理解):为了保障当前对象的单一职责(相对独立性),而需要创建另一个对象来处理调用当前对象之前的一些逻辑以提高代码的效 ...

  6. [Head First设计模式]生活中学设计模式——状态模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  7. javascript 设计模式-----策略模式

    在<javascript设计模式>中,作者并没有向我们介绍策略模式,然而它却是一种在开发中十分常见的设计模式.最常见的就是当我们遇到一个复杂的表单验证的时候,常常需要编写一大段的if和el ...

  8. JAVA 设计模式 状态模式

    用途 状态模式 (State) 当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式是一种行为型模式. 结构

  9. 深入浅出设计模式——状态模式(State Pattern)

    模式动机 在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的 (stateful)对象,这样的对象状态是从事先定义好的一系列值中取出的.当一个这样的 ...

随机推荐

  1. Linux(CentOS、Ububtu)一键安装Openstack及其它参考文档汇总

    原文链接  http://www.aboutyun.com/thread-10920-1-1.html openstack相关资料 CentOS下一键安装Openstack  http://blog. ...

  2. c/c++与Python的语法差异

    1.程序块语法方面: c/c++中用一对“{}”将多段语句括起来,表示一个程序块,并以右大括号表明程序块结束 ;i<n;i++) { cout<<a[i]; j+=; } Pytho ...

  3. Bootstrap弹窗插件(拟态框)关闭后回调函数

    $(function(){ $('#questionnaire').on('hidden.bs.modal',function(){ //清除缓存方法 }); }); 事件 Bootstrap 的模态 ...

  4. 【Excel 4.0 函数】REGISTER

    REGISTER.ID 返回指定的 DLL 或 代码资源注册过的函数 ID.如果 DLL 或 代码资源没有注册,这个函数将会注册它们,并返回 注册ID. REGISTER.ID 可以用于工作表(不同于 ...

  5. Struts2防止表单重复提交

    1.说明 系统拦截器的应用. 表单重复提交:当使用请求转化进行跳转的时候,存在着表单重复提交的问题. 2.在表单中加入s:token 如果页面加入了struts2的标签,页面的请求必须进入struts ...

  6. September 29th 2016 Week 40th Thursday

    Prosperity discovers vice, adversity virtue. 得意时露瑕疵,逆境中见品质. I wish I would have someone like you, fr ...

  7. Warp divergence

    Threads are executed in warps of 32, with all threads in the warp executing the same instruction at ...

  8. 月考(cogs 1176)

    [题目描述] 在上次的月考中Bugall同学违反了考场纪律还吃了处分,更可气的是在第二天的校会时 间学校就此事做了全校通报. 现已知在当天校会时间有总共N个同学听到了有关Bugall的处分决定.  B ...

  9. python基础——使用@property

    python基础——使用@property 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9 ...

  10. 有关Java的优秀博客集锦

    1. 在java编程中,多线程并发总有些疑惑:如为什么会产生并发?并发会有什么影响?java中提供了哪些处理并发的技术(机制) 关于并发产生的原因,我查了一些资料目前发现有两种原因:一,存在共享的资源 ...