Peter Seibel, autor de Practical Common Lisp, una vez dijo que si necesita un patrón, algo debe estar mal. El problema que mencionó se refiere a la necesidad de buscar y resumir una solución general debido a los defectos inherentes del lenguaje.
Ya sea un tipo débil o fuerte, un lenguaje estático o dinámico, un lenguaje imperativo o descriptivo, cada idioma tiene sus propias ventajas y desventajas. Un atleta jamaicano tiene algunas ventajas en sprints e incluso boxeo, pero carece de algunos en la práctica de yoga.
Los brujos y los sacerdotes de la sombra pueden ser fácilmente un excelente auxiliar, mientras que una magia enemiga que vuela con Macon en la espalda sería un poco incómoda. Para cambiar al programa, puede tomar mucho esfuerzo implementar el decorador en el lenguaje estático. Debido a que JS puede arrojar métodos a los objetos en cualquier momento, el patrón del decorador se vuelve inútil en JS.
Hay bastantes libros sobre los patrones de diseño de JavaScript. "Pro JavaScript Patterns de diseño" es un libro clásico, pero los ejemplos en él son bastante detallados, por lo que, según el código que escribí en el trabajo, resumiré mi comprensión. Si mi comprensión es sesgado, asegúrese de corregirlo.
1. Modo singleton
La definición de un patrón singleton es producir una instancia única de una clase, pero JS en sí es un lenguaje "sin clase". Muchos artículos que hablan sobre el patrón de diseño JS usan {} como un singleton y tienen sentido. Debido a que hay muchas formas de generar objetos de JS, echemos un vistazo a otro singleton más significativo.
Existe un requisito común de que al hacer clic en un botón, una capa de máscara debe aparecer en la página. Por ejemplo, cuando hace clic en Web.qq.com para iniciar sesión.
Este código que genera una capa de máscara de fondo gris es fácil de escribir.
La copia del código es la siguiente:
var createMask = function () {
Documento de retorno, Body.AppendChild (document.createElement (div));
}
$ ('botón') .Click (function () {
Var máscara = createMask ();
Mask.show ();
})
El problema es que esta capa de máscara es globalmente única, por lo que cada vez que llame a CreateMask, se creará un nuevo DIV, aunque se puede eliminar mientras oculta la capa de máscara. Sin embargo, obviamente no es razonable hacer esto.
Veamos la segunda solución, cree este DIV al comienzo de la página. Luego consulte a él con una variable.
La copia del código es la siguiente:
var máscara = document.body.appendChild (document.createElement ("div '));
$ ("Button ') .Click (function () {
Mask.show ();
})
Esto no significa que solo se creará una capa de máscara Div en la página, pero seguirá otro problema. Tal vez nunca necesitaremos esta capa de máscara, que desperdiciará un DIV y debería ser muy tacaño sobre cualquier operación del nodo DOM.
Si puede usar una variable, ¿determinar si se ha creado un DIV?
La copia del código es la siguiente:
máscara var;
var createMask = function () {
if (máscara) Máscara de retorno;
demás{
máscara = documento, body.appendChild (document.createElement (div));
Máscara de regreso;
}
}
Se ve bien, pero aquí completé una función que genera un objeto de columna única. Echemos un vistazo más de cerca a lo que está mal con este código.
En primer lugar, esta función tiene ciertos efectos secundarios. La función cambia la referencia a la máscara de variable externa en el cuerpo de la función. En un proyecto de colaboración en varias personas, CreateMask es una función insegura. Por otro lado, la máscara de variable global no es necesaria. Vamos a mejorarlo.
La copia del código es la siguiente:
var createMask = function () {
máscara var;
Función de retorno () {
Máscara de retorno || (máscara = document.body.appendChild (document.createElement ('div')))
}
} ()
Se utiliza un cierre simple para envolver la máscara variable, al menos para la función CreateMask, está cerrada.
Tal vez cuando veo esto, creo que el patrón singleton es demasiado simple. De hecho, algunos patrones de diseño son muy simples. Incluso si nunca he prestado atención al concepto de patrones de diseño, he utilizado algunos patrones de diseño en mi código diario sin saberlo. Al igual que cuando entendí lo que es el carrito de un anciano, lo pensé hace muchos años, resultó que este es el carrito de un anciano.
Los 23 patrones de diseño en GOF también son patrones que han existido y usado repetidamente en el desarrollo de software. Si el programador no se da cuenta claramente de que ha usado ciertos patrones, entonces puede perder un diseño más adecuado la próxima vez (este pasaje proviene de "el mundo de la programación en Matsumoto".
Volvamos al tema, el Singleton anterior todavía tiene sus desventajas. Solo se puede usar para crear capas de máscara. ¿Qué pasa si necesito escribir una función para crear un objeto XHR único? ¿Puedo encontrar un envoltorio general singleton?
Las funciones en JS son el primer tipo, lo que significa que las funciones también se pueden aprobar como parámetros. Echemos un vistazo al código final.
La copia del código es la siguiente:
var singleton = function (fn) {
resultado var;
Función de retorno () {
Resultado de retorno || (resultado = fn .apply (this, argumentos));
}
}
var createMask = Singleton (function () {
return document.body.appendChild (document.createElement ('div'));
})
Use una variable para guardar el primer valor de retorno. Si se ha asignado, la variable se devolverá primero en llamadas posteriores. El código que realmente crea la capa de máscara se pasa al envoltorio singleton a través de la función de devolución de llamada. Este método en realidad se llama modo puente. Con respecto al modo puente, se coloca un poco más tarde.
Sin embargo, la función singleton no es perfecta, siempre requiere un resultado variable para registrar la referencia al DIV. Desafortunadamente, las características funcionales de JS no son suficientes para eliminar completamente las declaraciones y declaraciones.