Qual é a melhor e mais conveniente maneira de implementar um padrão Singleton para uma classe no TypeScript? (Com e sem inicialização lenta).
singleton
typescript
maja
fonte
fonte
export default new Singleton()
?Desde o TS 2.0, temos a capacidade de definir modificadores de visibilidade em construtores ; portanto, agora podemos fazer singletons no TypeScript da mesma maneira que estamos acostumados em outras linguagens.
Exemplo dado:
Obrigado à @Drenai por salientar que, se você escrever código usando o javascript compilado bruto, não terá proteção contra várias instâncias, pois as restrições do TS desaparecem e o construtor não fica oculto.
fonte
A melhor maneira que eu encontrei é:
Aqui está como você o usa:
https://codebelt.github.io/blog/typescript/typescript-singleton-pattern/
fonte
A abordagem a seguir cria uma classe Singleton que pode ser usada exatamente como uma classe convencional:
Cada
new Singleton()
operação retornará a mesma instância. No entanto, isso pode ser inesperado pelo usuário.O exemplo a seguir é mais transparente para o usuário, mas requer um uso diferente:
Uso:
var obj = Singleton.getInstance();
fonte
new Class(...)
sintaxe.Estou surpreso por não ver o seguinte padrão aqui, que realmente parece muito simples.
Uso
fonte
Shout
classeVocê pode usar expressões de classe para isso (a partir da versão 1.6, acredito).
ou com o nome se sua turma precisar acessar seu tipo internamente
Outra opção é usar uma classe local dentro do seu singleton usando alguns membros estáticos
fonte
Adicione as 6 linhas a seguir a qualquer classe para torná-la "Singleton".
Exemplo de teste:
[Editar]: Use a resposta de Alex se você preferir obter a instância através de uma propriedade e não de um método.
fonte
new MySingleton()
digo, digamos 5 vezes? seu código reserva uma única instância?eu acho que talvez use genéricos seja massa
Como usar
passo 1
passo 2
fonte
Você também pode fazer uso da função Object.Freeze () . É simples e fácil:
fonte
if (!this.instance)
o construtor? Isso é apenas uma precaução extra caso você tenha criado várias instâncias antes da exportação?Eu encontrei uma nova versão disso com a qual o compilador Typescript está totalmente de acordo, e acho que é melhor porque não requer a chamada
getInstance()
constante de um método.Isso vem com uma desvantagem diferente. Se você
Singleton
tiver alguma propriedade, o compilador Typescript será um ajuste, a menos que você as inicialize com um valor. É por isso que incluí uma_express
propriedade na minha classe de exemplo, porque, a menos que você a inicialize com um valor, mesmo que você a atribua posteriormente no construtor, o Typescript pensará que ela não foi definida. Isso pode ser corrigido desativando o modo estrito, mas prefiro não, se possível. Há também outra desvantagem desse método que devo salientar, porque o construtor está realmente sendo chamado, cada vez que faz outra instância é tecnicamente criada, mas não acessível. Isso poderia, em teoria, causar vazamentos de memória.fonte
Este é provavelmente o processo mais longo para criar um singleton em texto datilografado, mas em aplicativos maiores é o que funcionou melhor para mim.
Primeiro você precisa de uma classe Singleton em, digamos, "./utils/Singleton.ts" :
Agora imagine que você precisa de um roteador singleton "./navigation/Router.ts" :
Nice !, agora inicialize ou importe onde você precisar:
O bom de fazer singletons dessa maneira é que você ainda usa toda a beleza das classes datilografadas, isso proporciona um bom senso de sentido, a lógica do singleton se mantém de alguma maneira separada e é fácil de remover, se necessário.
fonte
Minha solução para isso:
fonte
return Modal._instance
. Dessa forma, se vocênew
classifica essa classe, obtém o objeto existente, não um novo.No texto datilografado, não é necessário necessariamente seguir a
new instance()
metodologia Singleton. Uma classe estática importada e sem construtores também pode funcionar igualmente.Considerar:
Você pode importar a classe e consultar
YourSingleton.doThing()
em qualquer outra classe. Mas lembre-se, como essa é uma classe estática, ela não tem construtor, por isso geralmente uso umintialise()
método chamado de uma classe que importa o Singleton:Não esqueça que, em uma classe estática, todos os métodos e variáveis também precisam ser estáticos, portanto, em vez de
this
você usar o nome completo da classeYourSingleton
.fonte
Aqui está mais uma maneira de fazer isso com uma abordagem javascript mais convencional usando um IFFE :
Ver uma demonstração
fonte
Instance
variável? Você pode simplesmente colocar a variável e as funções diretamente abaixoApp.Counter
.Outra opção é usar símbolos no seu módulo. Dessa forma, você pode proteger sua classe, também se o usuário final da sua API estiver usando Javascript normal:
Uso:
Se o usuário estiver usando o arquivo js da API compilada, também ocorrerá um erro se ele tentar instanciar manualmente sua classe:
fonte
Não é um singleton puro (a inicialização pode não ser preguiçosa), mas padrão semelhante com a ajuda de
namespace
s.Acesso ao objeto de Singleton:
fonte
Esta é a maneira mais simples
fonte
Dessa forma, podemos aplicar uma interface, diferente da resposta aceita por Ryan Cavanaugh.
fonte
Depois de vasculhar esta discussão e brincar com todas as opções acima - resolvi com um Singleton que pode ser criado com os construtores adequados:
Isso exigiria uma configuração inicial (em
main.ts
, ouindex.ts
), que pode ser facilmente implementada pornew Singleton(/* PARAMS */)
Então, em qualquer lugar do seu código, basta ligar
Singleton.instnace
; neste caso, parawork
terminar, eu chamariaSingleton.instance.work()
fonte