La création d'une véritable classe singleton dans delphi


cet article décrit comment créer une classe qui suit le pattern singleton. La classe décrit prendra soin de le singleton exigences et les effets sur lui-même, pour effet de laisser au programmeur d'utiliser la classe comme tout les autres.
Un singleton est une classe qui prend en charge la création d'un seul objet. C'est comme votre ordinateur, il y a juste un clavier. Donc, si vous avez écrit le code Delphi qui a simulé votre ordinateur, vous souhaitez simplement une instance de l'objet à traiter avec le clavier de lecture, d'écriture et les activités de contrôle.
Articles à propos de singleton classes sont rares, mais il ya un peu sur Internet. J'ai vu quelques-uns dans les magazines. Mais aucun de ces articles comprennent des exemples de code pour créer une véritable classe singleton.
Par 'réel', je veux dire que la classe elle-même impose une instance exigence, au lieu de laisser cette tâche pour le programmeur. Tous les articles que j'ai vu jusqu'à présent ont exigé le programmeur d'utiliser la classe d'une manière spéciale à appliquer le pattern singleton.
Dans cet article, vous verrez comment créer une bonne classe singleton qui inclut la logique à appliquer l'une instance de la règle.
Remarque: L'approche conventionnelle, dans lequel une instance de la règle est maintenue explicitement par le programmeur, n'est pas sans mérite. Réel singleton classes comme celle que je présente ici effectivement masquer les détails et la sensibilisation du pattern singleton du programmeur. Le programmeur est déchargé de la tâche de faire respecter le modèle & c'est bien, mais le programmeur peut aussi ne pas être conscients de la nature particulière de la classe, ce qui est mauvais. Si vous ne savez pas que la classe est une classe singleton alors toutes sortes d'erreurs peuvent survenir. Vous avez été averti!
l'Écriture de code
Notre objectif est d'écrire une classe qui peut être utilisée comme ceci:

procédure de Test
var
& nbsp & nbsp s1, s2 : TSingleton
begin
& nbsp & nbsp s1 := TSingleton.Créer
& nbsp & nbsp s2 := TSingleton.Créer
& nbsp & nbsp // Faire quelque chose avec s1 et s2 ici
& nbsp & nbsp s2.Gratuit
& nbsp & nbsp s1.Gratuit
fin


(je l'ai laissé de côté l'essayer...enfin les blocs et les autres mesures de protection pour des raisons de simplicité.)
L'objectif est de faire de la TSingleton classe se comporter de telle manière que les deux s1 et s2 se référer au même objet. Voici ce que nous avons à faire:


  • Instancier l'objet la première fois de Créer est appelé (lorsque s1 est créé au-dessus)
  • assurez-vous que lorsqu'un autre Créer est exécutée (s2 ci-dessus), l'objet existant est réutilisés au lieu d'une autre créée
  • Éviter de détruire l'objet lorsqu'il n'est pas le dernier de référence qui est détruit (lorsque s2 est libérée)
  • Détruire l'instance lorsque la dernière référence est détruit (lorsque s1 est libérée ci-dessus)


Est-il possible de remplacer la création et la destruction d'un nouvel objet en Delphi? Il est sûr. Dans la classe TObject (la mère de tous les objets {pun intended}), il existe deux méthodes que nous pouvons utiliser:

fonction de classe NewInstance: TObject virtuel
procédure FreeInstance virtuel


NewInstance est responsable de l'allocation de mémoire pour contenir une nouvelle instance de la classe, et FreeInstance est responsable de la libération de la mémoire lorsque la classe est grâce à elle.
Ces méthodes de contrôle de ce qui se passe lorsque l'objet est créé et lorsque l'objet est détruit. Si l'on remplace ce code, nous pouvons modifier le comportement par défaut de travailler le dire une classe singleton exige. Rien.
le Suivi des cas est un peu plus délicat. Nous devons:


  1. Garder une trace de chaque instance de notre classe
  2. Garder une trace de la façon dont de nombreuses références y sont à cette instance
  3. Créer un nouvel objet uniquement si aucune instance existe
  4. destruction de l'objet lorsque la dernière référence est supprimée


