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>

  

  

  

原文地址:https://www.cnblogs.com/xinxingyu/p/4853744.html