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 :

Heritage ou classe partielle [Débat]


Sujet :

C#

  1. #1
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut Heritage ou classe partielle
    Bonjour

    J'aimerais soumettre un petit débat sur la pertinence ou l'avantage d'utiliser une classe partielle ou un héritage dans le cas suivant :

    Pour nos projet, nous avons créé en générateur de classe d'acces aux tables de Database SQL

    Ce génerateur cree la classe automatiquement a partir du schema d'une table
    Les methodes Insert, Delete, update avec le code SQL nécessaire sont créées

    Dans beaucoup de cas il est nécessaire d'y ajouter certaines propriétés ou methodes propre au business et aux contraites spécifique

    Le choix est donc d'ecrire ces methode dans un autre fichier que celui auto-généré

    Nous avons deux option

    1- L'heritage
    2- La classe partielle

    Auriez-vous des argument qui aideraient a orienter la décision ver un de ces choix ?

    Merci de votre aide

  2. #2
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Euh...

    Avec CommandBuilder, on peut déjà générer dynamiquement les commandes CRUD pour les tables.

    Donc pourquoi ne pas :
    1/ Utiliser un vrai code "propre", et non des fichiers de class générés par milliers, totalement impossible à maintenir ?
    2/ Vous n'aurez alors plus qu'à étendre une unique classe.

  3. #3
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Sinon, dans votre cas, vu le bordel, et le fait que vous ne maîtrisez pas le code généré, l'héritage tout comme les classes partielles me semble totalement suicidaire.

    Imaginez que votre classe actuelle contienne les méthodes suivantes :
    - Insert()
    - Update()
    - Delete()
    - Select()

    Actuellement, Delete() ne prends en paramètre qu'un int, qui correspond à la PK.

    Pour un projet spécifique, vous voulez pouvoir faire du mass delete, et vous ajoutez une méthode Delete(int[] arrayId)

    Plus tard, vous faites évoluer votre générateur de classes, et vous vous dites que Delete(int[] arrayId) c'est vachement bien, et que vous l'incluez dans votre générateur.

    Vlan, vous allez vous repalucher des milliers de classes que vous aviez dérivé ou étendu, pour neutraliser du code... qui ne fait peut-être pas la même chose ! (genre y'en a un qui est transactionnel et pas l'autre, ou qui fait un cascade et pas l'autre)

    Des jours de boulot perdu moi je vous dis :o

    (tout ceci pour dire que j'aime pas les générateurs de code)

  4. #4
    Membre confirmé
    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
    Points : 460
    Points
    460
    Par défaut
    Bonjour,

    Les deux ont leur (des)avantages
    Classes partielles coupler au méthodes partielles
    + Surcoût d'utilisation nul, toute en laissant le choix au développeur ou non d’implémenter la méthode
    - Il faut penser à définir la signature de toute éventuelle méthode utile
    - "Partiel" c'est en interne d'une assembly
    Heritage
    + Non limiter à une assembly
    - Peut causer de léger sur-cout
    - Le développeur peut casser l’héritage final

    Du coup comme ça à chaud, j'opterais pour un choix hybride, générer des classes partielles en définissant des méthodes partielles. Ces classes n'étant pas "sealed" ce qui permet une flexibilité


    PS :
    Citation Envoyé par olibara
    Dans beaucoup de cas il est nécessaire d'y ajouter certaines propriétés ou méthodes propre au business et aux contraintes spécifique
    Si tu penses a des contraintes de pré-validation et post-validation, les methodes partielles semble parfaite pour ça.

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Conceptuellement, je pense qu'une classe partielle est plus adaptée ; l'héritage n'aurait pas beaucoup de sens dans ce contexte. Par exemple, si ton outil te génère une classe Product pour la table Product, ça n'a pas vraiment de sens de créer une classe dérivée de Product plutôt que d'utiliser directement Product (sauf si tu penses créer plusieurs classes dérivées de Product bien sûr)

    D'ailleurs la plupart des outils qui génèrent des classes utilisent le système des classes partielles : DataSet, Linq to SQL, Entity Framework, web services...

    Citation Envoyé par StringBuilder Voir le message
    Avec CommandBuilder, on peut déjà générer dynamiquement les commandes CRUD pour les tables.
    Un CommandBuilder, c'est très bien s'il utilise des DataSets... mais tout le monde ne veut pas utiliser ça. Aujourd'hui la tendance est plutôt à la création de classes pour les entités de la DB.

    Citation Envoyé par StringBuilder Voir le message
    1/ Utiliser un vrai code "propre", et non des fichiers de class générés par milliers, totalement impossible à maintenir ?
    Je vois pas le rapport... en quoi utiliser des classes générées empêche d'avoir un code propre ? Et pour ce qui est de la maintenance, il n'y en a pas : on ne touche pas un fichier généré...

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Sinon, dans votre cas, vu le bordel, et le fait que vous ne maîtrisez pas le code généré, l'héritage tout comme les classes partielles me semble totalement suicidaire.
    Sur quoi te bases tu pour dire que c'est le bordel ? Tu n'as pas vu le code, que je sache...
    Et où as-tu vu qu'il ne maîtrisait pas le code généré ? C'est son propre générateur, il y met ce qu'il veut...

    Citation Envoyé par StringBuilder Voir le message
    (tout ceci pour dire que j'aime pas les générateurs de code)
    Oui, j'avais cru comprendre...
    D'un autre côté, tu suggérais l'utilisation de CommandBuilder, qui n'est autre qu'un... générateur de code SQL

  7. #7
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Un CommandBuilder, c'est très bien s'il utilise des DataSets... mais tout le monde ne veut pas utiliser ça. Aujourd'hui la tendance est plutôt à la création de classes pour les entités de la DB.
    Pas du tout, CommandBuilder travaille avec les objets classiques SqlCommand. Ce n'est en rien incompatible avec l'utilisation d'une classe dédiée à l'entité.

    Citation Envoyé par tomlev Voir le message
    Je vois pas le rapport... en quoi utiliser des classes générées empêche d'avoir un code propre ? Et pour ce qui est de la maintenance, il n'y en a pas : on ne touche pas un fichier généré...
    Parce que le jour où on a une modification au niveau de la base de données (modèle, drivers, SGBD, nouvel algo de pooling, etc.) on va devoir re-générer les classes. Et comme je l'indiquais, rien n'empêche qu'on se retrouve avec du code incompatible ou redondant avec le code qu'on a étendu la première fois qu'on avait généré les classes.

    Je trouve donc plus logique (c'est du moins ce que j'ai toujours fait) de créer une unique classe permettant l'accès à une table passée en paramètre du constructeur, dans l'objet entité (et ainsi, on sépare vraiment accès à la base de données, générique quel que soit l'objet demandé, de la couche métier, ou chaque entité a des méthodes et règles différentes).

    Bon, après, j'ai clairement pas la science infuse : au contraire, je pense que j'ai un niveau très médiocre en dev (en général) et donc en C# par la même occasion. Mais je trouve que le code généré, c'est avant tout une erreur de conception : c'est qu'on n'a pas su rendre générique un code plus simple à maintenir.

  8. #8
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 170
    Points : 7 422
    Points
    7 422
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Sur quoi te bases tu pour dire que c'est le bordel ? Tu n'as pas vu le code, que je sache...
    Et où as-tu vu qu'il ne maîtrisait pas le code généré ? C'est son propre générateur, il y met ce qu'il veut...
    Le mot "bordel" est un peu abusif, je l'admet.
    Mais le code généré n'étant pas modifiable, la maintenance est immédiatement bien plus complexe.
    => Si on a écrit un générateur de code, c'est qu'on désire l'utiliser sur plusieurs projets (ou alors on se prends vraiment la tête pour pas grand chose). Le problème c'est qu'ensuite, quand on a besoin de re-générer le code 2 ans après, soit on à une version du générateur différente par projet, et on doit réécrire 25 fois la même chose à chaque évolution, soit on a le même, et on risque rapidement de se retrouver avec du code généré qui n'est pas compatible avec tel ou tel projet, surtout si on surcharge/étends par la suite les classes.
    D'où l'intérêt, je trouve, d'utiliser une classe générique, qu'on n'a pas besoin d'hériter ou étendre : soit c'est lié à l'accès à la base, et on fait évoluer la classe, soit c'est lié à l'entité, et on modifie seulement le code de l'entité, sans touché à cette classe d'accès aux données.

    Citation Envoyé par tomlev Voir le message
    Oui, j'avais cru comprendre...
    D'un autre côté, tu suggérais l'utilisation de CommandBuilder, qui n'est autre qu'un... générateur de code SQL
    Je l'admet, mais dans une moindre mesure tout de même

  9. #9
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 184
    Points : 4 501
    Points
    4 501
    Par défaut
    Mais je trouve que le code généré, c'est avant tout une erreur de conception : c'est qu'on n'a pas su rendre générique un code plus simple à maintenir.
    Euh
    Je sais pas comment tu peux rendre générique un Insert/Update/Delete et créer des classes à partir de table ou l'inverse si c'est pas de la génération de code

    Et je me demande pourquoi il existant tant d'outil de mapping si tu n'as pas besoin de générateur

    et pour répondre à la question : classe partiel

  10. #10
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 184
    Points : 4 501
    Points
    4 501
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Le mot "bordel" est un peu abusif, je l'admet.
    Mais le code généré n'étant pas modifiable, la maintenance est immédiatement bien plus complexe.
    => Si on a écrit un générateur de code, c'est qu'on désire l'utiliser sur plusieurs projets (ou alors on se prends vraiment la tête pour pas grand chose). Le problème c'est qu'ensuite, quand on a besoin de re-générer le code 2 ans après, soit on à une version du générateur différente par projet, et on doit réécrire 25 fois la même chose à chaque évolution, soit on a le même, et on risque rapidement de se retrouver avec du code généré qui n'est pas compatible avec tel ou tel projet, surtout si on surcharge/étends par la suite les classes.
    D'où l'intérêt, je trouve, d'utiliser une classe générique, qu'on n'a pas besoin d'hériter ou étendre : soit c'est lié à l'accès à la base, et on fait évoluer la classe, soit c'est lié à l'entité, et on modifie seulement le code de l'entité, sans touché à cette classe d'accès aux données.


    Je l'admet, mais dans une moindre mesure tout de même
    Perso quand tu dois modéliser 50 tables, creer les objets, la dal, l'idal, la couche buisness, la couche serveur, la couche client, je suis bien content d'avoir un générateur de code spécifique pour ce projet ;p

    Et même si je n'utilise plus mon générateur dans 2 ans, ca m'aurait fait gagné du temps pendant la phase de conception du projet

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 753
    Points
    39 753
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    Pas du tout, CommandBuilder travaille avec les objets classiques SqlCommand. Ce n'est en rien incompatible avec l'utilisation d'une classe dédiée à l'entité.
    je sais pas si on parle de la même chose alors... je pensais que tu parlais de DbCommandBuilder, qui s'utilise avec un DbDataAdapter pour appliquer à une DB les modifs dans un DataSet. Mais tu avais peut-être en tête un autre truc que je ne connais pas...

  12. #12
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Merci a tous pour cet intéressant echange d'idée

    Le débat n'était évidemment pas l'intéret d'utiliser un générateur mais de l'intéret de la classe partielle vis a vis de l'heritage en vue separer le code auto-généré du code spécifique ajouté a la main.

    Je pense effectivement que la classe partielle sera la plus simple et pertinente dans la plupart des cas

    Et ca n'empeche en rien l'heritage s'il apparait utile dans certains cas

    Pour ce qui est du générateur je peux assurer les incrédules que les quelques heures que nous avons passé a le créer on déja fait passer des centaines d'heures en tant sans parler des bugs liés aux erreurs d'ecriture et la facilité liée a la normalisation du code
    En plus dans le cadre évoqué de manipulation DB que ca élimine completement la tentation de vite coller un petit code SQL par ci-par la
    Et celui qui pretends que les générateurs c'est bidon et qu'il peut creer une classe genérique d'acces a une DB a peut etre aussi trouvé la solution au mouvement perpetuel !

    Merci a tous

Discussions similaires

  1. Réponses: 6
    Dernier message: 28/12/2006, 18h22
  2. Réponses: 1
    Dernier message: 18/08/2006, 10h34
  3. Heritage de classe avec classes internes
    Par Regis.C dans le forum Langage
    Réponses: 11
    Dernier message: 27/04/2005, 12h19
  4. [FLASH MX2004] Heritage de classe
    Par bolo dans le forum Flash
    Réponses: 9
    Dernier message: 05/12/2004, 13h08

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