Pour garder la trace d'une instance existante, nous allons utiliser une variable globale. En fait, la variable sera finalement déclaré à l'intérieur de la mise en Œuvre d'une unité afin de ne pas être un vrai variable globale. Mais le champ d'application doit être suffisante pour suivre toutes les Créer et les appels Gratuits. Nous allons appeler la variable d'Instance, donc nous savons de quoi il s'agit.
Comme pour garder une trace de la façon dont de nombreuses références existent, nous avons besoin d'une autre variable. Nous pouvons à l'intérieur de la classe ou de faire une sorte de global comme Exemple. Je vais opter pour la dernière méthode, mais de faire ce qui vous convient le mieux. Je vais le nom de cette variable Ref_Count.
Nous avons maintenant deux variables:

var
& nbsp & nbsp Exemple : TSingleton = nil
& nbsp & nbsp Ref_Count : Integer = 0


j'initialise les variables de sorte que, au départ, ils ne contiennent pas de déchets. Je sais que le compilateur le fait automatiquement, donc c'est juste un problème de lisibilité.
Nous allons avoir besoin de déclarer la TSingleton classe au-dessus de la variable de bloc, et si vous jetez un oeil à l'exemple de fichiers que vous pouvez télécharger à la fin de cet article, vous verrez que j'ai mis de la déclaration dans la partie interface de l'appareil de sorte qu'il est visible de l'extérieur.

Voici la déclaration de la TSingleton classe:

type
& nbsp & nbsp TSingleton = classe
& nbsp & nbsp public
& ! & ! & ! & nbsp fonction de classe NewInstance: TObject remplacer
& ! & ! & ! & nbsp procédure FreeInstance remplacer
& ! & ! & ! & nbsp fonction de classe RefCount: Integer
& nbsp & nbsp fin


j'ai ajouté le RefCount fonction de sorte que nous pouvons voir que cela fonctionne réellement, et il est souvent pratique de pouvoir lire comment de nombreuses références à l'objet existe. Il n'est pas nécessaire, cependant, de sorte que vous n'avez pas à l'ajouter à vos classes singleton si vous n'en avez pas besoin.
Ok, maintenant pour la mise en œuvre de l'une des trois méthodes:

procédure TSingleton.FreeInstance
begin
& nbsp & nbsp Dec( Ref_Count )
& nbsp & nbsp si ( Ref_Count = 0 ) then
& nbsp & nbsp commencer
& ! & ! & ! & nbsp Exemple := nil
& ! & ! & ! & nbsp // Détruire des variables privées ici
& ! & ! & ! & nbsp hérité FreeInstance
& nbsp & nbsp fin
fin
fonction de classe TSingleton.NewInstance: TObject
begin
& nbsp & nbsp si ( non Affecté( Exemple) )
& nbsp & nbsp commencer
& ! & ! & ! & nbsp Exemple := hérité NewInstance
& ! & ! & ! & nbsp // initialisation des variables privées ici, comme ceci:
& ! & ! & ! & nbsp // TSingleton(le Résultat).Variable := Valeur
& nbsp & nbsp fin
& nbsp & nbsp Résultat := Exemple
& nbsp & nbsp Inc( Ref_Count )
fin
fonction de classe TSingleton.RefCount: Integer
begin
& nbsp & nbsp Résultat := Ref_Count
fin


