zoukankan      html  css  js  c++  java
  • 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>
    

      

      

      

  • 相关阅读:
    Castle Windsor 学习-----Installer的几种安装方式
    asp.net mvc源码分析-Route的GetRouteData
    查看iis对应w3wp.exe显示的进程ID号(转载)
    jvisualvm安装Visual GC插件
    Modelsimse10.4如何编译altera库文件以支持IP仿真
    sublime text3 配置使用
    Modelsim调用用do脚本自动化仿真
    Quartus16.0如何使用TCL脚本
    Java中使用Timer和TimerTask实现多线程
    框架导论
  • 原文地址:https://www.cnblogs.com/xinxingyu/p/4853744.html
Copyright © 2011-2022 走看看