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

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Points : 26
    Points
    26
    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 sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 549
    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 549
    Points : 25 119
    Points
    25 119
    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
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Points : 26
    Points
    26
    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 sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 549
    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 549
    Points : 25 119
    Points
    25 119
    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
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Points : 26
    Points
    26
    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 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 448
    Points
    28 448
    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

  7. #7
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    L'utilisation d'une TStringList peut être pas mal en effet mais je pense qu'en couplant le TObjectList qui permet de gérer la libération automatiquement des instances et le ClassName qui contient déjà le nom de la classe on obtient de meilleurs résultats.

    Par exemple le code suivant :

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    interface
    uses Contnrs;
     
      // accesseur public pour la liste contenant les instances d'objets
      function ObjectsManager: TObjectList;
      // deux méthodes pour ajouter une instance d'une classe quelconque à la liste
      procedure AddClassInstance( AClass: TClass ); overload;
      procedure AddClassInstance( AObject: TObject ); overload;
      // routine pour récupérer l'instance depuis son nom de classe
      function GetObjectByName( const AClassName: String ): TObject;
     
    implementation
     
    uses SysUtils;
     
    var
      // variable "privée" de la liste des instances d'objets
      voObjectsManager: TObjectList;
     
    function ObjectsManager: TObjectList;
    begin
      // si la liste n'est pas encore crée alors le faire
      // noter que OwnedObject est ici à True donc quand la liste sera détruite alors
      // les instancas d'objets seront détruites elles aussi => pas de gestion mémoire à effectuer
      if not Assigned( voObjectsManager ) then
       voObjectsManager := TObjectList.Create;
     
      Result := voObjectsManager;
    end;
     
    // ajouter une instance d'objet via sa classe, ceci peut poser problème si jamais
    // on a un constructeur avec paramètres ou que l'on veut utiliser initialiser l'objet
    // avant, dans ce cas utiliser l'autre version
    procedure AddClassInstance( AClass: TClass );
    begin
      if not Assigned( GetObjectByName( AClass.ClassName ) ) then
       ObjectsManager.Add( AClass.Create );
    end;
     
    // ajouter une instance d'objet via un objet déjà instancier
    // attention que cet objet sera détruit en même temps que la liste, ne pas faire
    // de Free sur cet objet
    procedure AddClassInstance( AObject: TObject );
    begin
      if not Assigned( GetObjectByName( AObject.ClassName ) ) then
       ObjectsManager.Add( AObject );
    end;
     
    function GetObjectByName( const AClassName: String ): TObject;
    var
     Cpt: Integer;
    begin
      // renvoyer NIL par défaut
      Result := NIL;
     
      // si le nom de classe est vide ou si la liste ne contient pas d'instance alors sortir
      if ( AClassName = '' ) or ( ObjectsManager.Count = 0 ) then
       Exit;
     
      // sinon boucler jusqu'à trouver l'instance dont le nom de classe correspond
      Cpt := 0;
      while not Assigned( Result ) and ( Cpt < ObjectsManager.Count ) do
       if ObjectsManager[Cpt].ClassNameIs( AClassName ) then
        Result := ObjectsManager[Cpt]
       else
        Inc( Cpt );
     
    end;
     
    initialization
      // initialisation de la variable "privée"
      voObjectsManager := NIL;
     
    finalization
      // si la liste des instances est créé alors la supprimer
      if Assigned( voObjectsManager ) then
       FreeAndNil( voObjectsManager );
    Après il suffit juste d'appeler une des versions de AddClassInstance pour chaque classe à ajouter (dans le Initialize par exemple) puis appeler GetObjectByName pour récupérer l'instance de l'objet.
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 549
    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 549
    Points : 25 119
    Points
    25 119
    Par défaut
    Effectivement, La méthode de la TStringList (ObjectList) est très utile lorsque l'on a beaucoup de classe (je pense par exemple à l'une de mes réalisations professionnelles qui gèraient l'importation et la transformation de plus d'une centaine de format de fichier Comptable ou Santé (SAGE, CIEL, CEGI, NX, CCAM, CIM10, ...) en XML et bien sur chaque fichier avait sa classe ... avec la liste, on peut retirer les singletons par unité, mais en encapsulant proprement l'obtention des singletons dans la classe ancêtre on peut avoir un avantage non négligeable c'est que l'instance n'est créée qu'à partir du moment où s'est utile, et non pas dès le début [/B]... mais il est vrai qu'à l'époque, sur WinNT, les machines sur lesquelles nous travaillons n'avait que 256Mo de RAM, et l'on traiter des fichiers de plusieurs Go, l'économie mémoire était de mise pour bufferiser la lecture au maximum ... ah oui, en plus en améliorant\corrigeant mon exemplen on pourrait s'approcher de la gestion par Singleton décrite dans les Design Patterns ...

    Ce qui important c'est que l'ancêtre doit être au moins un TPersistent , on peut faire un RegisterClass, ce qui permet de gérer la recherche de la classe par le système interne de delphi, ...

    quelques extraits de code, biensur TSuper, THerite1 sont dans des unités différentes, même principe que le code de Aka Guymelef (mais avec TStringList) et totalement encapsulé dans une classe ...

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    type
      TSuper = Class(TPersistent)
      private
        class procedure Initialize();
        class procedure Finalize();
      public
        class function GetSingleton(const AClassName: string): TSuper; 
      end;
     
    implementation
     
    var
      _SingletonList: TStringList = nil;
     
    class procedure TSuper.Initialize();
    begin
      if not Assigned(_SingletonList) then
        _SingletonList := TStringList.Create();
    end
     
    class procedure TSuper.Finalize();
    var
      I: Integer;
    begin
      if Assigned(_SingletonList) then
      begin
        for I := 0 to _SingletonList.Count - 1 do
          _SingletonList.Objects[I].Free();
     
        _SingletonList.Free();
        _SingletonList := nil;
      end;
    end
     
    class function TSuper.GetSingleton(const AClassName: string): TSuper; 
    var
      I: Integer;
      SingletonClass: TPersistentClass;
    begin
      I := _SingletonList.IndexOf(AClassName);
      if I < 0 then
      begin
        SingletonClass := GetClass(AClassName);
        if Assigned(SingletonClass) then
        begin
          Result := SingletonClass.Create();
          _SingletonList.AddObject(AClassName, Result);
        end
        else
          Result := nil;
      end 
      else  
        Result := _SingletonList.Objects[I] as TSuper; 
    end;
     
    initialization
      TSuper.Initialize();
     
    finalization
      TSuper.Finalize();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      THerite1 = class(TSuper)
        ...
     end;
     
     
    initialization
      RegisterClass(THerite1);
    Enfin, il me semble que l'on parlait de XML, avec un XSL pour transformer le XML en DFM Text, on peut directement utilisé le système de Flux du TComponent ... résultat, on peut charger un XML sans presque aucun code Delphi, mais juste avec les RTTI et les propriétés publiées ... c'est qui est utilisé actuellement chez mon employeur pour générer des Formulaires dynamiques (stocké en XML et transformer à la volée), on peut le faire sans XSL, mais dans ce cas, avec un TXMLDocument, on peut facilement faire un code générique pour transformer un XMLNode vers un TComponent via TypInfo.SetPropValue


    .
    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

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Points : 26
    Points
    26
    Par défaut
    Bonsoir,

    Je vous remercie pour toutes vos réponses et je me permets de rebondir un peu sur la question en l'étendant à une nouvelle problématique :

    Est-il possible de décrire une classe ( au moins ses propriétés ) entièrement depuis un fichier xml ? Je m'explique :

    Imaginons que j'ai toujours une " Super Classe " ( ou plusieurs ) dont vont hériter toutes mes classes. Cette classe possède elle même une propriété ListeObjet de type TObjectList dont tout les objets sont de la même classe. Je voudrais donc pouvoir créé dynamiquement via la lecture d’un fichier xml un objet la classe des objets de ma ListeObjet.

    Je donne un déroulé ( grossier et volontairement simplifié ) type du processus :

    1- Je lis un fichier xml qui contient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="UTF-8"?>
    	<MaClasse NomClasse="MaClasse" Extends="MaSuperClasse" NomListeObjetClasse="MaListeObjetClasse">
    		<MaPropriete1 Type="integer" Visibility="public">...</MaPropriete1>
    		<MaPropriete2 Type="boolean" Visibility="public">...</MaPropriete1>
    		<MaPropriete3 Type="string" Visibility="public">...</MaPropriete1>
                    …
    	</MaClasse>
    2- Mon programme créé une classe « MaClasse » héritée de « MaSuperClasse ». Donc dans cette classe, j’aurais un TObjectList ( hérité de ma « SuperClasse » ) que je veux remplir avec des objets de la classe « MaListeObjetClasse » qui contient les propriétés MaPropriete1, MaPropriete1, MaPropriete1,…Et dans la foulée instancier un objet de type « MaClasse ».

    Voilà, je ne sais pas si je suis vraiment clair mais l'idée est là : décrire une classe via lecture des données dans un fichier xml. Le but étant de permettre l'ajout et la gestion de type d'objets ( nombreux ) en dynamique sans avoir à recompiler continuellement le programme...

  10. #10
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Pour cela je pense que tu vas devoir t'orienter vers les RTTI, qui permettent de faire de la réflexion sur les classes et autres.
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 549
    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 549
    Points : 25 119
    Points
    25 119
    Par défaut
    Citation Envoyé par Aka Guymelef Voir le message
    Pour cela je pense que tu vas devoir t'orienter vers les RTTI, qui permettent de faire de la réflexion sur les classes et autres.
    Merci Aka, ...
    Citation Envoyé par ShaiLeTroll Voir le message
    résultat, on peut charger un XML sans presque aucun code Delphi, mais juste avec les RTTI et les propriétés publiées ...
    .
    j'ai eu l'impression de "parler" dans le vide avec mes idées, puisque tout ce que je propose n'est pas assez simple ...

    Sinon chipster45, je confirme ce que je disais et je m'en doutais que ton idée allait bien plus loin que ce tu nous avait enoncé au début, tu veux faire une sorte de couche de persistance pour un Mapping Object de données (en XML ou DB SQL ???), personnellement, j'ai déjà fait cela pour un projet c'est fonctionnel mais codé en dur car la parti dynamique (le fichier XML de structure qui ressemble au tient ) n'est pas fini aujourd'hui, seul le moteur persistant RTTI\DB-SQL et le mapping façon DataSource pour lié les objets avec des controls visuels est fait, tout ce qui concerne le XML de structure généré par un site web n'est pas fait, nous étions 3 personnes sur le code, et je suis le seul encore présent dans la boite, et plus de budget pour ce projet inutilement ambitieux (eh on m'a proposé de faire un Ferrari au prix d'une Fiat, je n'ai pas hésité, trop fun ce dev, j'ai fait le moteur, manque juste la carrosserie ... ), surtout qu'il était prévu de faire de la génération de code delphi automatique via XSL à partir du XML de structure ... pour l'instant, l'automatique c'est mes petits mains ...

    ... juste comme ça, etudie InstantObject ou le modèle ECO ... c'est pointu, tient un message que j'ai écrit, lit le donc, cela ne contient que la partie interface de la classe "Super", et des Classes pour les relations entre les objets ... rien que le prototype peut te laisser voir tout le travail à effectuer ...
    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

  12. #12
    Membre chevronné

    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    1 519
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 1 519
    Points : 2 153
    Points
    2 153
    Billets dans le blog
    1
    Par défaut
    Je pense tout de même que la discussion a été intéressante dans le sens où l'on a pu voir toutes les possibilités de résoudre le problème suivant le niveau de complexité : du plus simple (juste les noms de classes) aux plus complexes (récupérer les propriétés).

    De toute façon je pense que dès qu'on parle d'export/import de classes avec leurs propriétés tout en essayant d'être un maximum générique il ne reste plus que les RTTI ou les ReadComponent/WriteComponent.

    Après les modèles ECO ou autre là c'est encore le domaine au-dessus mais ça oblige aussi à revoir la structure de son application. Chose pas forcement évidente sur une appli existante ou bien entamée...

    Non, vraiment bien cette discussion
    La FAQ - les Tutoriels - Le guide du développeur Delphi devant un problème

    Pas de sollicitations techniques par MP -

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Points : 26
    Points
    26
    Par défaut
    Bonsoir,

    Je dois avouer que je me frotte à quelque chose d'assez ardu pour mon niveau et que beaucoup de notions que vous abordez me sont tout simplement inconnues et donc je n'assimile pas forcément tout tout de suite ( Déja que je suis pas rapide ). Je vais voir ce qui se fait du côté des RTTI.

    Sinon chipster45, je confirme ce que je disais et je m'en doutais que ton idée allait bien plus loin que ce tu nous avait enoncé au début, tu veux faire une sorte de couche de persistance pour un Mapping Object de données (en XML ou DB SQL ???)
    En fait, je n'avais pas encore cette idée mais étant donné l'architecture finale du projet sur lequel je travaille ( très ressemblante au projet que tu désscris ), l'idée s'est imposé à moi que je devais essayer de mettre en place ce Mapping Object totalement basé sur des fichiers xml.

    En tous cas, je vous donne des news dès que j'aurais mis au point une solution à mon problème ( rapidement j'espère ).

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Points : 26
    Points
    26
    Par défaut
    Bonjour,

    Bon je commence à explorer les possibilités des RTTI. J'appréhende petit à petit les mécanismes. C'est vraiment très intérressant et je vois déja pas mal de possibilités pour mon projet mais je ne vois nulle part la possibilité ( la manière ? ) d'ajouter une propriété ? J'ai un peu étudier le sources de différents projets tels que mentionnés dans les articles mais je ne vois rien...

  15. #15
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 549
    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 549
    Points : 25 119
    Points
    25 119
    Par défaut
    "Ajouter une Propriété ?"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    THerite = Class(TSuper )
      private
        FToto: string;
      protected
        function GetToto(): string; virtual;
        procedure SetToto(const Value: string); virtual;
      published
        property Toto: string read GetToto write SetToto; 
      end;
    tu peux en ajoutant autant que tu veux à tes objets, ... si c'est de cela que tu parles ...

    Par contre, chaque modification de structure de xml entrainera forcément une modification du code (pour publier les nouveaux champs) et une recompilation, ... la persistance est quelque chose de très rigide, cela garanti de la cohérence de ton application mais cela contraint à une rigueur assez élévée, qui est parfois en contradiction avec certaines méthodes de développements ...

    la Structure des tes données sera immuable (à quelques bidules près), ou au contraire, évoluerons réguilèrement en fonction des besoins fonctionnels ???

    Tu devrais regarder "Expert Liaison de données XML" fourni avec Delphi, il pourrait te servir totalement pour mapper ton XML, c'est fourni autant l'utiliser ... le Mapping Object via RTTI est plus dans le cadre d'une Base de Données qui souvent moins "volatile" dans sa structure métier qu'un XML ...
    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

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 42
    Points : 26
    Points
    26
    Par défaut
    En fait, je parle d'ajouter des propriétés à l'exécution. Je vois notamment le projet SEPI qui le fait ( et largement plus même ) mais alors le code... J'en ai vu d'autres mais je n'ai pas encore été à fond dans le code ( notamment http://codecentral.borland.com/Item.aspx?id=16204 ), donc ça doit bien être possible de le faire.

    Pour le moment, j'arrive très bien à instancier mes objets en parsant mon fichier xml et même à " parcourir " mes objets avec les fonctions de type " RTTI " ( ce qui me facilite la vie d'ailleurs ).

    la Structure des tes données sera immuable (à quelques bidules près), ou au contraire, évoluerons régulièrement en fonction des besoins fonctionnels ???
    La structure évoluera un peu mais pas fondamentalement je pense mais j'aimerais bien " appréhender " la technique. On va dire que je voudrais partir d'une classe dont je créerais un objet et si dans mon fichier xml, je " découvre " des champs qui ne correspondent pas aux propriétés de cet objet, pouvoir les créer. Je vais regarder aussi " Expert Liaison de données XML " suivant ton conseil.

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