Et voilà!
Lorsque vous appelez TSingleton du constructeur, d'un appel à la méthode NewInstance déclaré dans TObject. Cette méthode alloue de la mémoire pour contenir le nouvel objet et le retourne pour le constructeur. Le constructeur utilise que de la mémoire et, éventuellement, retourne un pointeur vers la mémoire pour le code qui appelle le constructeur. Ce pointeur est généralement stocké dans une variable tandis que l'objet est en cours d'utilisation.
j'ai remplacé la méthode NewInstance donc il va allouer de la mémoire uniquement si aucune instance de la classe existe. Si il y a une instance existante, la fonction retourne simplement qu'une instance pour le constructeur de sorte qu'il sera réutilisé.
Si l'on appel le constructeur de trois fois, un objet est créé uniquement la première fois. Les deux autres appels simplement réutiliser le premier objet. La référence de la variable nombre de laissez-nous savoir que nous avons trois références à l'instance unique.
Lorsque le programme appelle le destructeur, un appel à FreeInstance est placé pour libérer la mémoire allouée dans le constructeur. Cette méthode, aussi, est remplacé, de sorte que l'objet est détruit que lorsque la dernière référence est supprimée.
Si vous avez l'intention d'utiliser un singleton dans un programme multithread, traiter l'objet comme vous le feriez pour n'importe quelle variable partagées entre les threads. Parce que c'est juste ce que vous faites: le partage entre les threads. Si vous devez prendre un soin particulier lors de la modification de données.
Simplicité
Comme vous pouvez le voir, la création d'une classe singleton ne nécessite pas beaucoup d'effort, juste le droit de connaissances et de quelques lignes de code. Mon code fonctionne très bien en Delphi 5. La technique sera probablement très bien avec les anciennes versions de Delphi, mais je ne l'ai pas testé donc je ne fais pas de garanties.
Avant de vous donner le fichier à jouer avec, permettez-moi de vous donner quelques mots de mise en garde.


  • Ne pas descendre d'une classe singleton. La raison pour cela est qu'il n'est qu'un exemple et de référence de la variable nombre. Si vous dérivez deux classes de TSingleton, un seul objet sera créé. L'autre catégorie de réutilisation de l'objet, qui sera une instance d'une classe différente. N'allez pas sur la route!
  • Vous ne pouvez pas faire singleton composants pour la simple raison de la propriété. Un composant est détenue par une forme et un composant ne peut pas être possédé par plusieurs autres composants.
  • ne pas oublier que le constructeur et le destructeur appelée pour chaque nouvelle référence qu'ils sont créés et détruits. Ne pas initialiser les variables privées dans le constructeur et ne pas les libérer dans le destructeur. Au lieu de cela, générer ce code dans les NewInstance et la FreeInstance méthodes, comme indiqué dans les commentaires.
  • La commande de réglage de Ref_Count dans les deux méthodes en parallèle avec le reste du code dans ces deux méthodes est essentielle. Il a à voir avec la réalisation correcte de la création et de la destruction lorsque quelque chose va mal. Si votre code d'initialisation soulève une exception, l'ordre de faire les choses comme indiqué ci-dessus assurez-vous que la classe est détruite correctement. Modifier ce code à vos risques et périls!
    Le fichier que vous pouvez télécharger est juste une copie de l'unité qui déclare la classe singleton décrit dans cet article.
    Lien vers le fichier: CodeCentral entrée 15083.
    je suis sûr que vous pouvez trouver quelques endroits où une classe singleton est très pratique et vous avez maintenant les outils pour créer votre propre! Si vous souhaitez entrer en contact avec moi, mon email est [email protected]
    bonne programmation!









La creation d'une veritable classe singleton dans delphi


La creation d'une veritable classe singleton dans delphi : Plusieurs milliers de conseils pour vous faciliter la vie.


cet article decrit comment creer une classe qui suit le pattern singleton. La classe decrit prendra soin de le singleton exigences et les effets sur lui-meme, pour effet de laisser au programmeur d'utiliser la classe comme tout les autres.
Un singleton est une classe qui prend en charge la creation d'un seul objet. C'est comme votre ordinateur, il y a juste un clavier. Donc, si vous avez ecrit le code Delphi qui a simule votre ordinateur, vous souhaitez simplement une instance de l'objet a traiter avec le clavier de lecture, d'ecriture et les activites de controle.
Articles a propos de singleton classes sont rares, mais il ya un peu sur Internet. J'ai vu quelques-uns dans les magazines. Mais aucun de ces articles comprennent des exemples de code pour creer une veritable classe singleton.
Par 'reel', je veux dire que la classe elle-meme impose une instance exigence, au lieu de laisser cette tache pour le programmeur. Tous les articles que j'ai vu jusqu'a present ont exige le programmeur d'utiliser la classe d'une maniere speciale a appliquer le pattern singleton.
Dans cet article, vous verrez comment creer une bonne classe singleton qui inclut la logique a appliquer l'une instance de la regle.
Remarque: L'approche conventionnelle, dans lequel une instance de la regle est maintenue explicitement par le programmeur, n'est pas sans merite. Reel singleton classes comme celle que je presente ici effectivement masquer les details et la sensibilisation du pattern singleton du programmeur. Le programmeur est decharge de la tache de faire respecter le modele & c'est bien, mais le programmeur peut aussi ne pas etre conscients de la nature particuliere de la classe, ce qui est mauvais. Si vous ne savez pas que la classe est une classe singleton alors toutes sortes d'erreurs peuvent survenir. Vous avez ete averti!
l'Ecriture de code
Notre objectif est d'ecrire une classe qui peut etre utilisee comme ceci:

procedure de Test
var
& nbsp & nbsp s1, s2 : TSingleton
begin
& nbsp & nbsp s1 := TSingleton.Creer
& nbsp & nbsp s2 := TSingleton.Creer
& nbsp & nbsp // Faire quelque chose avec s1 et s2 ici
& nbsp & nbsp s2.Gratuit
& nbsp & nbsp s1.Gratuit
fin


