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

Dotnet Discussion :

Génération de code, architecture 3 tiers et databinding avancé


Sujet :

Dotnet

  1. #1
    Expert éminent
    Avatar de neo.51
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    2 663
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 663
    Points : 6 418
    Points
    6 418
    Par défaut Génération de code, architecture 3 tiers et databinding avancé
    Bonjour,

    Voilà, maintenant que j'appréhende assez bien les possibilitées du framework .NET 2.0. Je développe des applis qui sont à 80% des applis dites de gestion et je souhaiterais concevoir mes projets de la manière suivante :

    -Une couche d'accés aux données générée avec un générateur de code.
    -Une couche métier que je code en fonction des spécifs.
    -Une couche présentation en utilisant au maximum le databinding (avec mes objets en datasource).

    Je n'ai pas besoin d'une forte indépendance des couches mais la séparation en 3 couches me permettra de mieux maintenir mon code et de réutiliser mes couches data/métier dans un autre projet.

    Le problème que je rencontre actuellement, c'est que tous les générateurs de code que j'ai trouvé gènèrent un code mal adapté aux nouveautées de .NET 2.0 à savoir :
    -Les générics.
    -La possibilitée d'avoir des objets comme source de donnés.

    Sur ce deuxième point, un problème récurent est qu'on ne peut pas ni filtrer ni trier des bindingSources ayant un objet comme source de données. Que ce soit un généric ou une liste typé faite par un générateur on se retrouve avec une BindingSource "bridé" ce qui est assez pénalisant quand on veut un interface un minimum riche (pouvoir trier par colonne et faire des filtres c'est quand même les bases).

    Alors biensur rien ne m'oblige à utiliser une BindingSource ... certe, mais il faut quand même avouer que la conception d'interfaces graphiques et le code que ça engendre derrière pour faire quelques vues maitre/détail avec 2-3 liaisons est bien plus rapide et éfficace avec une bonne BindingSource.

    Le temps de développement de la partie UI est forcément allongé si on utilise pas le DataBinding à fond, plus les risques d'érreurs de code (forcément plus on code plus on a de chance de faire des érreurs).

    La modèle DataSet/DataAdapter me plait de moins en moins, trés rigide, trés opaque, qui peu le plus peut le moins mais le dataset me semble souvent être une grosse uzine à gaz dont je n'utilise que 10% des méthodes . En plus j'ai souvent plus de 50 Tables en base de donnée, imaginnez un dataset de 50 Tables !!! ingérable ...

    En gros j'ai l'impression d'avoir le choix :
    -Soit une DAL "propre" que je génère avec un générateur de code mais derrière une compléxité supplémentaire pour coder la partie UI.
    -Soit une DAL basée sur des Dataset avec difficultée de séparer la couche métier/data mais une UI plus facile à concevoir.

    Et vous comment faites vous ? Quels outils utilisez vous ?

  2. #2
    Expert éminent
    Avatar de neguib
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 627
    Détails du profil
    Informations personnelles :
    Âge : 63
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 627
    Points : 7 879
    Points
    7 879
    Par défaut
    Citation Envoyé par neo.51
    ...Le problème que je rencontre actuellement, c'est que tous les générateurs de code que j'ai trouvé gènèrent un code mal adapté aux nouveautées de .NET 2.0 à savoir :
    -Les générics.
    -La possibilitée d'avoir des objets comme source de donnés.

    Sur ce deuxième point, un problème récurent est qu'on ne peut pas ni filtrer ni trier des bindingSources ayant un objet comme source de données. Que ce soit un généric ou une liste typé faite par un générateur on se retrouve avec une BindingSource "bridé" ce qui est assez pénalisant quand on veut un interface un minimum riche (pouvoir trier par colonne et faire des filtres c'est quand même les bases).
    Disons que çà necessite une étape supplémentaire pour effectuer la transformation en un BindingList qui lui gèrera le tri et la recherche
    Pour le bien de ceux qui vous lisent, ayez à coeur le respect du forum et de ses règles

  3. #3
    Expert éminent
    Avatar de neo.51
    Profil pro
    Inscrit en
    Avril 2002
    Messages
    2 663
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : Avril 2002
    Messages : 2 663
    Points : 6 418
    Points
    6 418
    Par défaut
    Par défaut une bindingList ne peut pas être triée et encore moins filtrée.

    Pour le tri y a moyen de l'implémenter, le Search aussi, mais le filtrage ...

    Enfin je voulais aussi élargir le débat sur votre manière de procéder

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    122
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 122
    Points : 124
    Points
    124
    Par défaut
    Je me suis retrouvé confronté au même problème.

    La "solution" que j'ai trouvée consistait à passer par des SQLDataSource. C'est ces objets qui étaient chargés d'appeler les procédures stockées.
    Du coup, le modèle 3 tiers que j'avais mis en place a été cassé.
    Mais j'ai pas très bien saisi le fonctionnement de ces types d'objets, alors si qqun a des infos, je suis à l'écoute, comme Neo51!!

  5. #5
    Membre expérimenté
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Points : 1 505
    Points
    1 505
    Par défaut
    J'ai découvert le développement en couches il y a à peine un mois (à l'origine je viens d'Access) et depuis deux semaines j'étudie la question du mapping Objet Relationnel.

    Mes recherches (pour l'instant) m'ont amené à tester la solution originale proposée par Mistu Furuta de chez MS.


    L'idée est de stocker les données persistentes dans un Dataset.

    L'alimentation et la sauvegarde des données du Dataset (la partie SQL) est isolée dans une couche dédiée.

    De l'autre côté, on a une couche d'objets métiers qui vont offrir des "Vues" des données du Dataset.
    Une "vue", c'est à dire que les données ne sont pas stockées dans les objets. Les propriétés persistentes de l'objet pointent directement sur les données du Dataset (DataTable / DataRow).

    Côté IU c'est sur ces objets métier qu'on va se binder.


    Pour profiter de tous les avantages du BindingSource, il faut que les Objets métier implémentent les bonnes interfaces.

    Concrêtement on a les Classes de collection d'objet qui vont implémenter IBindingList, IBindingListView, etc., afin de profiter de toutes les fonctionnalités de filtrage et tri avancées.

    Et les classes d'objet "simple", qui vont éventuellement implémenter IEditableObject, afin de gérer le versionning, etc.

    Comment implémenter ces interfaces ? Rien de plus simple :

    - pour les classes de collection, on stocke un Dataview en tant que donnée membre Private et on fait un simple "chainage" des propriétés et méthodes du Dataview qui correspondent aux propriétés et méthodes des interfaces.

    - pour les autre objets, on fait la même chose, mais avec un DataRowView au lieu du DataView. Et on fait également un chaînage des propriétés persistantes...
    En fait, le DatarowView est une vue du DataRow (qui est le seul à contenir les données), tout comme les DataView sont des vues des DataTable. notre objet métier ici est lui-même une "vue" du DatarowView, mais une vue que l'on peut modeler soi-même : par exemple on peut masquer des colonnes, en mettre en ReadOnly, etc.


    Exemple d'implémentation d'interface par "chainage" pour un objet collection :

    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
        Public Class Clients
     
            Implements System.Collections.IEnumerable
            Implements System.Collections.ICollection
            Implements System.Collections.IList
            Implements System.ComponentModel.IBindingList
            Implements System.ComponentModel.IBindingListView
     
            Private WithEvents m_DataView As DataView
     
            Public Overloads Sub ApplySort(ByVal sorts As System.ComponentModel.ListSortDescriptionCollection) Implements System.ComponentModel.IBindingListView.ApplySort
                DirectCast(Me.m_DataView, System.ComponentModel.IBindingListView).ApplySort(sorts)
            End Sub
     
            Public Property Filter() As String Implements System.ComponentModel.IBindingListView.Filter
                Get
                    Return DirectCast(Me.m_DataView, System.ComponentModel.IBindingListView).Filter
                End Get
                Set(ByVal value As String)
                    DirectCast(Me.m_DataView, System.ComponentModel.IBindingListView).Filter = value
                End Set
            End Property
     
            Public Sub RemoveFilter() Implements System.ComponentModel.IBindingListView.RemoveFilter
                DirectCast(Me.m_DataView, System.ComponentModel.IBindingListView).RemoveFilter()
            End Sub
     
    Etc.
     
    End Class
    Bien entendu il ne s'agit pas de faire un chaînage 100 % identique dans nos objets collection, sinon ils ne seraient rien d'autre que des DataView ...
    En fait, il ne faut pas oublier de renvoyer notre objet métier au lieu de renvoyer un simple DataRowView dans :

    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
       Public Class Clients
     
    Private WithEvents m_DataView As DataView
    ...
     
            Default Public Property Item(ByVal index As Integer) As Object Implements System.Collections.IList.Item
                Get
                        Return New Client(m_DataView.Item(index ))
                End Get
                Set(ByVal value As Object)
                       ...
                End Set
            End Property
     
    ...

    Cette solution m'a séduit et j'essaye donc de la mettre en place dans mon application.

    Vous aurez plus d'infos ici : http://www.microsoft.com/france/even...ntID=118769669
    (\ _ /)
    (='.'=)
    (")-(")

  6. #6
    Membre éclairé Avatar de zeavan
    Architect
    Inscrit en
    Avril 2003
    Messages
    590
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : Autre

    Informations professionnelles :
    Activité : Architect

    Informations forums :
    Inscription : Avril 2003
    Messages : 590
    Points : 774
    Points
    774
    Par défaut
    perso j'utilise enterprise library 2.0 de microsoft+ datawindow 2.0 de sysbase et je creer mon prore model data.

    l'association des 2 me satisfait assez pour m'aider a differencier les differentes couches.

    sinon il y a codesmith avec netears qui supporte les generics mais je crois que c'est encore en beta.

  7. #7
    Membre expérimenté
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Points : 1 505
    Points
    1 505
    Par défaut
    Après un peu plus d'un mois de recherche, je reconnais qu'effectivement l'une des questions les plus épineuses en terme génération de code / architecture / DataBinding est celle du filtrage dynamique des données métiers.
    Néo, tu as parfaitement décrit la situation, que ce soit dans ce thread ou là sur ton blog.

    D'ailleurs, si quelqu'un a testé le BindingListView, son retour sur le sujet m'intéresse !


    Concernant l'utilisation des DataSet ou pas, je ne suis pas tout à fait de ton avis, Néo :
    Citation Envoyé par Neo
    La modèle DataSet/DataAdapter me plait de moins en moins, trés rigide, trés opaque, qui peu le plus peut le moins mais le dataset me semble souvent être une grosse uzine à gaz dont je n'utilise que 10% des méthodes . En plus j'ai souvent plus de 50 Tables en base de donnée, imaginnez un dataset de 50 Tables !!! ingérable ...
    Donc je vais reprendre tes arguments plus ceux que j'ai souvent entendu ici ou ailleurs sur la question.

    Tout d'abord, concernant la complexité du modèle ("plus de 50 Tables", etc.), je ne pense pas qu'on puisse utiliser cet argument contre le DataSet.
    En effet, soit la complexité du schéma est nécessaire pour la présentation des données à l'utilisateur et leur traitement. Et dans ce cas, même en mode connecté, la couche métier sera obligée de reproduire cette complexité.
    Soit, la complexité du schéma de la base de données source dépasse ce qui est nécessaire au niveau des couches métier/GUI, et là rien n'oblige à calquer le schéma du DataSet "métier" sur celui de la base.

    Concernant l'argument de la quantité des données en cache, la réponse est simple : le dataset n'impose pas la rapatriement systématique de toutes les données source, mais seulement de celles dont l'utilisateur va avoir besoin.

    Concernant l'argument suivant lequel le DataSet pollue le développement en couche. Je trouve que c'est faux.
    Mettons les choses au clair tout de suite : dans la couche métier, on oublie les DataSet fortement typés générés par l'assistant.
    Car l'idée même du couple DataTable/TableAdapter dans une même classe est une violation du principe de séparation des couches.
    Par contre, utiliser dans la couche métier un DataSet non typé (ou plus exactement sans DataAdapter), reflétant le modèle des objets métiers, en soi, ça me parait plutôt intéressant dans la mesure où les classes DataTable, DataView, DataRow, etc implémentent toutes les fonctionnalités dont on a besoin pour afficher et éditer des données dans la couche GUI, et ce facilement puisque 100% compatible avec le DataBinding.

    S'il fallait utiliser des DataSet typés générés par l'assistant, ce serait plutôt dans la couche d'accès aux données. On peut très bien imaginer une telle classe dont le rôle est d'aller chercher des données et de les fusionner ensuite (méthode merge) avec les Datatable du Dataset métier. Cette architecture respecte le principe des couches. Bien entendu rien n'impose l'utilisation d'un DataSet typé et de TableAdapter dans la DAL. On peut aller chercher les données n'importe où et n'importe comment, l'objectif étant simplement de remplier le DataSet de la couche métier.

    Dans un modèle à 3 couches, on pourrait avoir les choses comme ceci :
    • un assembly pour la couche GUI
    • un assembly pour la couche Métier
    • un assembly pour la couche d'accès aux données

    L'assembly GUI référence les deux autres. En effet, il faut connaître d'un côté les objets métier si on veut se "binder" dessus, ce binding servant à naviguer dans les données et les modifier... Et de l'autre côté, il faut connaître les réponses qu'on a à sa disposition en matière de sélection et de sauvegarde des données. Par exemple, "je veux me connecter sur une base Access, et compléter avec tel fichier XML ..., puis je veux sauvegarder telles données dans SQL Server ...". Ca, c'est le travail de la couche d'accès au données que fournir des classes pour aller chercher des données et les sauvegarder. Mais ces classes sont commandées généralement par la couche GUI puisque c'est l'utilisateur qui commande.
    L'assembly Métier ne référence aucun des autres. Il est totalement indépendant.
    L'assembly d'accès aux données référence uniquement l'assembly métier. Forcément, puisqu'il va devoir remplir le DataSet métier et en sauvegarder les modifications, il faut qu'il connaisse le type de cet objet.

    Voilà une architecture simple en couche qui peut avoir recourt aux DataSet. Sans DataAdapter dans la couche métier. Avec (si on le souhaite), dans la DAL. Je précise ici que les dataSet de la DAL n'ont pas à reproduire obligatoirement le shéma du Dataset de la couche métier. Le mappage des tables peut être personnalisé, pourvu qu'il soit encapsulé dans la DAL.

    Autre argument contre les Dataset : ce sont des usines à gaz opaques dont je n'utilise que 10% des fonctionnalités. Là je reconnais les classes ADO.NET, ça ne s'invente pas. Moi même après seulement quelque mois d'étude, je ne peux pas tout maîtriser. Mais il est clair qu'elles encapsulent de façon générique tout ce dont on peut avoir besoin en matière d'édition des données, et à mon avis pas beaucoup plus.

    On a besoin :
    • de gérer les transactions d'édition des données des objets métiers ? DataRow implémente IEditableObject.
    • de gérer les suppression / mise à jour en cascade des clés ? On a les DataRelation.
    • On veut calculer des champs automatiquement ? Les DataColumn ont une propriété Expression.
    • On veut filtrer, trier, rechercher ? DataView implémente implémente IBindingList pour le tri à une colonne et la recherche et IBindingListView pour le tri multicolonne et le filtrage.
    • On veut répercuter les modifications de données faites par l'utilisateur ? DataSet centralise les DataTable et on travaille sur des DataView qui n'ont qu'à cibler les mêmes instances de DataTable.
    • On veut afficher partout dans l'interface utilisateur les modifications ? Les fonctionnalités de notifications sont également implémentées, notament par l'événement ListChanged.
    • On veut faire la même choses à propos des informations d'erreur de saisie, non respect des règles métier ? DataRow et DataColumn permettent de définir des textes de description d'erreur et IDataErrorProvider est implémenté.
    • Au niveau de la DAL les classes DataAdapter et DataReader sont super utiles, surtout si on peut les faire générer par un assistant.


    Là, je me demande bien ce que font de plus les Dataset et que nous n'aurions pas à réimplémenter nous-mêmes si nous voulions que nos classes métiers soient compatibles avec le DataBinding avancé.
    Perso, il y a quelque chose que je pense ne pas utiliser dans les DataSet, c'est les contraintes aux niveaux des DataColumns. Qu'ils s'agisse de détecter les doublons ou de contrôler les tailles des types : on peut effectivement vouloir regrouper ce genre de contrôles dans nos classes métiers.

    Mais je me demande si, souvent, quant on critique le côté "usine à gaz opaque" des dataset, on ne fait pas un procès hors sujet aux DataSet Typé générés par l'assistant et qui veulent effectivement encapsuler la gestion des Nulls, intégrer comme ça des fonctionnalités qui au premier abord paraissent superflues ou qu'on aimerait regrouper dans nos objets métiers typés ...


    Passons au dernier argument contre les Dataset : les DataSet ne sont pas "objet" (entendre par là qu'ils ne sont pas typés comme doivent l'être de vrais objets métier). Ca ça pourrait bien être l'argument qui tue.
    Perso, j'étudie encore la question et c'est pourquoi ce débat m'intéresse...

    J'ai expliqué dans mon précédent message que j'étudiais une solution de classes métiers qui utiliseraient au maximum des classes ADO.NET, en travaillant un max sur le concept de "vues".
    Ainsi je pense à un DataSet central dans mon modèle métier, sur lequel seraient basées des DataView qui elles-mêmes seraient intégrées à mes classes. Et mes classes peuvent par ailleurs implémenter ITypedList et ICustomTypeDescriptor pour contrôler la vue offerte aux client de Binding.

    A ce niveau, je rencontre deux difficultées :
    - le filtrage
    - la génération de code

    (c'est quand même là que je vois que Néo est un vrai pro car ça fait bien longtemps qu'il a mis en avant ces points là ).

    Comment faire pour factoriser les fonctionnalités de filtrage ? Il me semble que le principal souci si on se base sur un Dataview sous-jacent, c'est éventuellement la non correspondance entre les noms réels des colonnes et les alias qu'on peut redéfinir au niveau des clients du bonding.
    La possibilité (et donc la prise en charge) d'un tel renommage est quasi inévitable si on veut concurrencer les partisans de classes 100% créées et très typées.

    Cependant la tâche n'est pas la plus complexe (enfin j'espère), d'autant plus que même avec des classes qui n'ont pas recours au Dataset et ses classes connexes, la question de la contruction des critères de filtre se pose aussi.
    La différence notable avec le modèle "connecté", c'est peut-être que les classes prenant en charge le filtrage peuvent être crées une fois et servir partout. Tandis que dans un modèle local le filtrage doit être implémenté à deux niveaux :
    1. Tout d'abord au moment du rapatriement des données, les classes gérant ce filtrage se trouvent alors au niveau de la couche GUI et/ou de la DAL, mais pas dans la couche métier. A noter qu'à ce niveau si les données sont peu nombreuses, leur filtrage n'est pas indispensable : on peut tout rapatrier directement en local.
    2. Ensuite, il faut que la couche métier si elle veut vraiment être un système de traitement des données indépendant implémente l'interface IBindingListView, implémentation d'un filtrage qui n'a rien à voir avec la précédente et représente donc un nouveau travail. D'où l'importance de la question de la facilité de ce travail, voire de la disponibilité de classes ou d'outils capable de l'effectuer. En effet, si on veut se simplifier la vie en profitant du DataBinding avancé, encore faut-il que les conditions de compatibilité (avec la Databinding) ne soient pas insurmontables en terme de coût de développement.

    Je disais que la chose devait être possible raisonnablement ... Encore qu'il faudrait que j'arrive à prouver mes propos par des exemples plus concrets (mais pour l'instant je suis plus dans la recherche que dans le développement d'une solution définitive, donc faudra attendre un peu ). Disons qu'en se servant de la classes DataView à l'intérieur de classes personnalisées, le filtrage ne doit pas posser de réel problème autre qu'un éventuel mappage des noms réels / alias de colonnes.
    Par contre la question du filtrage d'une collection d'objet dont les données proviendraient de plusieurs DataTable ma parait autrement plus épineuse, qu'ils s'agisse de faire une jonction (par exemple afficher une colonne issue d'une table parente ou enfant) ou une union.

    Mais vue la taille de mon post, je ne me sens pas de développer ce point maintenant. Et puis faut garder un peu de suspens ...

    Pour résumer, j'espère avoir apporter quelque arguments en faveur de la (re)considération des DataSet (sans DataAdapter) dans la couche métier et de leur utilité (avec DataAdapter) dans la DAL.

    Mouarf ! Je pense que j'ai fait chuter l'audience de dvp avec ce post, y a p'tet même eu des morts.
    (\ _ /)
    (='.'=)
    (")-(")

  8. #8
    Rédacteur
    Avatar de The_badger_man
    Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2005
    Messages
    2 745
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 745
    Points : 8 538
    Points
    8 538
    Par défaut
    Citation Envoyé par FRED.G
    Mouarf ! Je pense que j'ai fait chuter l'audience de dvp avec ce post, y a p'tet même eu des morts.
    Je te le fais pas dire.... sinon post interressant.

    Concernant quelque chose qui n'est pas encore sorti mais qui va faire parler de lui, que pensez-vous, par rapport à ce qui a été dit, de ADO.NET Entity Framework (si toute fois vous y avez jeté un coup d'oeil) ?

    Pour ceux qui ne vois pas de quoi je veux parler : http://channel9.msdn.com/ShowPost.aspx?PostID=233540
    Les règles du forum
    Le trio magique : FAQ + Cours + fonction rechercher
    Mes articles
    Pas de questions par messages privés svp

    Software is never finished, only abandoned.

  9. #9
    Membre expérimenté
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Points : 1 505
    Points
    1 505
    Par défaut
    Pour ma part je viens plutôt de jeter un coup d'oeil au framework 3.
    Non j'ai visité ton lien avant mais là quand je vois les nouvelles classes ADO.NET, je suis carrément optimiste sur la possibilité de bosser faciliment avec l'espace de nom System.Data sans me poser mille et une questions !

    On a par exemple des classes comme BindingListCollectionView, et côté UI, il y a le nouveau contrôle ListView qu'on peut binder.

    Ca fait super envie ! J'en taguerais presque ce topic "Résolu" !




    EDIT: ce ne sont pas de nouvelles classes ADO.NET, elles appartiennent à d'autres espace de nom (Windows.Data, etc.). Mais peu importe... En tout cas les ObersvableCollection(Of) et autres CollectionViewSource, ça me plait beaucoup...
    (\ _ /)
    (='.'=)
    (")-(")

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 101
    Points : 82
    Points
    82
    Par défaut
    Débat intéressant - mais qui dépasse de loin mon expérience récente et uniquement théorique de la plateforme .NET...

    Je suis entrain d'élaborer un projet que nous allons développer sur la plateforme .NET, et mes choix de conceptions s'avèrent déjà épineux... Concernant mon architecture logique, j'ai pris le parti d'avoir une seule couche 'métier/accés au données' (et tant pis pour la dépendance au SGBD !).

    J'ai l'impression que ça simplifie quelque peu mes choix de conceptions... mais ça reste encore floue.
    Si j'ai bien compris, le choix le plus judicieux dans ma couche 'métier/accés aux données' devrait être des DataSets fortement typés générés automatiquement...

    Soit...

    Qu'en pensez-vous ?

  11. #11
    Membre expérimenté
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Points : 1 505
    Points
    1 505
    Par défaut
    Salut le niçois (je suis pas loin )!

    Pour ce qui concerne mes propos, j'espère avoir suffisament argumenté mon point de vue, mais toujours est-il qu'il ne faut pas les prendre pour paroles d'évangile car je ne suis pas un expert en DotNet, loin s'en faut. J'ai découvert cette techno y a 6 mois à peine, et je ne suis pas dévelopeur professionnel, que les choses soient bien claires.

    Ceci dit j'ai beaucoup travaillé sur la question et je m'efforce de tester dans mes applis ce que j'apprends ça et là dans les tutos. Mais cela ne vaut pas une expérience de professionnel sur le terrain.

    En tout état de cause, si mon avis t'intéresse, je te répondrais que oui, il est possible de mêler ta couche Data et métier en utilisant un DataSet fortement typé si tu t'y retrouves (je veux dire si le binding direct sur des entités ADO.NET te convient).

    Mais pour ma part, je privilégie une architecture où je crée mes propres classes métier (bien que celles-ci pointent sur un DataSet qui stocke les données persistentes, mais ça c'est un autre débat...).
    Je trouve que c'est plus pratique d'avoir ses propres classes, notamment à cause des questions d'héritage car les modèles objets et relationnels ne représentent pas toujours les hiérarchies d'héritage de la même manière.
    Ainsi, là où dans un modèle objet tu vas avoir deux classes (avec la seconde qui hérite de la première) et vraisemblablement une collection pour chaque, dans un modèle relationnel, tu n'auras qu'une seule classe (en ADO.NET ce sera un DataRow) dont les instances seront regroupées dans une seule collection (DataTable).
    Au moment du binding (ou de tout autre utilisation) de tes objets calqués sur un modèle relationnel, tu feras la différence entre parents et enfants non pas en te basant sur le type de l'objet (car même typé, ce sera toujours le même DataRow) mais sur ses données (dans une table "contacts", tu distingueras par exemple les prospects et les clients par le stockage d'un booléen).
    Si cela ne te pose aucun problème, tout va bien. Mais travailler sur des entités réellement objet peut avoir des avantages. Par exemple, ces entités n'exposent que les méthodes et propriétés qui leur sont propres. Par exemple dans une entité "prospect", exit le flag booléen de tout à l'heure, ou les champs spécifiques aux données d'un client. Idem pour les méthodes. Plus besoin de les alourdir avec des paramètres permettant de distinguer si on traite un "client" ou un "prospect" lorsque cette distincition est nécessaire. Car la distinction est faite par le type même de l'entité, c'est sa raison d'être.
    D'une façon générale, utiliser de l'objet plutôt que du générique est plus intuitif, limite les erreurs dans les paramètres, etc. C'est plus précis. Or dans la plupart des cas le modèle relationnel ne correspond pas à l'équivalent objet, et par conséquent, générer des objets en se calquant strictement sur un modèle relationnel revient à avoir des objets "génériques" dans le sens où n'étant pas typés, c'est à dire n'étant pas spécialisés et identifiés dans leur forme par un type, il faut indentifier leur vraie nature (leur spécificité) en faisant des tests sur leur contenu (leur données). C'est ce que sont les DataSet (les objets ADO.NET), même fortement typés car ce "typage" est calqué sur une source relationnelle.

    Or du point de vue de la manipulation des données, c'est le modèle objet qui est le plus pratique par rapport au modèle relationnel. Car le modèle relationnel est là pour optimiser le stockage et le requêtage d'infos. Tandis que manipuler des entités objets plus proches de la nature est plus intuitif, notamment pour l'utilisateur. Par conséquent la conversion modèle relationnel / modèle objet se fait inéluctablement. Ne serait-ce que par l'utilisateur lui-même qui manipule "un contrat", "une date de cloture" et non un Datarow ou un DataColumn...

    Donc si tu te bindes sur des objets ADO.NET, tu repousses la conversion (l'identification de la spécificité d'une entité) dans la couche UI. Cette conversion, tu la fait, comme je l'ai dit plus haut, en fonction des données contenues dans ton DataRow. Par exemple si tu veux afficher uniquement une liste de Prospects, tu vas filter de façon spécifique ta DataTable de Contacts, en utilisant le booléen prévu à cet effet s'il existe... Ou encore, si tu es lié sur la DataTable Contacts et veut savoir si tel DataRowView est un client ou un prospect, il va falloir que tu testes les données du DataRowview, etc.

    Il y a des cas où ce travail d'interprétation est assez léger à faire. Soit parce que le modèle relationnel est proche du modèle objet, soit parce que le modèle relationnel n'est pas complexe (peu de tables...).

    Mais dans les cas plus sérieux, on se rend vite comptre que faire ce travail d'interprétation dans la couche UI est lourd et polluant. Ben oui, ça multiplie vite les lignes de codes et on s'y perd...

    C'est là qu'il convient, je crois, de travailler sur un modèle objet, et de localiser le travail de mapping entre ces objets et une source relationnelle dans une couche DATA. Là tu te retrouves avec une couche UI "toute propre". Et en outre, tu factorises ton travail de conversion entre les modèles : tu fais le mapping une seule fois dans la couche Data. Ensuite, partout dans la couche UI, tu n'as plus ce travail à faitre puisque tu te bindes et bosses sur des objets correctement typés.

    Tu vois le truc ? Donc il n'y a pas d'interdit. La solution d'utiliser seulement des classes ADO.NET est viable mais possède ses limites qu'ils faut ne pas avoir à franchir. Si tu sais que tu n'auras pas à les franchir, fonce ! Sinon, crées une architecture plus complexe, mais plus rationnelle.

    Pour ma part, j'envisage d'utiliser les classes ADO.NET comme conteneurs centralisant les données persistentes et notifiant mes objets métiers de leur changement. Ca fait une couche intermédiaire entre la couche métier et la couche Data puisque mes objets métier pointent sur mes objets ADO.NET, et que ma couche Data remplit et sauvegardes les données de ces objets ADO.NET. A ce niveau en fait, je considère que les objets ADO.NET (en fait un Dataset) font partie de ma couche métier.

    Bon je m'arrête là, je pense avoir répondu à ta question.
    (\ _ /)
    (='.'=)
    (")-(")

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 101
    Points : 82
    Points
    82
    Par défaut
    Merci pour ta réponse chaleureuse et complète

    Je prendrais le temps d'analyser et de répondre aprés mes vacances (plus que quelques heures avant le bonheur !), mais les points que tu avances me semble d'ores et déjà intéressant à la première lecture.

    Juste un point qui m'a chatouillé : j'ai cru comprendre que ta couche DataAccess était dépendante de ta couche Métier (apparement elle lui notifie les mofications de données). Cela signifie t-il que ta couche Métier est 'en-dessous' de ta couche DataAccess ? (et que tu n'as donc pas de dépendance de ta couche Métier vers ta couche DataAccess) ou bien a tu fais le choix de ne pas respecter la contraintes de dépendances descendante entre couches ?


    Encore merci,
    Bonnes fêtes et à l'année prochaîne.

  13. #13
    Membre expérimenté
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Points : 1 505
    Points
    1 505
    Par défaut
    Salut,

    je décris comment je conçois le modèle en couche ici quand je discute l'argument suivant lequel "le DataSet pollue le développement en couche".

    La différence avec mon dernier post, c'est que je n'approfondis pas la différence de nature entre les classes ADO.NET (le Dataset) qui reflètent un modèle relationnel et les classes métiers qui reflètent un modèle objet. Les problèmes découlant de cette différence étant pratiques (difficulté du Binding notamment) mais relatifs (à chacun de juger si dans son projet utiliser des DataView/DataRowView automatiquement générés est plus simple que créer et utiliser des classes métier spécialisées).

    Dans mon dernier post, je fais mention de ma tentative d'utilisation d'un Dataset dans ma couche métier pour stocker les données persistantes et notifier les changements à mes classes métier spécialisées. Je le dis clairement ici, ce dataset fait quand même partie de la couche métier.

    Par contre, les classes qui vont le remplir et sauver ses donénes (des DataAdapter, ou même d'autres DataSet qu'on va "merger") sont, elles, cantonnées dans la couche DATA.
    Quant aux "notifications"... Je parle simplement de notifications au niveau de ma couche métier. Pour reprendre l'exemple de la table Contacts qui contient des Client et des Prospects : imaginons que dans ma couche métier j'ai un Dataset (donc plutôt calqué sur un modèle relationnel). Si par ailleurs, je conçois mes classes métier comme des objets spécialisés offrant des "vues" des données de mon Dataset, alors j'aurais une classe (et sa collection) "Contact" et ses classes dérivées "Client" et "Prospect"... Ces classes là pointeront sur le même DataTable ("Contacs") et ses DataRow... Comme les classes ADO.NET supportent les notifications de changement (INotifyPropertyChanged, etc.), je pourrai facilement répercuter ses notifactions à toutes les instances des classes métier "Contact", "Client" et "Prospect" aussitôt que l'une d'elle est modifiée... Les classes ADO.NET servent ici de "conteneurs" de données et font le lien entre les instances de mes classes métier.
    (\ _ /)
    (='.'=)
    (")-(")

  14. #14
    Membre expérimenté
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Points : 1 505
    Points
    1 505
    Par défaut
    Citation Envoyé par The_badger_man
    Concernant quelque chose qui n'est pas encore sorti mais qui va faire parler de lui, que pensez-vous, par rapport à ce qui a été dit, de ADO.NET Entity Framework (si toute fois vous y avez jeté un coup d'oeil) ?

    Pour ceux qui ne vois pas de quoi je veux parler : http://channel9.msdn.com/ShowPost.aspx?PostID=233540
    Je n'ai pas encore exploré à fond cette techno naissante, mais après visionnage de la vidéo, je pense qu'il sont en plein dans le sujet !
    Ils partent du principe que dans nos applis clientes, ce sont des objets qu'on veut manipuler. Tandis que la source des données est légitimement organisée selon une logique relationnelle. Donc l'idée est de fournir un framework qui encapsule le code nécessaire pour réaliser ce mapping.

    C'est très prometteur... Personnellement j'aimerais savoir si leur framework impose de taper directement sur la source de donnée (de cette façon, le modèle relationnel serait "virtuel", exprimé simplement au travers des infos de mapping), ou si on peut instancier ce modèle (dans un dataset ?) de manière à pouvoir par exemple profiter des notifications de changements au niveau du cache de données dans l'appli cliente...

    J'attends de voir comment ils règlent aussi la question des "colonnes calculées" (avec agréation, etc.) qui sont indispensables pour typer correctement certains objets métier et faciliter leur filtrage au niveau de l'appli cliente...
    (\ _ /)
    (='.'=)
    (")-(")

  15. #15
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 273
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 273
    Points : 2 202
    Points
    2 202
    Par défaut
    Et bien j'espére que ca ne sera pas perçu comme de la pub, mais la solution de ta question est exactement ce que je gére les composants data enterprise de component one.

    A savoir :
    Un dataref local client pouvant pointer sur un composant tier d'accès aux données, qui lui même peut être lié à des classes métier.

    Ca ne fait pas tout, c'est très propriétaire, mais j'ai envie de dire aussi que tous les composants se dérivent.

    Je suis assez sidéré aujourd'hui de voir que beaucoup de développeurs prennent les composants "as it", en drag and drop, alors que la régle d'or d'un composant quel qu'il soit, et que l'évolutivité et la maintenance souhaiterai que tous prennent le simple temps de créer un nouveau composant dérivé.

    Et là tu gagneras du temps.

  16. #16
    Membre expérimenté
    Avatar de FRED.G
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    1 032
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 1 032
    Points : 1 505
    Points
    1 505
    Par défaut
    Je ne vois pas là de la pub mal placée, c'est toujours intéressant d'avoir un retour utilisateur sur une techno donnée, propriétaire ou non.

    Tu peux même écrire un article sur les composants data enterprise, nous aurons la possibilité de le publier s'il est bien fait.

    Sinon pour ma part, je préfère viser des outils libres ou MS, c'est pourquoi j'étudie l'Entity Framework en ce moment.
    (\ _ /)
    (='.'=)
    (")-(")

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 101
    Points : 82
    Points
    82
    Par défaut
    Bonjour,

    Rentré de vacances depuis peu , je viens de prendre un peu de temps pour continuer à explorer les mystères de l'architecture 3 tier en DotNet et du mapping objet/relationnel. Fred.g, Tes réponses m'ont eclairé, et je viens de lire quelques articles concernant ObjectSpaces de Microsoft (notamment ici).

    L'avez vous utilisé ? Quel sont vos retours ?

    Chaleureusement.

  18. #18
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    101
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Septembre 2004
    Messages : 101
    Points : 82
    Points
    82
    Par défaut
    Je viens de voir que Microsoft ne donne pas suite à ObjectSpaces et que son successeur s'appellera DLinq ou (Linq ?...)(que ferait-on sans dvp ?) et qu'il est prévu avec la version 3.0 de C# (lien msdn)...

    Ca me parait un peu la jungle au niveau des 'ORM' DotNet...
    Je reviens donc à une des problèmatiques posé par neo.51 au début du thread :

    Citation Envoyé par neo.51
    Et vous comment faites vous ? Quels outils utilisez vous ?

  19. #19
    Membre actif
    Homme Profil pro
    Directeur des systèmes d'information
    Inscrit en
    Avril 2006
    Messages
    141
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Directeur des systèmes d'information
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2006
    Messages : 141
    Points : 210
    Points
    210
    Par défaut db2c
    Bonjour,
    perso j'ai developper mon propre générateur de code, sa me permet a souhait de rajouter tout ce que je veux, si il y en as que sa interesse www.database2code.com. il comporte probablement des inconvenient par rapport a des outils pro, mais a surtout pas mal d'avantage (comme la mise a jour de structure de base de donnée, et un vrai mapping, ce qui permet de passer d'une base Access, SQL Server ou MySql en qq seconde).

    Autrement je vais regarder un peu tout les outils que vous avez cité ici, je pense que je peu m'inspirer de certaine de ces fonctionnalitées.

    merci,
    DSI et développeur du logiciel Lulidb
    http://www.lulidb.com - outils de gestion de base de données orienté développer.

  20. #20
    Nouveau membre du Club
    Profil pro
    Chef projet
    Inscrit en
    Novembre 2002
    Messages
    20
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Chef projet

    Informations forums :
    Inscription : Novembre 2002
    Messages : 20
    Points : 35
    Points
    35
    Par défaut Perso
    moi j'utilise le générateur de code mygeneration avec le modéle objet "DOODADS", c'est assez performant et on peut filtrer les données dans le modéle objet.

    http://www.mygenerationsoftware.com/portal/default.aspx

Discussions similaires

  1. XML Databinding et génération de code c++
    Par ArnaudCasella dans le forum XML/XSL et SOAP
    Réponses: 0
    Dernier message: 11/04/2011, 12h14
  2. Génération de code & bpm4struts
    Par k4eve dans le forum BPM
    Réponses: 3
    Dernier message: 08/03/2007, 15h12
  3. [UML] génération de code avec omondo.uml
    Par RENAULT dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 31/10/2003, 13h14
  4. [Design Patterns] Architecture 3 tiers
    Par HPJ dans le forum Design Patterns
    Réponses: 1
    Dernier message: 29/07/2003, 11h49
  5. [Lomboz] Génération de code pour EJB
    Par paikan dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 09/07/2003, 14h28

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