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

Java Discussion :

Construction d'objet : Attribut


Sujet :

Java

  1. #1
    Nouveau membre du Club
    Inscrit en
    Août 2011
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Août 2011
    Messages : 109
    Points : 32
    Points
    32
    Par défaut Construction d'objet : Attribut
    Bonjour.

    J'ai une question qui est la base du Java, mais je me la pose car je vois les différents codages : lequel utiliser?

    Je vais prendre un exemple simple avec un pays, qui contient des villes, elles-mêmes qui contiennent des quartiers
    Soit une base de données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Table Pays :
    - champ pays_id
    - champ pays_nom
     
    Table Ville : 
    - champ ville_id
    - champ ville_nom
    - champ ville_id_paysParent (provenant de A)
     
    Table quartier :
    - champ quartier_id
    - champ quartier_nom
    - champ quartier_id_villeParent (provenant de B)
    En JAVA, je vois différents codages :

    le 1er :
    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
    class Pays
    {
      int pays_id
      String pays_nom
      List<ville> listeVilles
    }
    class Ville
    {
     int ville_id
     String ville_nom
     List<quartier> listeQuartiers
    }
    class quartier :
    {
     int quartier_id
     String quartier_nom
    }
    Le problème de cette représentation est que lors du chargement des pays depuis la base de données, il faut aller lire les villes, puis les quartiers en cascade pour alimenter la liste de Ville de l'objet pays.
    --> En fonction de la structure de la base, on peut donc faire un grand nombre de requête en cascade, sachant que chaque objet va charger son objet "voisin". mais l'avantage est qu'une fois chargé, on a tout.

    le 2eme :
    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
    class Pays
    {
      int pays_id
      String pays_nom
    }
    class Ville
    {
     int ville_id
     String ville_nom
     Pays paysParent
    }
    class quartier :
    {
     int quartier_id
     String quartier_nom
     Ville villeParent
    }
    Cette représentation correspond à la base de données. Mais il y a toujours des requêtes en cascade car lors de la recherche des quartiers, on va lire la ville, qui va lire le pays...
    idem l'avantage est qu'une fois chargé, on a tout.

    la 3eme :
    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
    class Pays
    {
      int pays_id
      String pays_nom
    }
    class Ville
    {
     int ville_id
     String ville_nom
     int id_paysParent
    }
    class quartier :
    {
     int quartier_id
     String quartier_nom
     int id_villeParent
    }
    Cette représentation ne lit rien en cascade car les objets ne contiennent pas d'objet en attribut mais que des "id", mais à charque fois qu'on a besoin d'un objet en relation avec celui sur lequel on travaille, on est obligé de le charger.
    Pour moi, cela ressemble moins à de "l'objet".

    Quelle est donc la norme en terme de codage?
    Et en cas de solution 1 ou 2, comment savoir à quel moment s’arrêter de lire les voisins?

    Merci d'avance.
    Johann

  2. #2
    Membre expérimenté Avatar de Ivelios
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2008
    Messages
    1 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 031
    Points : 1 540
    Points
    1 540
    Par défaut
    Bonjour,

    Tout dépend de ton utilisation au final.
    L'implémentation la plus complète consistera a posséder les enfants et le parent. Un mélange de la 1er et de la 2ème solutions proposées. En faisant attention à ce que les enfants contenu dans un parent ont comme parent ce même parent. ( c.a.d France : Paris, Lyon, Lille, ... | Lille parent : France | Lyon parent : Mexique !ERROR | ,... )
    La 3ème solution n'est pas funky du tout .

    Après comme dit plus haut tout dépend de ton utilisation final, si tu pouvez nous en dire plus? A savoir que les requêtes en BDD sont plus que rapide ^^. Select * FROM Quartier WHEN quartier_id_villeParent==526 prendra 0.03sec à vu de nez.
    Il était une fois [...] Et ils vécurent heureux et eurent beaucoup d'enfants!

  3. #3
    Membre chevronné
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Points : 1 984
    Points
    1 984
    Par défaut
    Ca sent la mauvais architecture ca. Au demarrage d'une application, il ne faut pas charger toute la BDD en mémoire. Si tu fais ca, quand tu testeras, ca marchera avec 5 enregistrements. Puis quand l'application aura un peu vécu, avec 10000-100000 enregistrements, le demarrage prendra 15 minutes jusqu'à une exception de saturation mémoire.

    Bref, l'usage, c'est de stocker tout ca dans une base de données (sqlite, H2, ...) puis de ne lire que ce dont on a besoin. C'est beaucoup plus rapide et consomme beaucoup moins de mémoire...

  4. #4
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Je dirais qu'il n'y a pas de norme, ça dépend des cas...

    Pour ma part, j'évite le cas 1 dans la majorité des applications, à moins d'avoir un lien fonctionnel fort entre "l'en-tête" et les "lignes"...
    Par exemple, dans le cas d'une facture, c'est tout à fait justifié, on fait les opérations sur la facture qui par cascade persiste les lignes.

    Tu peux également jouer sur le lazy-loading pour éviter de charger tout... enfin, avec certaines technos (jpa, hibernate,...)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Bon, déjà une remarque, à part de ta demande.

    Pourquoi tu fait préfixer le nom du champ par le nom de la table. On vois bien que le champs est dedans, c'est inutilement verbeux dans le cas présent selon moi (dans certains cas c'est jsutifié pour éviter la confusion). Je prendrais plutot ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Table Pays :
    - champ pays_id
    - champ nom
     
    Table Ville : 
    - champ ville_id
    - champ nom
    - champ pays_id (provenant de A)
     
    Table quartier :
    - champ quartier_id
    - champ nom
    - champ ville_id (provenant de B)
    Je ne met les préfixes que sur les id, car ça reste pratique pour lire les requêtes de jointure, mais pas indispensable.


    Ensuite, pour les 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
    class Pays
    {
      int id
      String nom
      List<ville> villes
    }
    class Ville
    {
     int id
     String nom
     List<quartier> quartiers
    }
    class quartier :
    {
     int id
     String nom
    }
    Idem pour les autres classe.


    Pour le reste, je suis d'accord avec les autres interventions: ça dépend de ton cas d'utilisation, des technos que tu utilise. Un gestion bi-directionnelle parent <-> enfant, en général, je prend ça sous hibernate car c'est facile à gérer, avec le lazy-loading on ne charge pas tout, et ça donne plein de liberté dans l'utilisation par la suite de la classe. Si une ville a besoins de connaitre son pays, il te faut un champ pays dans la ville. Si un pays a besoin de connaitre ses villes, il te faut la liste de ville dans le pays.

  6. #6
    Nouveau membre du Club
    Inscrit en
    Août 2011
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Août 2011
    Messages : 109
    Points : 32
    Points
    32
    Par défaut
    tchize_, pour répondre à ta question, les noms sont préfixés en base de données, mais c'est vrai qu'en réalité dans les classes, je ne préfixe pas les champs.
    Le préfixage est fait en base pour qu'un select * fournisse bien les bons noms de champs lors des jointures (si les deux tables ont les mêmes noms de champs)


    Pour l'instant, il n'y a pas d'utilisation d'hibernate, mais nous gérons les DAO "manuellement".
    Je me posais la question car j'ai remarqué que certaines personnes ne mettaient que des id dans les classes.

    Cela avait pour effet, en cas d'affichage d'une liste de ville, de lire à chaque ligne le pays correspondant.
    Donc dans le cas de longues listes, on peut se retrouver à faire beaucoup de requetes, alors qu'en une seule, on aurait pu récupérer l'ensemble des données.

    ------

    Pour info, je suis en train de regarder comment hibernate fonctionne avec Eclipse et le plugin jboss "hibernate tools".
    Je remarque que le plugin génère l'objet ainsi que l'objetHome.
    Si je dois rajouter des methodes (exemple findAll), je suppose qu'il faut les mettre dans "objetHome", mais si je regénère le code, mon code personnel va être écrasé, non?)


    Cdt

  7. #7
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Personellement, sauf en étape initiale, je n'aime pas générer automatiquement le code, pour les raisons que tu mentionne.

    Hibernate est une solution, il est a noter qu'il en existe aussi d'autres, peut être plus légère mais moins complètes, comme mybatis

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par johannsan Voir le message
    Le préfixage est fait en base pour qu'un select * fournisse bien les bons noms de champs lors des jointures (si les deux tables ont les mêmes noms de champs)
    Il serait plus judicieux d'utiliser des alias dans les requêtes, ça va de toute façon bien plus loin que des champs préfixés...
    Comme par exemple une liaison d'une table sur elle même (on suppose que la table personne à une colonne pereUid qui référence une personne)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select a.uid, a.nom, b.nom from personne a join personne b on a.pereUid = b.uid
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Nouveau membre du Club
    Inscrit en
    Août 2011
    Messages
    109
    Détails du profil
    Informations forums :
    Inscription : Août 2011
    Messages : 109
    Points : 32
    Points
    32
    Par défaut
    OButterlin, très bon exemple pour ne pas utiliser les champs prefixés.

Discussions similaires

  1. Comment sous-traiter la construction des objets
    Par Pierrot92320 dans le forum Interfaces Graphiques
    Réponses: 10
    Dernier message: 17/06/2009, 11h49
  2. Objet, attribut et fonction de debugage
    Par Djobird dans le forum Langage
    Réponses: 4
    Dernier message: 26/03/2009, 13h31
  3. Réponses: 4
    Dernier message: 11/04/2007, 14h26
  4. Réponses: 29
    Dernier message: 17/07/2006, 01h33

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