(je l'ai laisse de cote l'essayer...enfin les blocs et les autres mesures de protection pour des raisons de simplicite.)
L'objectif est de faire de la TSingleton classe se comporter de telle maniere que les deux s1 et s2 se referer au meme objet. Voici ce que nous avons a faire:


  • Instancier l'objet la premiere fois de Creer est appele (lorsque s1 est cree au-dessus)
  • assurez-vous que lorsqu'un autre Creer est executee (s2 ci-dessus), l'objet existant est reutilises au lieu d'une autre creee
  • Eviter de detruire l'objet lorsqu'il n'est pas le dernier de reference qui est detruit (lorsque s2 est liberee)
  • Detruire l'instance lorsque la derniere reference est detruit (lorsque s1 est liberee ci-dessus)


Est-il possible de remplacer la creation et la destruction d'un nouvel objet en Delphi? Il est sûr. Dans la classe TObject (la mere de tous les objets {pun intended}), il existe deux methodes que nous pouvons utiliser:

fonction de classe NewInstance: TObject virtuel
procedure FreeInstance virtuel


NewInstance est responsable de l'allocation de memoire pour contenir une nouvelle instance de la classe, et FreeInstance est responsable de la liberation de la memoire lorsque la classe est grace a elle.
Ces methodes de controle de ce qui se passe lorsque l'objet est cree et lorsque l'objet est detruit. Si l'on remplace ce code, nous pouvons modifier le comportement par defaut de travailler le dire une classe singleton exige. Rien.
le Suivi des cas est un peu plus delicat. Nous devons:


  1. Garder une trace de chaque instance de notre classe
  2. Garder une trace de la façon dont de nombreuses references y sont a cette instance
  3. Creer un nouvel objet uniquement si aucune instance existe
  4. destruction de l'objet lorsque la derniere reference est supprimee


Pour garder la trace d'une instance existante, nous allons utiliser une variable globale. En fait, la variable sera finalement declare a l'interieur de la mise en Œuvre d'une unite afin de ne pas etre un vrai variable globale. Mais le champ d'application doit etre suffisante pour suivre toutes les Creer et les appels Gratuits. Nous allons appeler la variable d'Instance, donc nous savons de quoi il s'agit.
Comme pour garder une trace de la façon dont de nombreuses references existent, nous avons besoin d'une autre variable. Nous pouvons a l'interieur de la classe ou de faire une sorte de global comme Exemple. Je vais opter pour la derniere methode, mais de faire ce qui vous convient le mieux. Je vais le nom de cette variable Ref_Count.
Nous avons maintenant deux variables:

var
& nbsp & nbsp Exemple : TSingleton = nil
& nbsp & nbsp Ref_Count : Integer = 0


j'initialise les variables de sorte que, au depart, ils ne contiennent pas de dechets. Je sais que le compilateur le fait automatiquement, donc c'est juste un probleme de lisibilite.
Nous allons avoir besoin de declarer la TSingleton classe au-dessus de la variable de bloc, et si vous jetez un oeil a l'exemple de fichiers que vous pouvez telecharger a la fin de cet article, vous verrez que j'ai mis de la declaration dans la partie interface de l'appareil de sorte qu'il est visible de l'exterieur.

Voici la declaration de la TSingleton classe:

type
& nbsp & nbsp TSingleton = classe
& nbsp & nbsp public
& ! & ! & ! & nbsp fonction de classe NewInstance: TObject remplacer
& ! & ! & ! & nbsp procedure FreeInstance remplacer
& ! & ! & ! & nbsp fonction de classe RefCount: Integer
& nbsp & nbsp fin


j'ai ajoute le RefCount fonction de sorte que nous pouvons voir que cela fonctionne reellement, et il est souvent pratique de pouvoir lire comment de nombreuses references a l'objet existe. Il n'est pas necessaire, cependant, de sorte que vous n'avez pas a l'ajouter a vos classes singleton si vous n'en avez pas besoin.
Ok, maintenant pour la mise en œuvre de l'une des trois methodes:

