introducir
El modo de estado permite que un objeto cambie su comportamiento cuando cambia su estado interno, y el objeto parece modificar su clase.
texto
Por ejemplo, cuando descargamos las cosas, generalmente tenemos varios estados, como ReadyState, Descargar State, PausedState, DescargedState, DownloadedState y FallingState. Es decir, en cada estado, solo puede hacer lo que el estado actual puede hacer, pero no lo que otros estados pueden hacer.
Porque el patrón de estado describe cómo las descargas (descargar) se comportan de manera diferente en cada estado. La idea clave de este patrón es introducir una clase abstracta llamada estado (o una función en JS) para representar el estado de descarga. La función de estado (como prototipo) declara algunas interfaces comunes para las subclases (funciones de herencia) de cada estado. Cada función de herencia implementa comportamientos relacionados con un estado específico, como la descarga de estate y descarga, implementa respectivamente los comportamientos que se descargan y descargan. Estos comportamientos se pueden mantener a través de la descarga.
Implementemos un juego, primero definir la función de estado como un prototipo de otras funciones básicas:
La copia del código es la siguiente:
var state = function () {
};
State.prototype.download = function () {
arrojar un nuevo error ("Este método debe estar sobrecargado!");
};
State.prototype.pause = function () {
arrojar un nuevo error ("Este método debe estar sobrecargado!");
};
State.prototype.fail = function () {
arrojar un nuevo error ("Este método debe estar sobrecargado!");
};
State.prototype.finish = function () {
arrojar un nuevo error ("Este método debe estar sobrecargado!");
};
Definimos 4 interfaces de métodos para el prototipo de estado, que corresponde a descargar (descargar), pausa, falla y fin para que la subfunción pueda reescribirse.
Antes de escribir una subfunción, primero escribimos una función ReadyState para que el estado pueda pasar al primer estado de descarga:
La copia del código es la siguiente:
var latelystate = function (Odownload) {
State.apply (esto);
this.odownload = Odownload;
};
ReadyState.prototype = new State ();
ReadyState.Prototype.download = function () {
this.odownload.setState (this.odownload.getDownloadingState ());
// Después de listo, puede comenzar a descargar, por lo que establece el método de adquisición de estado en la función de descarga
console.log ("¡Comienza la descarga!");
};
ReadyState.Prototype.Pause = function () {
arrojar un nuevo error ("La descarga aún no ha comenzado, ¡no se puede hacer una pausa!");
};
ReadyState.prototype.fail = function () {
Agregue un nuevo error ("El archivo aún no ha comenzado a descargar, ¿cómo se puede decir que ha fallado!");
};
ReadyState.prototype.finish = function () {
arrojar un nuevo error ("El archivo no ha comenzado a descargar, por supuesto que no se puede terminar!");
};
Esta función toma una instancia de la función de mantenimiento de descarga como un parámetro. La función de descarga se utiliza para controlar los cambios y adquisiciones de estado (similar al controlador central, permitiendo llamadas externas). ReadyState reescribe el método de descarga prototipo para comenzar a descargar. Sigamos observando las funciones principales de la función de descarga:
La copia del código es la siguiente:
var descargar = function () {
this.ostate = new ReadyState (this);
};
Descargar.prototype.setstate = function (ostate) {
this.ostate = ostate;
};
// cuatro métodos públicos expuestos al exterior para llamadas externas
Descargar.prototype.download = function () {
this.ostate.download ();
};
Descargar.prototype.pause = function () {
this.ostate.Pause ();
};
Descargar.prototype.fail = function () {
this.ostate.fail ();
};
Descargar.prototype.finish = function () {
this.ostate.finish ();
};
// Obtener varios estados y pasar en la actual este objeto
Descargar.prototype.getreadystate = function () {
devolver nuevo ReadyState (esto);
};
Descargar.prototype.getDownloadingState = function () {
devolver nuevo Descargar State (esto);
};
Descargar.prototype.getDownloadPausedState = function () {
devolver nuevo DownloadPausedState (esto);
};
Download.prototype.getDownloadedState = function () {
devolver nuevo DownloadedState (esto);
};
Download.prototype.getDownloadedFailedState = function () {
devolver nuevo DownloadFailedState (esto);
};
El prototipo de la función de descarga proporciona 8 métodos, 4 son comportamientos operativos para la descarga de los estados, y los otros 4 se utilizan para obtener los cuatro estados actuales diferentes. Todos estos 4 métodos reciben esto como un parámetro, es decir, pasar la instancia de descarga en sí como un parámetro al objeto de estado (ReadyState y la función de herencia que se implementará más adelante), lo que hace que el objeto de estado sea accesible para Odownlaod que si sea necesario.
A continuación, continúe definiendo 4 funciones estatales relacionadas:
La copia del código es la siguiente:
var downloadingState = function (Odownload) {
State.apply (esto);
this.odownload = Odownload;
};
Descargarstate.prototype = new State ();
Descargarstate.prototype.download = function () {
arrojar un nuevo error ("¡El archivo ya se está descargando!");
};
Descargarstate.prototype.pause = function () {this.odownload.setState (this.odownload.getDownloadPausedState ());
console.log ("¡Descarga de pausa!");
};
Descargarstate.prototype.fail = function () {this.odownload.setState (this.odownload.getDownloadedFailedState ());
console.log ("¡Descargar fallido!");
};
Descargarstate.prototype.finish = function () {
this.odownload.setState (this.odownload.getDownloadedState ());
console.log ("¡Descargado!");
};
Lo principal a tener en cuenta sobre la descarga de State es que el archivo que ya está descargando no se puede descargar nuevamente, y otros estados se pueden realizar continuamente.
La copia del código es la siguiente:
var downloadPausedState = function (Odownload) {
State.apply (esto);
this.odownload = Odownload;
};
DownloadPausedState.prototype = new State ();
DownloadPausedState.prototype.download = function () {
this.odownload.setState (this.odownload.getDownloadingState ());
console.log ("¡Continuar descargando!");
};
DownloadPausedState.prototype.Pause = function () {
arrojar un nuevo error ("Se ha detenido, ¿por qué aún tienes que hacer una pausa!");
};
DownloadPausedState.prototype.fail = function () {this.odownload.setState (this.odownlownload.getDownloadedFailedState ());
console.log ("¡Descargar fallido!");
};
DownloadPausedState.prototype.finish = function () {
this.odownload.setState (this.odownload.getDownloadedState ());
console.log ("¡Descargado!");
};
Cabe señalar en la función DownloadPausedState que las descargas que se han detenido no se pueden pausar nuevamente.
La copia del código es la siguiente:
var descargaedState = function (Odownload) {
State.apply (esto);
this.odownload = Odownload;
};
DescargedState.prototype = new State ();
DescargarseState.prototype.download = function () {
this.odownload.setState (this.odownload.getDownloadingState ());
console.log ("Re-descendente!");
};
DescargarseState.prototype.Pause = function () {
arrojar un nuevo error ("¿Qué más pausará después de descargar?");
};
DescargedState.prototype.fail = function () {
arrojar un nuevo error ("La descarga ha sido exitosa, ¿por qué fallará?");
};
DescargarseState.prototype.finish = function () {
Tire un nuevo error ("La descarga es exitosa, ¡ya no puedes hacerlo!");
};
DownloadedState Function, de manera similar, después de una descarga exitosa, ya no puede establecer Finalización, solo puede establecer el estado de re-descarga.
La copia del código es la siguiente:
var descargarfailedstate = function (Odownload) {
State.apply (esto);
this.odownload = Odownload;
};
Descargarfailedstate.prototype = new State ();
Descargarfailedstate.prototype.download = function () {
this.odownload.setState (this.odownload.getDownloadingState ());
console.log ("¡Intenta volver a descargar!");
};
Descargarfailedstate.prototype.pause = function () {
arrojar un nuevo error ("La descarga fallida no se puede pausar!");
};
Descargarfailedstate.prototype.fail = function () {
arrojar un nuevo error ("Todo falló, ¿por qué todavía falló!");
};
Descargarfailedstate.prototype.finish = function () {
arrojar un nuevo error ("La descarga fallida definitivamente no tendrá éxito!");
};
Del mismo modo, el estado de falla de la función DownloadFailedState no puede fallar nuevamente, pero puede intentar descargarlo nuevamente después de terminar.
Llamar al código de prueba es muy simple. Demostrarlo en HTML. Primero, necesita jQuery, y luego hay 3 botones que representan: comenzar descarga, pausa y vuelva a descargar. (Tenga en cuenta que usa Firebug para ver los resultados en Firefox, porque se utiliza el método console.log).
La copia del código es la siguiente:
<html>
<Evista>
<Link type = "text/css" rel = "stylesheet" href = "http://www.cnblogs.com/css/style.css"/>
<title> State Pattern </title>
<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 = "estados/descargarfailedstate.js"> </script>
<script type = "text/javaScript" src = "estados/downloadPausedState.js"> </script>
<script type = "text/javaScript" src = "estados/descargedstate.js"> </script>
<script type = "text/javaScript" src = "estados/descargingstate.js"> </script>
<script type = "text/javaScript" src = "states/latekstate.js"> </script>
</ablo>
<Body>
<input type = "Button" Value = "Start download" id = "download_button" />
<input type = "button" value = "pause" id = "pause_button" />
<input type = "button" value = "re-download" id = "resume_button" />
<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>
</body>
</html>
Resumir
Los escenarios de uso del modo de estado también son particularmente claros, con los siguientes dos puntos:
1. El comportamiento de un objeto depende de su estado, y debe cambiar su comportamiento de acuerdo con su estado en el tiempo de ejecución.
2. Una operación contiene una gran cantidad de declaraciones de rama, y estas declaraciones de rama dependen del estado del objeto. El estado suele ser una representación de una o más constantes de enumeración.