Quel est le moyen le meilleur et le plus pratique d'implémenter un modèle Singleton pour une classe dans TypeScript? (Avec et sans initialisation paresseuse).
singleton
typescript
maja
la source
la source
export default new Singleton()
?Depuis TS 2.0, nous avons la possibilité de définir des modificateurs de visibilité sur les constructeurs , donc maintenant nous pouvons faire des singletons dans TypeScript comme nous en avons l'habitude dans d'autres langages.
Exemple donné:
Merci @Drenai d'avoir souligné que si vous écrivez du code en utilisant le javascript compilé brut, vous n'aurez pas de protection contre l'instanciation multiple, car les contraintes de TS disparaissent et le constructeur ne sera pas masqué.
la source
Le meilleur moyen que j'ai trouvé est:
Voici comment vous l'utilisez:
https://codebelt.github.io/blog/typescript/typescript-singleton-pattern/
la source
L'approche suivante crée une classe Singleton qui peut être utilisée exactement comme une classe conventionnelle:
Chaque
new Singleton()
opération renverra la même instance. Cela peut cependant être inattendu par l'utilisateur.L'exemple suivant est plus transparent pour l'utilisateur mais nécessite une utilisation différente:
Usage:
var obj = Singleton.getInstance();
la source
new Class(...)
syntaxe.Je suis surpris de ne pas voir le modèle suivant ici, qui semble en fait très simple.
Usage
la source
Shout
Vous pouvez utiliser des expressions de classe pour cela (à partir de 1.6 je crois).
ou avec le nom si votre classe a besoin d'accéder à son type en interne
Une autre option consiste à utiliser une classe locale à l'intérieur de votre singleton en utilisant des membres statiques
la source
Ajoutez les 6 lignes suivantes à n'importe quelle classe pour en faire un "Singleton".
Exemple de test:
[Edit]: Utilisez Alex answer si vous préférez obtenir l'instance via une propriété plutôt qu'une méthode.
la source
new MySingleton()
, disons 5 fois? votre code réserve-t-il une seule instance?je pense que peut-être utiliser des génériques
comment utiliser
étape 1
étape 2
la source
Vous pouvez également utiliser la fonction Object.Freeze () . C'est simple et facile:
la source
if (!this.instance)
dans le constructeur? Est-ce juste une précaution supplémentaire au cas où vous auriez créé plusieurs instances avant l'exportation?J'ai trouvé une nouvelle version de ceci que le compilateur Typescript est tout à fait d'accord, et je pense qu'elle est meilleure car elle ne nécessite pas d'appeler une
getInstance()
méthode en permanence.Cela présente un inconvénient différent. Si vous
Singleton
avez des propriétés, le compilateur Typescript lèvera un ajustement à moins que vous ne les initialisiez avec une valeur. C'est pourquoi j'ai inclus une_express
propriété dans mon exemple de classe car à moins que vous ne l'initialisiez avec une valeur, même si vous l'assignez plus tard dans le constructeur, Typescript pensera qu'elle n'a pas été définie. Cela pourrait être résolu en désactivant le mode strict, mais je préfère ne pas le faire si possible. Il y a aussi un autre inconvénient à cette méthode que je dois souligner, car le constructeur est en fait appelé, chaque fois qu'il le fait, une autre instance est techniquement créée, mais pas accessible. Cela pourrait, en théorie, provoquer des fuites de mémoire.la source
C'est probablement le processus le plus long pour créer un singleton en tapuscrit, mais dans les applications plus importantes, c'est celui qui a le mieux fonctionné pour moi.
Vous avez d'abord besoin d'une classe Singleton dans, disons, "./utils/Singleton.ts" :
Imaginez maintenant que vous ayez besoin d'un singleton de routeur "./navigation/Router.ts" :
Nice !, maintenant initialisez ou importez où vous en avez besoin:
L'avantage de faire des singletons de cette façon est que vous utilisez toujours toute la beauté des classes dactylographiées, cela vous donne une belle intelligence, la logique des singleton reste en quelque sorte séparée et elle est facile à supprimer si nécessaire.
la source
Ma solution pour cela:
la source
return Modal._instance
. De cette façon, si vousnew
utilisez cette classe, vous obtenez l'objet existant, pas un nouveau.Dans Typescript, il n'est pas nécessaire de suivre les
new instance()
méthodologie Singleton. Une classe statique importée sans constructeur peut également fonctionner.Considérer:
Vous pouvez importer la classe et y faire référence
YourSingleton.doThing()
dans n'importe quelle autre classe. Mais rappelez-vous, comme il s'agit d'une classe statique, elle n'a pas de constructeur, donc j'utilise généralement uneintialise()
méthode appelée à partir d'une classe qui importe le Singleton:N'oubliez pas que dans une classe statique, chaque méthode et variable doit également être statique, donc au lieu d'
this
utiliser le nom complet de la classeYourSingleton
.la source
Voici encore une autre façon de le faire avec une approche javascript plus conventionnelle utilisant un IFFE :
Voir une démo
la source
Instance
variable? Vous pouvez simplement mettre la variable et les fonctions directement sousApp.Counter
.Une autre option consiste à utiliser des symboles dans votre module. De cette façon, vous pouvez protéger votre classe, même si l'utilisateur final de votre API utilise du Javascript normal:
Usage:
Si l'utilisateur utilise votre fichier API js compilé, il obtiendra également une erreur s'il tente d'instancier manuellement votre classe:
la source
Pas un singleton pur (l'initialisation peut ne pas être paresseuse), mais un modèle similaire à l'aide de
namespace
s.Accès à l'objet de Singleton:
la source
C'est le moyen le plus simple
la source
De cette façon, nous pouvons appliquer une interface, contrairement à la réponse acceptée de Ryan Cavanaugh.
la source
Après avoir parcouru ce fil et joué avec toutes les options ci-dessus, je me suis installé avec un Singleton qui peut être créé avec les constructeurs appropriés:
Cela nécessiterait une configuration initiale (dans
main.ts
ouindex.ts
), qui peut facilement être implémentée parnew Singleton(/* PARAMS */)
Ensuite, n'importe où dans votre code, appelez simplement
Singleton.instnace
; dans ce cas, pourwork
faire, j'appelleraisSingleton.instance.work()
la source