procedure TSingleton.FreeInstance
begin
& nbsp & nbsp Dec( Ref_Count )
& nbsp & nbsp si ( Ref_Count = 0 ) then
& nbsp & nbsp commencer
& ! & ! & ! & nbsp Exemple := nil
& ! & ! & ! & nbsp // Detruire des variables privees ici
& ! & ! & ! & nbsp herite FreeInstance
& nbsp & nbsp fin
fin
fonction de classe TSingleton.NewInstance: TObject
begin
& nbsp & nbsp si ( non Affecte( Exemple) )
& nbsp & nbsp commencer
& ! & ! & ! & nbsp Exemple := herite NewInstance
& ! & ! & ! & nbsp // initialisation des variables privees ici, comme ceci:
& ! & ! & ! & nbsp // TSingleton(le Resultat).Variable := Valeur
& nbsp & nbsp fin
& nbsp & nbsp Resultat := Exemple
& nbsp & nbsp Inc( Ref_Count )
fin
fonction de classe TSingleton.RefCount: Integer
begin
& nbsp & nbsp Resultat := Ref_Count
fin


Et voila!
Lorsque vous appelez TSingleton du constructeur, d'un appel a la methode NewInstance declare dans TObject. Cette methode alloue de la memoire pour contenir le nouvel objet et le retourne pour le constructeur. Le constructeur utilise que de la memoire et, eventuellement, retourne un pointeur vers la memoire pour le code qui appelle le constructeur. Ce pointeur est generalement stocke dans une variable tandis que l'objet est en cours d'utilisation.
j'ai remplace la methode NewInstance donc il va allouer de la memoire uniquement si aucune instance de la classe existe. Si il y a une instance existante, la fonction retourne simplement qu'une instance pour le constructeur de sorte qu'il sera reutilise.
Si l'on appel le constructeur de trois fois, un objet est cree uniquement la premiere fois. Les deux autres appels simplement reutiliser le premier objet. La reference de la variable nombre de laissez-nous savoir que nous avons trois references a l'instance unique.
Lorsque le programme appelle le destructeur, un appel a FreeInstance est place pour liberer la memoire allouee dans le constructeur. Cette methode, aussi, est remplace, de sorte que l'objet est detruit que lorsque la derniere reference est supprimee.
Si vous avez l'intention d'utiliser un singleton dans un programme multithread, traiter l'objet comme vous le feriez pour n'importe quelle variable partagees entre les threads. Parce que c'est juste ce que vous faites: le partage entre les threads. Si vous devez prendre un soin particulier lors de la modification de donnees.
Simplicite
Comme vous pouvez le voir, la creation d'une classe singleton ne necessite pas beaucoup d'effort, juste le droit de connaissances et de quelques lignes de code. Mon code fonctionne tres bien en Delphi 5. La technique sera probablement tres bien avec les anciennes versions de Delphi, mais je ne l'ai pas teste donc je ne fais pas de garanties.
Avant de vous donner le fichier a jouer avec, permettez-moi de vous donner quelques mots de mise en garde.


  • Ne pas descendre d'une classe singleton. La raison pour cela est qu'il n'est qu'un exemple et de reference de la variable nombre. Si vous derivez deux classes de TSingleton, un seul objet sera cree. L'autre categorie de reutilisation de l'objet, qui sera une instance d'une classe differente. N'allez pas sur la route!
  • Vous ne pouvez pas faire singleton composants pour la simple raison de la propriete. Un composant est detenue par une forme et un composant ne peut pas etre possede par plusieurs autres composants.
  • ne pas oublier que le constructeur et le destructeur appelee pour chaque nouvelle reference qu'ils sont crees et detruits. Ne pas initialiser les variables privees dans le constructeur et ne pas les liberer dans le destructeur. Au lieu de cela, generer ce code dans les NewInstance et la FreeInstance methodes, comme indique dans les commentaires.
  • La commande de reglage de Ref_Count dans les deux methodes en parallele avec le reste du code dans ces deux methodes est essentielle. Il a a voir avec la realisation correcte de la creation et de la destruction lorsque quelque chose va mal. Si votre code d'initialisation souleve une exception, l'ordre de faire les choses comme indique ci-dessus assurez-vous que la classe est detruite correctement. Modifier ce code a vos risques et perils!
    Le fichier que vous pouvez telecharger est juste une copie de l'unite qui declare la classe singleton decrit dans cet article.
    Lien vers le fichier: CodeCentral entree 15083.
    je suis sûr que vous pouvez trouver quelques endroits ou une classe singleton est tres pratique et vous avez maintenant les outils pour creer votre propre! Si vous souhaitez entrer en contact avec moi, mon email est [email protected]
    bonne programmation!


La création d'une véritable classe singleton dans delphi

La création d'une véritable classe singleton dans delphi : Plusieurs milliers de conseils pour vous faciliter la vie.
Recommander aux amis
  • gplus
  • pinterest

Messages récents

Commentaire

Laisser un commentaire

évaluation