2012-04-28 14 views
5

módulo que estaba leyendo este enlace http://addyosmani.com/largescalejavascript/#modpatternencapsulación en javascript patrón

Y vi el siguiente ejemplo.

var basketModule = (function() { 
var basket = []; //private 

return { //exposed to public 
     addItem: function(values) { 
      basket.push(values); 
     }, 
     getItemCount: function() { 
      return basket.length; 
     }, 
     getTotal: function(){ 
      var q = this.getItemCount(),p=0; 
      while(q--){ 
       p+= basket[q].price; 
      } 
     return p; 
     } 
     } 
}()); 

basketModule.addItem({item:'bread',price:0.5}); 
basketModule.addItem({item:'butter',price:0.3}); 

console.log(basketModule.getItemCount()); 
console.log(basketModule.getTotal()); 

Se stats que "El patrón módulo es un diseño popular que el patrón que encapsula 'privacidad', el estado y la organización mediante cierres" ¿Cómo es esto diferente a escribir como si fuera el siguiente? ¿No se puede hacer cumplir la privacidad simplemente con el alcance de la función?

var basketModule = function() { 
var basket = []; //private 
     this.addItem = function(values) { 
      basket.push(values); 
     } 
     this.getItemCount = function() { 
      return basket.length; 
     } 
     this.getTotal = function(){ 
      var q = this.getItemCount(),p=0; 
      while(q--){ 
       p+= basket[q].price; 
      } 
     return p; 
     } 

} 

var basket = new basketModule(); 

basket.addItem({item:'bread',price:0.5}); 
basket.addItem({item:'butter',price:0.3}); 

Respuesta

3

En la primera variante crea un objeto sin la posibilidad de crear nuevas instancias del mismo (se trata de una función inmediatamente instanciada). El segundo ejemplo es una función contructor completa, que permite varias instancias. La encapsulación es la misma en ambos ejemplos, la matriz basket es 'privada' en ambos.

Sólo por diversión: lo mejor de ambos mundos podrían ser:

var basketModule = (function() { 
    function Basket(){ 
     var basket = []; //private 
     this.addItem = function(values) { 
      basket.push(values); 
     } 
     this.getItemCount = function() { 
      return basket.length; 
     } 
     this.getTotal = function(){ 
      var q = this.getItemCount(),p=0; 
      while(q--){ 
       p+= basket[q].price; 
      } 
     return p; 
     } 
    } 
    return { 
    basket: function(){return new Basket;} 
    } 
}()); 
//usage 
var basket1 = basketModule.basket(), 
    basket2 = basketModule.basket(), 
+0

Creo que mi pregunta es ahora es el primer patrón más "módulo" que el segundo. El enlace usa la primera variante como un ejemplo explícito del patrón del módulo. – eirikrl

+0

Diría que la primera variante refleja el patrón del módulo (entregando el 'basketModule'), el segundo ofrece una manera de crear instancias' basket' ​​*. Por cierto, todo se trata de etiquetar, podría nombrar la primera variante también como 'patrón de singleton'. – KooiInc

+0

Desde el punto de vista de que un módulo es un paquete aislado de funcionalidad en lugar de un conjunto de clases instanciables, entonces sí. Sin embargo, la diferencia entre los dos no es tanto diseño, es sintaxis. No hay nada que te impida tener un singleton de la segunda manera al tener 'var basketModule = new function() {...};'. La idea de utilizar un objeto de retorno es que puede condensar la interfaz en unas pocas líneas de código, si lo prefiere, para que pueda verlo de un vistazo. Pero no usaría grandes funciones anónimas para esto, simplemente haría 'return {publicFunc: privateFunc};'. –