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 :

alternatives aux variables globales


Sujet :

Langage Delphi

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    839
    Détails du profil
    Informations personnelles :
    Âge : 59
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 839
    Points : 262
    Points
    262
    Par défaut alternatives aux variables globales
    Bonjour,

    Partout on lit qu'il ne faut pas utiliser les variables globales.
    Mais peut on les éviter ?

    Autant je comprends que gerer 50 ou 100 variables globales serait dangeureux , on a quand même besoin de quelques variables qui sont propres à tout le programme.

    Dans mon appli en cours, j'ai choisi la méthode de faire une unité globale.pas où sont rassemblés toutes mes variables. J'ai environ 10 variables qui sont pour la plupart des strings représentant des chemin d'accès. Ces variables sont chargés au demarrage de l'appli depuis un fichier .ini propre à chaque utilisateur.

    Et vous; comment faites vous pour gerer des données communes à tout le programme , mais qui sont différentes en fonction des utilisateurs?

    Merci

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France, Marne (Champagne Ardenne)

    Informations forums :
    Inscription : Novembre 2006
    Messages : 249
    Points : 357
    Points
    357
    Par défaut
    Bonsoir,

    Le .ini ça date un peu.

    La base de registre ça sert aussi à cela.

    Sinon, selon les cas, pourquoi ne pas utiliser un fichier XML ?...

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    Alors non, les variables globales ce n'est pas "mal", pas plus que les fonctions non-objet ou le code procédural

    Ce qui est mal, c'est d'utiliser des variables globales alors quelle ne devrait pas l'être.

    Ton exemple d'usage est parfaitement légitime, je fais exactement la même chose, ce sont des valeurs initialisées au lancement du programme qui n'ont pas vocation à changer en cours d'exécution et qui sont utilisées à différents endroit, c'est parfait.

    Un exemple de mauvaise utilisation de variable globale, que je rencontre souvent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Form1.Caption := 'Hello';
    end;
    la méthode d'instance TForm1.Button1Click se retrouve liée à une instance spécifique Form1 et non l'instance en cours. Alors oui, ça fonctionne s'il n'existe qu'une seule instance de TForm1 et que celle-ci est crée en affectant la variable Form1. C'est même le cas si la fiche est crée automatiquement dans le .DPR, mais c'es très mal de faire ça

    la seule raison que je veux bien voir évoquer pour justifier de taper Form1, c'est pour avoir la complétion de code...mais c'est alors une erreur aussi, car il suffit d'utiliser Self !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Self.Caption := 'Hello';
    end;
    PS: EMC51 tu ne réponds pas à la question

    PS2: l'usage des variables globales est un sujet récurant...
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Points : 757
    Points
    757
    Par défaut
    Citation Envoyé par EMC51 Voir le message
    Bonsoir,

    Le .ini ça date un peu.

    La base de registre ça sert aussi à cela.

    Sinon, selon les cas, pourquoi ne pas utiliser un fichier XML ?...
    Sauf que si l'utilisateur a un jour besoin de bosser sur un autre poste, il n'aura plus ses paramètres personnels. Tandis qu'avec le .ini, il peut " l'emporter " avec lui et garder ainsi son parametrage perso.

    Les citations du genre "ça date un peu" je trouve que ça fait très "jeunisme" à outrance, sans forcément chercher à savoir ce qui est le plus pertinent, pratique et fonctionnel.

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    j'approuve le ini voire le XML , beaucoup moins la base de registre (quand on voit le b....l que c'est, autant s'en passer) .

    J'utilise beaucoup la SGBD pour stocker les préférences perso dans le cas d'une application multi-users (avantage , le user n'a pas besoin " d'emporter avec lui " son fichier de préférences).

    je pensais que l'on avait déjà répondu à tes introspections http://www.developpez.net/forums/d12...ace-variables/
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  6. #6
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Points : 757
    Points
    757
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    j'approuve le ini voire le XML , beaucoup moins la base de registre (quand on voit le b....l que c'est, autant s'en passer) .

    J'utilise beaucoup la SGBD pour stocker les préférences perso dans le cas d'une application multi-users (avantage , le user n'a pas besoin " d'emporter avec lui " son fichier de préférences).

    je pensais que l'on avait déjà répondu à tes introspections http://www.developpez.net/forums/d12...ace-variables/
    Bien entendu, que le SGBD est mieux que le ini, mais rien ne laissait supposer ici que l'appli en question ait un accès SGBD, bien au contraire dirais je même.

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Pour répondre aux variables globales, il y a aussi une méthode pour les encapsuler !

    Tu peux faire un record Contexte qui regroupe les paramétrages, tu peux subdiviser en sous record
    record ou classe !

    Il suffit de s'inspirer de TFormatSettings parfait exemple passage de globales à une approche plus "propre"

    J'ai du développer assez rapidement une extension réutilisable pour compenser une fonctionnalité manquante dans le logiciel principal
    L'intégration de cette fonctionnalité directement aurait été beaucoup plus longue avec trop d'impacts sur d'autres modules, j'ai donc fait un petit programme SANS DB, utilisant un ini pour la facilité de déploiement de modification via blocnote (les ini étant massivement utilisé dans le logiciel que je maintiens, trop je dirais même)

    j'ai été confronté à ce même problème "des strings représentant des chemin d'accès."

    Voici le prototype (j'ai juste changé les noms c'est le code réel)
    Pour gérer les globales, j'ai juste un singleton qui contient ce qu'il faut pour les éléments de base utilisés dans le WinMain (le DPR en Delphi) et un peu partout dans le projet

    Code c++ : 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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    //---------------------------------------------------------------------------
    //                        TPetitProjetEnvironnement                         -
    //---------------------------------------------------------------------------
    class TPetitProjetEnvironnement : public TObject
    {
    private:
      // Membres Privés (Singleton)
      static TPetitProjetEnvironnement *FSingletonInstance;
     
      // Membres Privés
      AnsiString FPathLogicielPrincipal;
      AnsiString FPathLogicielPrincipalIni;
      AnsiString FPathLogicielPrincipali18nIni;
      AnsiString FPathPetitProjetIni;
     
      HANDLE FMutexHandle;
      TUtilSociete *FUtilSociete;
      TIniFile* FPetitProjetIni;
     
    private:
      // Constructeurs Protégés (Masqués)
      /*constructor*/__fastcall TPetitProjetEnvironnement();
     
    public:
      // Constructeurs Publiques
      /*destructor*/virtual __fastcall ~TPetitProjetEnvironnement();
     
      // Méthodes Publiques (Singleton)
      static TPetitProjetEnvironnement* GetInstance();
      static TPetitProjetEnvironnement* Env() {return GetInstance();}
      static TPetitProjetEnvironnement* Ini() {return GetInstance();}
      static void ReleaseInstance();
     
      // Méthodes Publiques (Divers)
      static bool IsFirstInstance(TClass AWindowClass);
     
      // Méthodes Publiques (DLL)
      static bool ChargementDLLLogicielPrincipal();
      static bool DechargementDLLLogicielPrincipal();
     
      // Méthodes Publiques (Ini)
      AnsiString GetLogicielPrincipali18n(const AnsiString AIdent);
     
      // Propriétés Publiques
      __property AnsiString PathLogicielPrincipal = {read=FPathLogicielPrincipal};
      __property AnsiString PathLogicielPrincipalIni = {read=FPathLogicielPrincipalIni};
      __property AnsiString PathLogicielPrincipali18nIni = {read=FPathLogicielPrincipali18nIni};
      __property AnsiString PathPetitProjetIni = {read=FPathPetitProjetIni};
      __property TUtilSociete* UtilSociete= {read=FUtilSociete};
      __property TIniFile* PetitProjetIni = {read=FPetitProjetIni};
    };
    //---------------------------------------------------------------------------

    et un des nombreux cas d’utilisation

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void TPetitProjetDeviceManager::LoadDeviceList()
    {
      if (MainThreadID == GetCurrentThreadId())
      {
        TIniFile *ini = TPetitProjetEnvironnement::Ini()->PetitProjetIni;
        if (ini->SectionExists(DEVICE_SECTION_LIST))
        {
         ...

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    bool TPetitProjetDeviceManager::InternalPollStart()
    {
      int StartCount = 0;
     
      TPetitProjetEnvironnement::Env()->UtilSociete->Trace("StartPulser", "Lancement", true, true);
      FLogicielPrincipalEventPulser->StartPulser();
      ...

    C'est juste une histoire syntaxe, au lieu d'avoir un tas de globale, tu as une seule globale qui encapsule un tas de propriété et de fonctionnalité générale !
    Certains te diront que cela ressemble à une anti-pattern "Objet Divin" parce que c'est un fourre-tout sans cohérence !

    Il faut juste que le code te plaise ET qu'il FONCTIONNE
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 693
    Points : 13 128
    Points
    13 128
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Pour répondre aux variables globales, il y a aussi une méthode pour les encapsuler !
    C'est exactement ce que j'allais proposer avant de lire ton post
    C'est à mon sens la meilleure solution, la plus souple et... celle que j'utilise.

    Une seule méthode d'ouverture facilement adaptable (BdR, ini, xml, autres) et des propriétés encapsulées.
    Un des gros avantages est de permettre la modification "à la volée" sans redémarrer l'application (surtout si c'est un serveur).
    J'évite par contre le simple remplissage de variables. Même dans le cas d'un fichier, celui-ci est conservé en cache pour cause d'accès fréquents et ne souffre d'aucune latence

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 07/03/2012, 10h58
  2. [XL-2007] Accès aux variables globales
    Par ghosty177 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 19/01/2011, 14h39
  3. Astuce pour accès aux variables globales depuis une fonction
    Par manur0 dans le forum Général Python
    Réponses: 0
    Dernier message: 03/09/2009, 14h30
  4. une alternative aux variables globales ?
    Par scheme dans le forum Général Python
    Réponses: 18
    Dernier message: 24/07/2009, 00h55
  5. Accéder aux variables static du Global.asax
    Par tscoops dans le forum ASP.NET
    Réponses: 3
    Dernier message: 10/04/2007, 14h41

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