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

C# Discussion :

C# et SQL: POO et Database - concepts


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juillet 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 75
    Par défaut C# et SQL: POO et Database - concepts
    Bonjour,

    je viens d'avoir une conversation avec mon supérieur et j'aimerais votre avis sur le concept POO...

    Je possède 2 tables:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    TABLE PERSONNES(
    ID,
    NOM,
    COUNTRY_ID)
     
    TABLE COUNTRIES(
    ID,
    NOM)
    Selon moi, je créé donc la classe "Country.cs" de cette façon

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public class Country
    public int id {get;set;)
    public string nom{get;set;}
    et la classe "Personne.cs" de cette manière

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public class Personne
    public int id {get;set;)
    public string nom{get;set;}
    public Country country{get;set;}
    et après avoir initialisé tout ça (Je vous épargne le code), idéalement, je déclare un pays ma personne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Country country = new Country ("USA");
    Personne pers = new Personne("Jean", country);
    et je suis tout content d'avoir mon objet et de pouvoir obtenir le pays de ma personne comme ceci...


    Maintenant, mon supérieur m'a signifié que la "manière" de créer les classes n'était pas correct, car une classe doit représenter la base de données -->

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public class Personne
    public int id {get;set;)
    public string nom{get;set;}
    public int countryId{get;set;}
    et que ensuite, nous pouvions rechercher le nom du pays en faisant une requête du style:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Country country = SELECT * FROM COUNTRIES WHERE ID = pers.countryId;
    ce qui selon moi est une aberration que de faire "matcher à l'identique" les champs de la base de données avec les classes objets...

    Ai-je perdu tous mes concepts ou... autre chose ???

    Merci de vos lumières...

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 194
    Par défaut
    Moi je ferai les deux.

    Tu n'auras pas toujours besoin du pays même si ici tu n'as que 2 champs dans la table pays imagine si tu en as des des dizaines...

    sinon tu peux aussi faire Personne, PersonneDetaille qui elle contriandra Country

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Avril 2011
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2011
    Messages : 51
    Par défaut
    pour quoi tu utilise pas Entity DATA Model il permet de générer ces class automatiquement en plus tu peux faire tes requête directement en linq
    regarde ici
    http://msdn.microsoft.com/fr-fr/libr.../ee382825.aspx

  4. #4
    Membre confirmé
    Inscrit en
    Juillet 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 75
    Par défaut
    Citation Envoyé par BenoitM Voir le message
    Moi je ferai les deux.

    Tu n'auras pas toujours besoin du pays même si ici tu n'as que 2 champs dans la table pays imagine si tu en as des des dizaines...

    sinon tu peux aussi faire Personne, PersonneDetaille qui elle contriandra Country
    C'est vrai que tu n'auras pas forcément besoin du pays à chaque fois, et oui bien sûr, la table "pays" ne se résume pas seulement à 2 champs.

    Mais je pars du principe que si on peut le moins, on peut le plus, c'est à dire que je préfère avoir des objets exaustifs, que des objets "minimalistes".

    L'approche que je trouve choquant, c'est de vouloir faire en sorte que les classes correspondent aux tables SQL, alors que pour moi, si on veut travailler avec des Personnes, on sait qu'un objet "personne" existe et on s'en fiche de comment est structuré la BD derrière, tant qu'on obtient les infos qu'on veut... Je ne sais pas pour vous, mais pour moi c'est l'approche objet qui veut ça...

    pour quoi tu utilise pas Entity DATA Model il permet de générer ces class automatiquement en plus tu peux faire tes requête directement en linq
    regarde ici
    http://msdn.microsoft.com/fr-fr/libr.../ee382825.aspx
    Merci mais je voulais plus un avis de la façon de travailler qu'une "technique" pour le réaliser. J'ai posé un exemple assez simple qui représentait mon problème en vue d'avoir une idée générale si je suis dans "les rails" du juste ou non...

  5. #5
    Membre actif
    Homme Profil pro
    Architecte C#
    Inscrit en
    Février 2003
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte C#

    Informations forums :
    Inscription : Février 2003
    Messages : 78
    Par défaut
    Bonjour,

    A mon avis, tu es bien dans les rails, en revanche, ton supérieur aussi a raison, si il pense que tu chargera systématiquement l'objet Country avec l'objet Personne.

    je rejoins Michou2000 en pensant que les ORMs sont la solution. Cependant, sois conscient qu'ils n'enlèvent pas la complexité, ils la transforment juste. Au lieu de te demander "quelle requête faire ?"/ "avec quelle jointure?", tu vas te poser des questions comme "qui est maitre de la relation avec entre la personne et la country ?" / "comment faire en sorte que mon modèle s'articule bien ?" / "est ce cohérent d'avoir une relation N/N ici ?" "dois je charger l'objet et ses enfants ou juste l'objet ?"


    Cette couche de complexité va te guider dans le développement :
    Si tu rencontre des points de frictions, c'est qu'il y a quelque chose à revoir en amont.
    En revanche, coté chargement et optimisations, tu aura de bien meilleurs points sur lesquels travailler.

    Bonne journée.

  6. #6
    Membre confirmé
    Inscrit en
    Juillet 2007
    Messages
    75
    Détails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 75
    Par défaut
    Citation Envoyé par Vimaire Voir le message
    Bonjour,

    A mon avis, tu es bien dans les rails, en revanche, ton supérieur aussi a raison, si il pense que tu chargera systématiquement l'objet Country avec l'objet Personne.
    Au niveau performance, je peux comprendre, mais même, ce n'est pas un argument assez fort pour moi pour "éviter" de le coder...

    au pire, tu définis plusieurs constructeurs avec les différentes possibilités, d'avoir le pays ou non.

    Mais selon moi, si pour apprendre comment fonctionne mon programme je dois IMPERATIVEMENT toujours regarder les champs de la BD, alors que je pourrais simplement regarder comment sont organisées les différentes classes représentant la BD, quelquechose quelque part a mal tourné :-)

    Bien sûr, si on veut faire des modifs, on va aller dans la BD, etc...

    mais moi je pars du principe que des objets vitaux d'un programme (tjs les mêmes utilisés) doivent contenir le max de properties possible...

    L'objet est là pour modéliser au maximum...

  7. #7
    Membre actif
    Homme Profil pro
    Architecte C#
    Inscrit en
    Février 2003
    Messages
    78
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte C#

    Informations forums :
    Inscription : Février 2003
    Messages : 78
    Par défaut
    @staticx :

    Le problème, c'est qu'il te faudra le coder, ca te fera une charge de travail non négligeable, même si tu pars sur du YAGNI (partir systématiquement au plus simple).

    après, que tu fasses par constructeurs, par réflection ou par mapping, ca n'empeche pas que dans certains cas, tu devras charger l'objet et dans d'autres non. ce sont des cas qu'il te faudra gérer, qu'il te faudra coder et qui ne font pas partie du métier demandé.

    Les orms existant (EntityFramework & NHibernate, pour ne citer que les plus connus) te permettent ce comportement nativement, voire te permettent de charger l'objet de niveau 1 et ne chargent l'objet de niveau 2 que si tu essaie d'y accéder, c'est une solution qui me parait satisfaire les 2 parties, mais sois conscient qu'il y a une courbe d'apprentissage non négligeable. En revanche, contrairement à la solution "maison", l'avantage ici sera qu'une fois formé à la techno, tu pourra la réappliquer sur d'autres projets sans avoir à te reformer (alors qu'avec la techno "maison", il faudra probablement en recoder une très grosse partie).

    l'autre avantage des ORMS, c'est que tu modifie l'objet et tu demande à l'orm de répercuter les modifications, c'est lui qui s'en occupe.

    Citation Envoyé par staticx Voir le message
    mais moi je pars du principe que des objets vitaux d'un programme (tjs les mêmes utilisés) doivent contenir le max de properties possible...
    Ca dépends, j'ai connu des cas de figure ou les objets étaient blindés de propriétés qui n'étaient là "qu'au cas où" et qui, du coup n'étaient la plupart du temps pas utilisées.

    Si dans un objet, tu as des propriétés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class MaClasse
    {
        public long IdToto{get;set;}
        public long Toto_Id{get;set;}
        public long Unique_Id{get;set;}
        public long Identifiant_Toto{get;set;}
    }
    ca risque d'etre confus....
    (ce n'est qu'un exemple, mais avec des reprises d'existants, c'est malheureusement possible)

    Citation Envoyé par staticx Voir le message
    L'objet est là pour modéliser au maximum...
    Là, je te suis à 200% j'ai la chance justement d'utiliser des orms, notamment NHibernate depuis plusieurs projets, "oublier" le sql tout en conservant des points d'optimisations et pouvoir parcourir toute la grappe d'objets de façon cohérente, c'est du bonheur , par contre, la courbe d'apprentissage est bien là.

    Si tu veux en savoir plus, je te renvoie vers l'excellent NHibernate In Action qui, bien que ciblant une ancienne version, présente très bien l'outil & ses contraintes.

  8. #8
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2011
    Messages
    269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 269
    Par défaut
    Bonjour,

    Pour moi "orienté objet" implique ta classe "Personne" ai une propriété public "Country". En se sens l'orienté objet est différent du model relationnel SQL. Ton objet ne doit pas reflété ton model relationnel, il doit reflété le model de donnés qui a été traduit en MERISE.

    Maintenant ça ne veux pas dire que cette propriété doit être initialisé avec les instance de "Personne".

    En gros tu peux présenté une face public qui est de l'orienté objet, avec en interne une face privé qui correspond au SQL.

    En gros quelques chose comme ca
    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
    public class Personne
    {
       private int countryID;
       private Country country;
     
       public int id {get;set;)
       public string nom{get;set;}
       public Country Country
    {
      get 
      {
        if (contry == null)
          country  = InitializeCountry(countryID);
        return country;
      }
      set
      {
        country = value;
        countryID = country.id;
      }
    }
     
     private Country InitializeCountry(int countryID)
     {
        //Requêter la base pour récupérer l'instance de Country
     }
    }
    Le problème avec cette méthode c'est le risque des multiple instance de Country pour une même valeur.
    Autre problème, celui de la persistance, ou la codé? Surtout si on veux respecter les principes SOLID.

    Globalement, un design existe pour résoudre ton problème, repository pattern
    Tu aura des objets pure, et le repository lié à chaque type d'objet ce chargera de faire la transition avec le SQL.

Discussions similaires

  1. Réponses: 0
    Dernier message: 20/07/2007, 15h35
  2. [SQL] Conserver le database handler dans l'objet
    Par RGuy_ dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 29/05/2007, 17h05
  3. [POO] Logique de conception POO
    Par nicocolt dans le forum Langage
    Réponses: 11
    Dernier message: 18/04/2007, 17h06
  4. [POO] Méthodologie de conception en langage dynamique
    Par csszzen dans le forum Langage
    Réponses: 5
    Dernier message: 28/03/2007, 19h50
  5. [POO] Problème de conception POO et requêtes sql
    Par redsaint0 dans le forum Langage
    Réponses: 4
    Dernier message: 13/02/2007, 19h59

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