javascript - nodejs - ES6 Singleton vs instanciar una clase una vez
singleton en node (4)
Veo patrones que hacen uso de un patrón de singleton utilizando clases ES6 y me pregunto por qué los usaría en lugar de simplemente crear una instancia de la clase en la parte inferior del archivo y exportar la instancia. ¿Hay algún tipo de inconveniente negativo para hacer esto? Por ejemplo:
Instancia exportadora de ES6:
import Constants from ''../constants'';
class _API {
constructor() {
this.url = Constants.API_URL;
}
getCities() {
return fetch(this.url, { method: ''get'' })
.then(response => response.json());
}
}
const API = new _API();
export default API;
Uso:
import API from ''./services/api-service''
¿Cuál es la diferencia de usar el siguiente patrón de Singleton? ¿Hay alguna razón para usar una de la otra? En realidad, tengo más curiosidad por saber si el primer ejemplo que di puede tener problemas que no conozco.
Patrón Singleton:
import Constants from ''../constants'';
let instance = null;
class API {
constructor() {
if(!instance){
instance = this;
}
this.url = Constants.API_URL;
return instance;
}
getCities() {
return fetch(this.url, { method: ''get'' })
.then(response => response.json());
}
}
export default API;
Uso:
import API from ''./services/api-service'';
let api = new API()
Ambos hacen lo mismo. El primero es 100% es6. El segundo es el antiguo camino reescrito en es6.
Me gustaría ir con el primero en cualquier momento, los nuevos desarrolladores no entenderán por qué tuvo que complicar las cosas, si es6 es con lo que comenzaron en primer lugar.
La diferencia es si quieres probar cosas.
Digamos que tienes el archivo de prueba api.spec.js
Y que tu cosa API tiene una dependencia, como esas Constantes.
Específicamente, el constructor en ambas versiones toma un parámetro, sus Constants
importan.
Entonces tu constructor se ve así:
class API {
constructor(constants) {
this.API_URL = constants.API_URL;
}
...
}
// single-instance method first
import API from ''./api'';
describe(''Single Instance'', () => {
it(''should take Constants as parameter'', () => {
const mockConstants = {
API_URL: "fake_url"
}
const api = new API(mockConstants); // all good, you provided mock here.
});
});
Ahora, con instancia exportadora, no hay burla.
import API from ''./api'';
describe(''Singleton'', () => {
it(''should let us mock the constants somehow'', () => {
const mockConstants = {
API_URL: "fake_url"
}
// erm... now what?
});
});
Con la exportación de objetos instanciados, no puede (fácil y sanamente) cambiar su comportamiento.
Otra razón para utilizar Singleton Pattern es que en algunos marcos (como Polymer 1.0
) no puede usar export
sintaxis de export
.
Es por eso que la segunda opción (patrón Singleton) es más útil, para mí.
Espero eso ayude.
Yo no recomendaría ninguno. Esto es totalmente complicado. Si solo necesita un objeto, ¡no use la sintaxis de class
! Solo ve por
import Constants from ''../constants'';
export default {
url: Constants.API_URL,
getCities() {
return fetch(this.url, { method: ''get'' }).then(response => response.json());
}
};
import API from ''./services/api-service''
o incluso más simple
import Constants from ''../constants'';
export const url = Constants.API_URL;
export function getCities() {
return fetch(url, { method: ''get'' }).then(response => response.json());
}
import * as API from ''./services/api-service''