IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Variables globales section implémentation et objet singleton


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 931
    Billets dans le blog
    6
    Par défaut Variables globales section implémentation et objet singleton
    Bonjour,

    Je m'interrogeais sur la meilleure manière de faire pour un objet singleton utilisant des procédures requérant des variables globales.

    La structure actuelle est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    implementation
     
    var
      UneSeuleInstance: TMyObject = nil;
      // ici les variables utiles à mes procédures, settées par mon objet
      procVar1, procVar2: integer;
     
    procedure CallBack(aParam: integer);
    begin
     //...
    end;
     
    procedure TMyObject.Create;
    begin
      if Assigned(UneSeuleInstance)
      then raise Exception.Create('Une seule instance de TMyObject autorisée ; désolé.')
      else inherited Create;
      UneSeuleInstance:=self; // car singleton
      //...
    end;
    Serait-il plus "propre" de déclarer les procVar en :
    1) class var en "compliquant" leur appel dans les CallBacks (TMyObject.procVar1) ?
    2) membres privés de la classe, puisqu'une seule instance (UneSeuleInstance.procVar1) ?
    3) autre ?

    Merci pour vos avis !
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  2. #2
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    bonjour,

    le singleton est instancié (a priori), il n'y a donc pas lieu d'avoir des membres de classe

    maintenant deux choses, soit tu fais de l'objet, soit tu n'en fais pas

    version "moins" objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    unit MonUnit;
     
    interface
     
    type
      TMyObject = class
      end;
     
    function GetInstance: TMyObject;
     
    implementation
     
    type
    // on peut en profiter pour ajouter des choses invisibles
      TMyObject2 = class(TMyObject)
      end;
     
    var
      Instance: TMyObject2 = nil;
     
    function GetIsntance: TMyObject;
    begin
      if Instance = nil then
       Instance := TMyObject2.Create;
      Result := Instance;
    end;
     
    end.
    version "plus" objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    unit MonUnit;
     
    interface
     
    type
      TMyObject = class
        class var Instance: TMyObject;
        class function GetInstance: TMyObject;
      end;
     
    implementation
     
    function TMyObject.GetInstance: TMyObject;
    begin
      if Instance = nil then
       Instance := TMyObject.Create;
      Result := Instance;
    end;
     
    end.
    tu peux aussi surcharger le constructeur pour lever une exception

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    unit MonUnit;
     
    interface
     
    type
      TMyObject = class
       private
        class var Instance: TMyObject;
        constructor CreateInstance;
       public
        constructor Create; override;
        class function GetInstance: TMyObject;
      end;
     
    implementation
     
    constructor TMyObject.Create;
    begin
       raise Exception.Create('Use TMyObject.GetInstance()');
    end;
     
    constructor TMyObject.CreateInstance;
    begin
      inherited Create;
    end;
     
    function TMyObject.GetInstance: TMyObject;
    begin
      if Instance = nil then
       Instance := TMyObject.CreateInstance;
      Result := Instance;
    end;
     
    end.
    NB: outre les questions philosophiques, il n'y a pas de différence technique entre la version "moins" objet et la version "plus" objet

    et dans les deux cas je considère qu'il faut retourner l'instance existante au lieu de lever une exception comme tu le fais.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 931
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 931
    Billets dans le blog
    6
    Par défaut
    Merci, Paul, pour tes exemples et avoir alimenté ma réflexion
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  4. #4
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 527
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 527
    Par défaut
    Paul, je trouve sympa ta troisième méthode sauf que ... pour le create, pas d'override

    Ensuite, j'ai essayé (juste en changeant le nom, donc sans conséquence):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    uses SysUtils;
     
    type
     
      TSingleton = class
      private
        class var Instance: TSingleton;
        constructor CreateInstance;
      public
        constructor Create;
        class function GetInstance: TSingleton;
      end;
     
    implementation
     
    { TSingleton }
     
    constructor TSingleton.Create;
    begin
      raise Exception.Create('Use TSingleton.GetInstance()');
    end;
     
    constructor TSingleton.CreateInstance;
    begin
      inherited Create;
    end;
     
    class function TSingleton.GetInstance: TSingleton;
    begin
      if Instance = nil then
        Instance := TSingleton.CreateInstance;
      Result := Instance;
    end;
    et dans une fiche appelante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    uses UnitSingleton;
     
    var
      Singleton: UnitSingleton.TSingleton;
     
    procedure TForm2.Button1Click(Sender: TObject);
    begin
      Singleton := UnitSingleton.TSingleton.GetInstance;
      Singleton.Free;
    end;
    Le premier clic passe sans problème.
    Pour le second clic:
    ---------------------------
    Opération de pointeur incorrecte.
    ---------------------------

    ça devrait pourtant fonctionner non ??


    le troisième clic me renvoie une violation d'accès.

    Je suis sur un XE3

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 933
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 933
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    ça devrait pourtant fonctionner non ??
    Que vaut Instance après Singleton.Free

  6. #6
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 527
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 527
    Par défaut
    Je vais peut-être dire une connerie mais ... si ma variable Singleton représente la variable Instance, Instance est nil ...

    Ou alors, y'a un truc qui m'échappe

    J'ai remplacé le .Free par un FreeAndnil mais j'obtiens le même comportement

    Un peu bouché le papy aujourd'hui ????

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VxiR2] Variables globales et objets pour moyennes mobiles par mois glissant
    Par sfbertrand dans le forum Designer
    Réponses: 3
    Dernier message: 02/06/2009, 10h31
  2. Objet Connection variable global
    Par anikeh dans le forum Access
    Réponses: 6
    Dernier message: 23/08/2006, 19h37
  3. [C#] variables globales et bonne implémentation singleton
    Par grome dans le forum Windows Forms
    Réponses: 7
    Dernier message: 05/05/2006, 11h11
  4. Réponses: 5
    Dernier message: 25/05/2005, 22h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo