2012-05-16 14 views
7

He estado investigando para crear un estilo de codificación JavaScript estandarizado para mi equipo. La mayoría de los recursos ahora recomiendan el patrón "módulo" que implica el cierre, como esto:¿Cuál es el beneficio del Patrón de Módulos Javascript?

var Module = function() { 

    someMethod = function() { /* ... */ }; 

    return { 
     someMethod: someMethod 
    }; 

}(); 

y la invocan como Module.someMethod();. Este enfoque parece funcionar únicamente con métodos que serían estáticos en un contexto de OOP tradicional, por ejemplo, clases de repositorio para buscar/guardar datos, capas de servicio para realizar solicitudes externas y similares. A menos que me haya olvidado de algo, el patrón del módulo no está destinado a ser utilizado con clases de datos (piense DTO) que típicamente necesitarían pasar a/desde los métodos de servicio al código de pegamento de UI.

Un beneficio común que veo citado es que se puede tener verdaderos métodos privados y campos en Javascript con el patrón de módulo, pero esto también puede lograrse junto con poder tener o métodos de instancia estáticas con el " "estilo Javascript clásico similar a esto:

myClass = function(param) { 
    // this is completely public 
    this.publicProperty = 'Foo'; 

    // this is completely private 
    var privateProp = param; 

    // this function can access the private fields 
    // AND can be called publicly; best of both? 
    this.someMethod = function() { 
     return privateProp; 
    }; 

    // this function is private. FOR INTERNAL USE ONLY 
    function privateMethod() { 
     /* ... */ 
    }; 
} 

// this method is static and doesn't require an instance 
myClass.staticMethod = function() { /* ... */ }; 

// this method requires an instance and is the "public API" 
myClass.prototype.instanceMethod = function() { /* ... */ }; 

Así que supongo que mi pregunta es ¿qué hace que el Patrón de Módulo sea mejor que el estilo tradicional? Es un poco más limpio, pero ese parece ser el único beneficio que es inmediatamente aparente; de hecho, el estilo tradicional parece ofrecer la capacidad de proporcionar una encapsulación real (similar a los verdaderos lenguajes OOP como Java o C#) en lugar de simplemente devolver una colección de métodos solo estáticos.

¿Hay algo que me falta?

+0

El patrón de módulo se puede utilizar para crear prototipos, así como ver: 'var Module = function() { function Module() {}; Module.prototype.whatever = function() {}; return Module }(); ' –

+1

Si está definiendo un singleton, no debería importar si usa métodos estáticos o de instancia. De hecho, preferiría la versión estática, ya que entonces no tengo que preocuparme por estropear el "esto" al usar ons de las funciones en una devolución de llamada. – hugomg

Respuesta

1

Otro beneficio que olvidó mencionar en el patrón del módulo es que promueve menos desorden en el espacio de nombre global, es decir, a qué se refieren las personas cuando dicen "no contaminan el espacio de nombres global". Claro que puedes hacer eso en tu enfoque clásico, pero parece que crear objetos fuera de las funciones anónimas sería más fácil para crear esos objetos en el espacio de nombres global.

En otras palabras, el patrón del módulo promueve el código autónomo. Un módulo típicamente empujará un objeto en el espacio de nombre global, y toda la interacción con el módulo pasará por este objeto. Es como un método "principal".

Menos desorden en el espacio de nombres global es bueno, ya que reduce las posibilidades de colisiones con otros marcos y código de JavaScript.

1

Patrón módulo se puede utilizar para crear prototipos así ver:

var Module = function() { 
    function Module() {}; 
    Module.prototype.whatever = function() {}; 
    return Module 
}(); 
var m = new Module(); 
m.whatever(); 

Como el otro cartel dijo que el espacio de nombres global limpia es la razón para ello. Sin embargo, otra forma de lograr esto es utilizar el patrón AMD, que también resuelve otros problemas, como la administración de dependencias. También envuelve todo en un tipo de cierre. Aquí hay un gran Introduction to AMD que significa definición de módulo asíncrono.

También recomiendo leer JavaScript Patterns ya que cubre completamente las razones de varios patrones de módulos.

2

El patrón del módulo anterior no tiene sentido. Todo lo que está haciendo es usar un cierre para devolver un constructor con prototipo. Que podría haber logrado lo mismo con:

function Module() {}; 
Module.prototype.whatever = function() {}; 

var m = new Module(); 
m.whatever(); 

De hecho se habría ahorrado un objeto (el cierre) que se creen, con la misma salida.

Mi otra carne de res con el patrón del módulo es que si lo está usando para encapsulación privada, solo puede usarlo fácilmente con clases simples y no concretas. Para crear clases concretas con datos privados, terminas envolviendo a dos cerradores, lo que se pone feo. También estoy de acuerdo en que poder depurar las propiedades pseudo privadas de subrayado es mucho más fácil cuando son visibles. Toda la noción de "qué pasa si alguien usa tu clase de forma incorrecta" nunca se justifica. Haga una API pública limpia, documente, y si las personas no la siguen correctamente, entonces tiene un programador deficiente en su equipo. La cantidad de esfuerzo requerida en JavaScript para ocultar variables (que se puede descubrir con eval en Firefox) no vale la pena el uso típico de JS, incluso para proyectos medianos a grandes. La gente no husmea en tus objetos para aprenderlos, leen tus documentos. Si sus documentos son buenos (por ejemplo, usando JSDoc), se mantendrán, al igual que usamos todas las bibliotecas de terceros que necesitamos. No manipulamos jQuery o YUI, solo confiamos y usamos la API pública sin preocuparnos demasiado por cómo o qué usa debajo.

Cuestiones relacionadas