状态和行为:

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

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

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

环境和状态处理对象:

在状态模式中,环境(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. storyboard在ios模拟器无法显示的问题

    一.问题描述 1.在原有项目新建一个名称为test的storyboard类型的文件. 2.test.storyboard添加View Controller,并设置View Controller下Vie ...

  2. codeforces 556C. Case of Matryoshkas 解题报告

    题目链接:http://codeforces.com/contest/556/problem/C 题目意思:有 n 个数(1,2,...,n)组成 k 条链.第 i 条链由 mi 个数组成.每一秒只可 ...

  3. mybatis,批量新增、修改,删除

    转载自:http://blog.csdn.net/sanyuesan0000/article/details/19998727 最近需要用到Mybatis批量新增oracle数据库,刚开始在网上找到的 ...

  4. EF-实体更新

    1.数据库表增加字段,EF更新视图后,对应的实体对象没有新增的字段原因:edmx文件右键属性设置了 保存时转换相关的文本模板-false...正确的应该是rue 2. 更改视图后(或者更改字段类型?) ...

  5. AFNetworking request failed unacceptable content type text/html

    今天体验AFNetwork 3.1.0 进行数据解析,但是解析数据控制台一直都输出这样的 error 结果: 于是,照着以前AFN2.+版本的进行设置: 结果发现在新版本的 AFN 上不能设置了.既然 ...

  6. PCH文件配置路径

    "项目" >> Build  Settings >> Preflx Header >> $(SRCROOT)/项目名/XXX.pch

  7. arcgis

    投影的时候两个选择: projected:平面的,以米为单位 另一个:球迷的,以经纬度为单位

  8. Java网络连接之HttpURLConnection 与 HttpClient

    HttpClient使用详解:http://blog.csdn.net/wangpeng047/article/details/19624529   注:HttpURLConnection输出流用ou ...

  9. MyString(重写String)

    http://wenku.baidu.com/view/d7ac113243323968011c925b.html 已知类String的原型为: class String  { public:     ...

  10. core

    http://blog.csdn.net/xiaoxiaoniaoer1/article/details/7740820 1.core文件的生成开关和大小限制--------------------- ...