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

Modélisation Discussion :

[AVIS] Conception d'un modèle pour gérer les liens entre plein d'objets


Sujet :

Modélisation

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 198
    Points : 106
    Points
    106
    Par défaut [AVIS] Conception d'un modèle pour gérer les liens entre plein d'objets
    Bonjour,

    Je suis actuellement entrain de concevoir une sorte de "framework" pour un gros logiciel écris en C++/MFC. Mise à part une petite problématique, je me pose surtout la question sur la qualité du modèle que je conçois. Je n'ai pas très grande expérience et c'est pour ça que je fais appel à vous.
    Donc premièrement j’ai une question ( que je poserai en fin ), deuxièmement je suis avide d’avis, de critique et de conseils (car je sens qu'il y a moyen de faire mieux) et petit troisièmement dites-moi si vous reconnaissez un pattern appliqué ( car même après les avoir lu et relu, je les reconnais difficilement).

    L'existant



    Tout d'abord, il y a l'existant sur lequel je n'ai aucun controle ou presque. On a une classe Record héritant sur plusieurs classe ( final order, material unit, job, ...). Tout ces objets sont directement ou indirectement liés entre eux. Prenons l'exemple des material unit qui peuvent être lié à 0 ou N FinalOrder et à 0 ou N job. La method GetAttribute permet d’obtenir à base d’un nom n’importe quel attribut non calculé.

    Le but de mon travail est de pouvoir obtenir des attributs calculé et non calculé, ainsi que d'obtenir des attributs d'une FinalOrder en partant de sa Material unit (ceci dans tous les sens de tous les type de record vers tout les type de record). Et tout ça de façon transparente.
    De cette manière l'affichage, et l'export doivent se faire simplement.

    Recherche du record



    Ilookup est une interface contenant les getters vers tous les objets. Elle hérite sur FinalOrderLookup, JobLookup, ... De cette manière, une fois qu’on a un Ilookup on peut accéder à tous les objets liés de façon transparente.


    Recherche d’attributs



    LookupOperation contient un Ilookup qui permet d’obtenir le bon type de record. Et les classes filles connaisse les traitements exacte à effectuer. Par exemple MaterialUnitDefaultOperation connaitra le traitement pour tout les attributs non calculés ( c’est toujours le même traitement pour les non calculé). La methode BuildOperation de IOperation se débrouille de trouver la bonne instance.

    ExportOperation, construit avec un IOperation et un flux de sortie, se débrouille pour exporter comme il faut.

    Le but est de construire une list de IOperation. Cette liste représente toutes les colonnes d’une vue liste. Pour l’affichage il suffira de créer un nouveau Ilookup et de le setter pour chaque ligne de la liste.

    Même chose pour ExportOperation, la différence est que je n’arrive pas à faire un ExportOperation qui fonctionne, génériquement, pour tous les IOperation ET qui me permette de setter un Lookup.
    Je pourrais setter un IOperation mais ca implequerait que je doive RE-retrouver le bon type de LookupOperation. Ou je pourrais faire contenir à ExportOperation un LookupOperation mais ca engendrerait une moins bonne généricité.

    Question :
    Comment pouvoir garder une certaine généricité (garder IOperation) et garder une certaine flexibilité (pouvoir setter simplement un ILookup) ?
    De façon à parourir une liste d’ExportOperation (la liste des différents attributs à exporter) et de pouvoir changer le ILookup pour chaque ligne à exporter.

    Un grand merci d’avoir déja tout lu

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 198
    Points : 106
    Points
    106
    Par défaut
    Un petit up :p
    Si quelque chose n'est pas clair, hésitez pas.

  3. #3
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    ben le problème c'est que l'on ne connait pas ton problème.
    Tu ne fais que présenter une solution à un problème que l'on ne connais pas.
    Bref, qu'est ce que tu cherches réellement à faire ?


    Pour te donner un exemple, je ne comprend pas pourquoi tu cherches à récupérer des attributs de manière générique (visiblement).

    En conception, soit on cherche à faire un truc générique mais souvent on s'engouffre dans un truc pas possible enfin, complexe, soit on se définit des........patterns et on les appliques à chaque fois que cela est nécessaire. Dans ce dernier cas, on peut être amené à écrire du code à chaque nouveauté mais au moins on a des choses plus simples en général.
    La généricité n'est pas toujours la bonne solution

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 198
    Points : 106
    Points
    106
    Par défaut
    Oui, j'ai mal posé le problème. Merci à toi de le souligner.

    En fait étant donné l'existant (Record et et dérives). Il y a pour chaque dérivé de Record un tas d'attributs différents calculé et non calculé. Il y a derrière ça un fichier de format par type de record, qui permet de lire et interpréter un fichier contenant les données. Tout cela est dynamique, chaque client a son type de format. Il y a juste certains attributs qui seront toujours commun et qui sont nécessaire au modèle.

    Le problème vient au moment de l'affichage et de l'export.
    Il faut pouvoir afficher et exporter TOUS les attributs et également tout les attributs d'un autre type de record lié. Ex: job->GetMaterialUnit()->GetAttributeValue("Attribut1");

    La généricité vient du fait qu'on a en input un fichier format d'export ou de configuration d'affichage.
    La syntax est grossièrement comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    "nomAttribut1"        of MaterialUnit
    "nomAttribut2"        of MaterialUnit
    "nomAttribut3"        of FinalOrder
    "nomAttribut4"        of Job
    "nomAttribut5"        of TypeRecord1
    Le format ci-dessous peut s'appliquer à n'importe quel type de Record. Si on export des Job, alors ca revient à faire job->MaterialUnit()->GetAttributeValue("nomAttribut1"); et ainsi de suite.

    En résumé, je dois développer une solution qui étant donné l'existant doit pouvoir, avec le fichier de format (ci-dessus), exporter et afficher les bons attributs.
    Question: Comment répondre à cette demande sans avoir 2 switch et une infinité de "case" ?
    Les images UML, me servent uniquement à présenter le problème, le problème n'est pas de comment le représenter en UML mais de le développer.

    Je présente ma solution dans le premier post parce que j'ai du pondre quelque chose pour le boulot mais je ne suis pas convaincu que ça soit la -meilleure-. (De plus une petite question pour ma solution expliqué au post 1 au niveau de ExportOperation mais moins important pour le moment).

  5. #5
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    il te faut des Builder qui connaissent eux la structure des données = un Builder par classe "fille" de Record.
    Il te faut de plus un mécanisme qui sait lire une ligne et en fonction du "of" va savoir quel Builder appeler. Au Builder on passe la string et lui il sait quel "set" faire

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 198
    Points : 106
    Points
    106
    Par défaut
    Faire le set de quoi ? Je ne suis pas sur de comprendre.
    Le builder me faisant pensé au pattern factory, un peu comme présenté dans ma solution, qui avec un string trouvait la bonne instance de classe. Mais je dois me tromper étant donné que tu parles de setter quelque chose.

  7. #7
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Points : 3 510
    Points
    3 510
    Billets dans le blog
    2
    Par défaut
    Builder, Factory oui c'est un peu pareil.
    Mais tu ne dis pas tout sur ton fichier.
    Par exemple, je ne vois pas comment tu sais de quel attribut il s'agit quand tu lis une ligne de ton fichier. Il te faut le nom de l'attribut + le nom de la classe + la valeur elle-même.
    Si ta ligne est toujours découpée de la même manière du genre :

    valeur;nom attribut;nom classe

    Il faut des factory/builder par classe comme tu as fait.
    Il faut un mécanisme générique qui lui fait la lecture de la ligne et récupère les 3 infos genre dans une StructuredLine qui comporte les données value,attribute,class.
    Chaque Builder/Factory est enregistré dans un dictionnaire ( ~ Hashtable) et la clé de recherche pour chaque Builder est le nom de la classe. Ainsi ton mécanisme de lecture peut récupérer le Builder en fonction de la ligne qu'il vient de récupérer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Ex : Builder *builder =builderDictionary->getBuilder(structuredLine->getClassName());
    Au final, tu as un truc du genre (j'ai fait un truc résumé et pour la syntaxe C++, ça fait hyper longtemps que je n'en ai pas écrit donc....) :
    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
    struct StructuredLine {
    	char *value;
    	char *attribute;
    	char *className;
    }
    
    // Utilisé pour stocker tous les objets créés lors de la lecture du fichier
    struct ObjectList {
    }
    
    initDictionary(BuilderDictionary *dictionary) {
    	dictionary->register("Class1",new Class1Builder());
    	dictionary->register("Class2",new Class2Builder());
    	dictionary->register("Class3",new Class3Builder());
    	...
    }
    
    readObjectFile(int fd,ObjectList *objectList,BuilderDictionary *dictionary) {
    	void *currentObject = null;
    	char *line = null;
    	char *currentClassName = null;
    	StructuredLine structuredLine;
    	
    while (!fin du fichier) {
            line = readline(fd);
    	if (line!=null) {
    		// Split de la ligne pour remplir structuredLine
    		...
    
    		Builder *builder = dictionary->getBuilder(structuredLine.className);
    		// On part du principe que tous les objets ont un builder sinon, il faut gérer en plus ce cas.
    		if (currentClassName==null || strcmp(currentClassName,structuredLine.className)!=0) {
    			// Nouvel objet à créer
    			if (currentObject!=null)
    				objectList->addObject(currentObject);
    			currentObject=null;
    			currentObject = builder->createObject();
    		}
    		// Chaque builder réel (sous classe de Builder) sait quoi affecter en fonction du nom de l'attribut lu. Il comporte, le builder, une série de strcmp pour tester les nom des attributs dans sa méthode "set"
    		builder->set(currentObject,structuredLine);
    	}
    	else {
    		// Fin du fichier, ne pas oublier le dernier objet non ajouté
    		if (currentObject!=null)
    			objectList->addObject(currentObject);
                    // positionner "fin du fichier"
    	}
     }
    }

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    198
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 198
    Points : 106
    Points
    106
    Par défaut
    Concernant le fichier format, il contient bien que deux valeurs (principale). Le nom de lattribut et le nom de classe, la valeur n’est pas dedans étant donné que c’est un format ( la valeur est dans le modèle ). C’est au moment de l’export (ou de l’affichage) que le programme connait la structure ( les colonnes ) à exporter. Au moment de l’export :
    1. On dit quelle type de record à exporter.
    2. On parse le fichier format (pour savoir quoi exporter)
    3. On dit quelle type de record à exporter.
    4. On parse le fichier format (pour savoir quoi exporter)
      1. Ca crée une liste des attributs à exporter
    5. On parcours la liste contenant ce type de record(nécéssité de l’étape 1)
    6. Pour chaque record, on parcours la liste des attributs à exporter.


    Donc la difficulté est de ne pas avoir un parser par type d’attributs. Ce mecanisme ne doit pas uniquement servir pour l’export mais aussi pour l’affichage ( même principe sauf qu’on écrit dans la vue et non dans un fichier).
    La liste des objets (objectList) crées lors de la lecture représente les colonnes d’un fichier d’export ? Ce sont ces objets qui pourront calculer la bonne valeur des attributs à exporter pour chaque ligne(record)?
    En tout cas merci de prendre de ton temps pour me répondre

Discussions similaires

  1. Quels modules Perl pour gérer les documents XML ?
    Par djibril dans le forum Modules
    Réponses: 8
    Dernier message: 02/12/2010, 23h54
  2. [Info] Conseils pour gérer les ressources
    Par calogerogigante dans le forum Eclipse Java
    Réponses: 10
    Dernier message: 05/07/2009, 12h49
  3. Réponses: 1
    Dernier message: 15/05/2008, 14h10
  4. Réponses: 13
    Dernier message: 07/02/2007, 12h10
  5. Méthode simple pour gérer les collisions
    Par Hyoga dans le forum OpenGL
    Réponses: 2
    Dernier message: 19/02/2005, 13h43

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