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 :

Retrouver une instance de classe par son nom


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Par défaut Décrire une classe via fichier XML
    Bonjour,


    J'ai dans mon programme une " SuperClasse " Abstraite dont dérive plusieurs autres classes ( nommons les " Classe1 ", " Classe2 " , ...). La " SuperClasse " contient une méthode " Ajouter " ( dont l'implémentation varie suivant la classe " fille " ).

    Je lis un fichier XML contenant des nodes dont le traitement varie suivant le nom du noeud. Chaque type de noeud correspond à une instance ( " Classe1 ", " Classe2 " ). Ces noeuds ont les memes noms que mes classes. ex :

    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
    <Classe1>
    ....
    </Classe1>
    <Classe2>
    ....
    </Classe2>
    <Classe1>
    ....
    </Classe1>
    <Classe1>
    ....
    </Classe1>
    <Classe2>
    ....
    </Classe2>
    Ce que je voudrais faire, c'est pouvoir appeller directement la bonne classe pour le traitement sans avoir à passer par quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if XMLNode.name = 'Classe1' then
    InstanceClasse1.add(XMLNode);
    Je voudrais donc pouvoir directement appeller la bonne classe ( ou l'objet...unique dans le programme et dont la rêgle de nommage est stricte ex : " MonClasse1 " ) du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TSuperClasse(RetrouveObjetParSonNom('Mon'+XMLNode.name )).add(XMLNode);
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TSuperClasse(RetrouveInstanceDeClasse(XMLNode.name )).add(XMLNode);
    Je précise que la " SuperClasse " ne dérive elle d'aucune classe et que " Classe1 " , " Classe2 " n'ont qu'une seule instance dans le programme.

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 089
    Par défaut
    Citation Envoyé par chipster45 Voir le message
    Je précise que la " SuperClasse " ne dérive elle d'aucune classe et que " Classe1 " , " Classe2 " n'ont qu'une seule instance dans le programme.
    Cela dérive forcément de TObject (c'est implicite, voir l'aide) même si tu as fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    type
      TSuperClass = class
        ...
      end;
    "Retrouver une instance de classe par son nom ?"

    Juste évite TSuperClass, comme nom, c'est réservé à la Référence de classe de TSuper ... mais je suppose que c'est juste un exemple ...

    Soit Tu confonds une Instance de Classe qui est un Objet
    Et une Référence de Classe qui est le "descripteur" (je ne trouve pas le bon mot) de ta Classe

    Soit, tu voulais parler de Singleton, je donc traiter les deux

    Pour Reférence de Class, j'ai fait exactement, la même chose pour ma couche de persistante, où dans un XML était décrit les classes de l'application, les relations entre classes, l'héritage, ... pour encaspuler la DB dans une couche Objet

    Il faut recenser les classes (hérité de TPersistent) avec RegisterClass, et faire ensuite FindClass

    Sinon, faire une TStringList, donc chaque objet pointe en fait une TClass ... et non une instance

    Pour Instance de Classe, un singleton ...

    il te suffit ce faire une méthode de classe abtraite dans Super

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class function GetInstance: TSuper; virtual; abstract
    et dans les sous classes

    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
     
    interface
     
    class function GetInstance: TSuper; override;
     
    implementation
     
    var
      _SingletonMaClasse1: TMaClasse1 = nil;
     
    class function TMaClasse1.GetInstance: TSuper; 
    begin
      if not Assigned(_SingletonMaClasse1) then
        _SingletonMaClasse1 := TMaClasse1.Create();
     
      Result := _SingletonMaClasse1;
    end;
     
    initialization
    //  _SingletonMaClasse1 := TMaClasse1.Create();
     
    finalization
      if Assigned(_SingletonMaClasse1) then
      begin
        _SingletonMaClasse1.Free();
        _SingletonMaClasse1 := nil;
      end;
    tu peux aussi faire une propriété publiée, mais il te faudra tout de même avoir une variable globale derrière

    PS : Si tu as Delphi 2006, ils ont ajouté les variables de classes, il me semble, tu devrais voir cela, si tu as Delphi 7 ou moins, mon code remplacera cette grosse lacune
    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

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Par défaut
    Soit Tu confonds une Instance de Classe qui est un Objet
    Et une Référence de Classe qui est le "descripteur" (je ne trouve pas le bon mot) de ta Classe. Soit, tu voulais parler de Singleton, je donc traiter les deux
    En fait, je n'ai qu'une seule instance par type de classe ( objets créés dans le " create " de ma " form " principale ). C'est pour cela que je recherche soit à retrouver mon objet par son nom ou soit par sa classe instanciée " unique " dans mon programme.

    Juste évite TSuperClass, comme nom, c'est réservé à la Référence de classe de TSuper ... mais je suppose que c'est juste un exemple ...
    Oui c'est un exemple.

    Pour Reférence de Class, j'ai fait exactement, la même chose pour ma couche de persistante, où dans un XML était décrit les classes de l'application, les relations entre classes, l'héritage, ... pour encaspuler la DB dans une couche Objet

    Il faut recenser les classes (hérité de TPersistent) avec RegisterClass, et faire ensuite FindClass
    Bon, je pense que c'est là que se situe actuellement mon problème. Je ne comprends pas bien l'utilisation du " RegisterClass ". Ma classe n'héritant pas d'un Tpersistent (?), je n'arrive pas à effectuer cette procédure ( et d'ailleurs ou faut-il l'implanter ? ) et donc je ne trouve pas la classe correspondante. En tout cas, ce n'est pas bien clair pour moi.

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 089
    Par défaut
    tu peux aussi faire ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    type
      TMyClassesType = (mcSuper, mcHerite1, mcHerite2);
      TSuper = Class
        ...
        class function GetInstance: TSuper; virtual; abstract;
      end;
      TSuperClass = class of TSuper;
      THerite1= Class(TSuper)
        ...
        class function GetInstance: TSuper; override;
      end;
     
    const
      MY_CLASSES : array[TMyClassesType] of TSuperClass = (TSuper, THerite1, THerite2)
    tu parcoures le tableau

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function GetIndexClasses(const AClassName: string): TMyClassesType;
    begin
      for Result := Low(TMyClassesType) to High(TMyClassesType) do
        if MY_CLASSES[Result].ClassName = AClassName then
          Exit;
      Result := mcSuper;
    end;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function RetrouveObjetParSonNom(const AClassName: string): TSuper;
    begin
      try
        Result := MY_CLASSES[GetIndexClasses(AClassName)].GetInstance;
      except
        on E: Exception do
          raise ExceptClass(E.ClassType).CreateFmt('la Classe %s n''a pas d''instance : "%s"', [AClassName, E.Message]);
      end;
    end;
    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

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Par défaut
    Merci beaucoup pour les réponses. J'ai finalement opté pour une solution " plus simple " et rapide à mettre en oeuvre ( c'est mon avis ) : J'ai créé une liste d'objet ( TObjectList ) dans laquelle j'ajoute tout mes objets dérivés de ma " Super Classe " à laquelle j'ai ajouté une propriété " Name " ( String ) qui me permet d'identifier directement l'objet et ensuite à chaque node de mon fichier XML, je compare son nom à tout les noms de ma liste d'objets et je peux ainsi " orienter " directement vers le bon objet pour traitement.

    Voilà Ca marche bien mais je rêve encore d'une fonction " GetObjectByName "

  6. #6
    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
    Citation Envoyé par chipster45 Voir le message
    Merci beaucoup pour les réponses. J'ai finalement opté pour une solution " plus simple " et rapide à mettre en oeuvre ( c'est mon avis ) : J'ai créé une liste d'objet ( TObjectList ) dans laquelle j'ajoute tout mes objets dérivés de ma " Super Classe " à laquelle j'ai ajouté une propriété " Name " ( String ) qui me permet d'identifier directement l'objet et ensuite à chaque node de mon fichier XML, je compare son nom à tout les noms de ma liste d'objets et je peux ainsi " orienter " directement vers le bon objet pour traitement.

    Voilà Ca marche bien mais je rêve encore d'une fonction " GetObjectByName "
    les solutions les plus simples sont parfois les meilleurs

    tu aurais aussi pu utiliser ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     ClassList:=TStringList.Create;
     ClassList.AddObject('Class1',TClasse1.Create);
     ClassList.AddObject('Class2',TClasse2.Create);
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. [Débutant] Appel d'une instance de classe par le nom de cette dernière
    Par Jean-Marie Grave dans le forum VB.NET
    Réponses: 16
    Dernier message: 22/08/2012, 19h33
  2. Réponses: 5
    Dernier message: 31/05/2012, 16h00
  3. Réponses: 3
    Dernier message: 30/05/2008, 11h31
  4. Réponses: 3
    Dernier message: 25/02/2007, 18h49
  5. Réponses: 8
    Dernier message: 19/10/2006, 15h41

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