Design Patterns no JavaScript – Singleton
Leia em 1 minuto
No artigo anterior vimos como funciona o Module Pattern. Agora chegou a hora de vermos um pouco sobre o Singleton Pattern.
O Singleton Pattern diz que você pode ter apenas uma única instância de uma classe (ou, no caso do JavaScript, função construtora). Isso significa que uma vez que a classe for instanciada, você deve sempre retornar esta mesma instância em chamadas subsequentes.
Um exemplo clássico deste pattern é usar um único objeto como namespace de sua aplicação.
var HOWTO = {};
Pelo fato de termos definido a variável como um objeto, não podemos instanciar novos objetos à partir dele (embora possamos criar novos objetos usando este como base com a função Object.create
, por exemplo).
Esse pattern também pode ser aplicado às funções construtoras. A maneira mais simples é utilizar Singleton com Immediately-Invoked Function Expression (IIFE) ou, como dizemos mais comumente, funções auto-executáveis.
function MyApp() {
if (!MyApp.instance) {
MyApp.instance = this;
}
return MyApp.instance;
}
Essa função construtora irá garantir que você sempre receba a mesma instância como resultado. Isso só é possível porque funções construtoras utilizam o retorno como resultado da instanciação. Na prática, você poderia retornar qualquer tipo de objeto, como arrays ou strings.
var instance = new MyApp();
console.log(instance === new MyApp());
//=> true
Você pode perceber que o resultado é sempre o mesmo, independente de quantas vezes instanciarmos a função MyApp
.
O grande problema dessa implementação é que alguém pode manipular a instância armazenada em MyApp.instance
, embora seja pouco provável. Uma alternativa seria utilizar o conceito de closure para simular a privacidade do atributo.
function MyApp() {
var instance;
// Override the original implementation.
MyApp = function() {
return instance;
};
// Set the instance.
instance = this;
}
Essa é uma implementação bastante curiosa. A função MyApp
possui uma implementação que redefine a própria função MyApp
para retornar apenas a instância.
Alternativamente você poderia utilizar o Module Pattern, mas acho que fica um pouco mais complexo que a implementação anterior.
var MyApp;
(function(){
var instance;
MyApp = function() {
if (instance) {
return instance;
}
instance = this;
};
})();
Finalizando
Sempre que quiser garantir a existência de apenas uma instância de uma função construtora, por exemplo, utilize o Singleton Pattern.
No próximo artigo iremos falar sobre o Factory Pattern.