JavaScript: Design Pattern-state pattern

Source: Internet
Author: User

JavaScript: Design Pattern-state pattern
Introduction

The State mode allows an object to change its behavior when its internal State changes. The object seems to have modified its class.

Body

For example, we usually download objects in several states, such as ReadyState, DownloadingState, and DownloadPausedState) downloadedState and DownloadFailedState. That is to say, in each state, you can only do what is in the current state, but not what can be done in other States.

Because the State mode describes how Download shows different behaviors in each State. The key idea of this mode is to introduce an abstract class called State (or a function in JS) to indicate the download State. The State function (as a prototype) declare some public interfaces for subclasses (inherited functions) of each State. Each of its inherited functions implements behaviors related to specific States. For example, DownloadingState and DownloadedState implement the behaviors of downloadinging and DownloadedState respectively. These actions can be maintained through Download.

Let's implement one. First, define the State function as the prototype of other basic functions:

Var State = function () {}; State. prototype. download = function () {throw new Error (this method must be overloaded !);}; State. prototype. pause = function () {throw new Error (this method must be overloaded !);}; State. prototype. fail = function () {throw new Error (this method must be overloaded !);}; State. prototype. finish = function () {throw new Error (this method must be overloaded !);};

We have defined four method interfaces for the prototype of State, which correspond to download, pause, fail, and finish so that subfunctions can be rewritten.

Before writing a subfunction, write a ReadyState function to pass the state to the first download state:

Var ReadyState = function (oDownload) {State. apply (this); this. oDownload = oDownload;}; ReadyState. prototype = new State (); ReadyState. prototype. download = function () {this. oDownload. setState (this. oDownload. getDownloadingState (); // After Ready, you can start downloading. Therefore, you have set the console for obtaining the status in the Download function. log (Start Download !);}; ReadyState. prototype. pause = function () {throw new Error (download not started yet, cannot be paused !);}; ReadyState. prototype. fail = function () {throw new Error (File Download has not started yet. How can this problem be solved !);}; ReadyState. prototype. finish = function () {throw new Error (the file has not started to be downloaded, and of course it cannot be ended !);};

This function receives an instance of the Download maintenance function as a parameter. The Download function is used to control the change and acquisition of the State (similar to the central controller for external calls). ReadyState overrides the download method of the prototype, to start the download. Let's continue to look at the main functions of the Download function:

Var Download = function () {this. oState = new ReadyState (this) ;}; Download. prototype. setState = function (oState) {this. oState = oState ;}; // four public methods exposed to the outside, so that the external call 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 () ;}; // obtain various statuses and pass in the current this object Download. prototype. getReadyState = function () {return new ReadyState (this) ;}; Download. prototype. getDownloadingState = function () {return new DownloadingState (this) ;}; Download. prototype. getDownloadPausedState = function () {return new DownloadPausedState (this) ;}; Download. prototype. getDownloadedState = function () {return new DownloadedState (this) ;}; Download. prototype. getDownloadedFailedState = function () {return new DownloadFailedState (this );};

The Download function prototype provides eight methods, four of which are used to perform operations on the Download status, and the other four are used to obtain the current four different states, all the four methods receive this as a parameter, that is, passing the Download instance itself as a parameter to the status object that processes the request (ReadyState and the inherited function to be implemented later ), this allows the State object to access oDownlaod when necessary.

Next, we will continue to define four functions related to the status:

Var DownloadingState = function (oDownload) {State. apply (this); this. oDownload = oDownload;}; DownloadingState. prototype = new State (); DownloadingState. prototype. download = function () {throw new Error (the file is already being downloaded !);}; DownloadingState. prototype. pause = function () {this. oDownload. setState (this. oDownload. getDownloadPausedState (); console. log (pause download !);}; DownloadingState. prototype. fail = function () {this. oDownload. setState (this. oDownload. getDownloadedFailedState (); console. log (download failed !);}; DownloadingState. prototype. finish = function () {this. oDownload. setState (this. oDownload. getDownloadedState (); console. log (download completed !);};

The main note of DownloadingState is the file that is already being downloaded. You cannot start DownloadingState again. other statuses can be continuously performed.

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 (continue to download !);}; DownloadPausedState. prototype. pause = function () {throw new Error (paused. Why do you need to pause it !);}; DownloadPausedState. prototype. fail = function () {this. oDownload. setState (this. oDownload. getDownloadedFailedState (); console. log (download failed !);}; DownloadPausedState. prototype. finish = function () {this. oDownload. setState (this. oDownload. getDownloadedState (); console. log (download completed !);};

In the DownloadPausedState function, you must note that the download that has been paused cannot be paused again.

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 (download again !);}; DownloadedState. prototype. pause = function () {throw new Error (after the download is complete, what is the pause ?);}; DownloadedState. prototype. fail = function () {throw new Error (all download succeeded. Why ?);}; DownloadedState. prototype. finish = function () {throw new Error (the download is successful, so you can no longer succeed !);};

The DownloadedState function. After successful download, you can only set the download status again.

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 (try to download again !);}; DownloadFailedState. prototype. pause = function () {throw new Error (failed download, cannot be paused !);}; DownloadFailedState. prototype. fail = function () {throw new Error (all failed. Why? Still failed !);}; DownloadFailedState. prototype. finish = function () {throw new Error (failed download will certainly not succeed !);}; Similarly, the DownloadFailedState function cannot fail again, but it can be re-downloaded again after finished.

It's very easy to call the test code. Let's demonstrate it in HTML. First, we need jquery, and there are three buttons for them: Start download, pause, and re-download. (Check the result with firebug in Firefox because the console. log method is used ).

  <Script type = text/javascript src =/jquery. js> </script> <script type = text/javascript src = Download. js> </script> <script type = text/javascript src = states/State. js> </script> <script type = text/javascript src = states/DownloadFailedState. js> </script> <script type = text/javascript src = states/DownloadPausedState. js> </script> <script type = text/javascript src = states/DownloadedState. js> </script> <script type = text/javascript src = states/DownloadingState. js> </script> <script type = text/javascript src = states/ReadyState. js> </script>   <Script type = text/javascript> var oDownload = new Download (); $ (# download_button ). click (function () {oDownload. download () ;}); $ (# pause_button ). click (function () {oDownload. pause () ;}); $ (# resume_button ). click (function () {oDownload. download () ;}); </script> conclusion 

The usage scenarios of the Status mode are also specific, including the following:

  1. The behavior of an object depends on its state, and it must change its behavior according to its state at runtime.
  2. An operation contains a large number of branch statements, and these branch statements depend on the state of the object. The status is usually expressed by one or more enumerated constants.

     

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.