状态和行为:
所谓对象的状态,通常指的就是对象实例的属性的值;而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上。
状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的不同功能。也就是说,状态和行为是相关联的,它们的关系可以描述为:状态决定行为。
由于状态是在运行期被改变的,因此行为也会在运行期根据状态的改变而改变。
环境和状态处理对象:
在状态模式中,环境(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>
原文:http://www.cnblogs.com/xinxingyu/p/4853744.html