|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 |
|
Membre du Club
![]() |
Bonjour,
Bon je vais commencer par le début. Je développe actuellement un projet ASP.NET assez important en utilisant une conception multi-couches. J'ai décomposé ma conception ainsi :
Voilà, donc en fait on peut lire dans de nombreux bouquins que les objets c'est avant tout un ensemble d'attributs et d'opérations (classique). Mais tout mon problème est déjà là; ma couche controleur manipule mes objets métiers et les objets DAO et réalise en qq sorte une grande partie de la logique applicative + logique métier. Donc du coup mes objets métiers n'ont presque plus besoin d'avoir de méthodes puisque le controleur fait tout (et a donc tendance à devenir imposant) ! Or de nombreux ouvrages préconisent que le controleur ne doit que "déléguer" le soin aux objets métiers d'effectuer ces tâches. Alors vous me direz, dans ce cas tu n'as qu'à déplacer ta logique métier dans les méthodes des objets métier (logique quoi ! Hé bien non ! parce que comme vous l'avez vu, mon controleur manipule aussi des DAO, c'est à dire que j'ai besoin de pouvoir charger certains objets depuis une base de données, en d'autres termes, travailler avec des objets initialisés. Or si je me mets à effectuer cette tâche dans les objets métiers eux même, je ruine ma conception puisque les objets métiers manipuleraient des objets d'accès aux données. Je vais juste prendre un exemple pour éventuellement clarifier un peu : Dans mon projet commercial, j'ai une classe CoefficientIndividuel qui doit prendre en compte de nombreux paramètres distincts. Par exemple le taux d'absence d'un commercial, le fait qu'il soit à temps plein ou non etc .. Or toutes ces données sont dispatchées dans des objets métiers bien distincts et pas forcément toujours directement reliés entre eux (ex : Commercial, Absence, TempsTravail). Or je ne peux pas donner la possibilité de faire réaliser le calcul par ma classe CoefficientIndividuel (mais c'est ce que j'aimerais faire !!), puisqu'il faudrait charger (initialiser) d'abord tous les objets dont j'ai besoin pour travailler avec eux, ce qui n'est pas le rôle de l'objet métier. /* Note pour ego ici : j'ai d'ailleurs tout spécialement du mal à comprendre pourquoi dans ton tutorial sur SPRING on voit une classe Produit qui est lié à un ProduitDAO, ou alors il y a un problème de fond qui m'échappe */ La seule solution serait donc d'initialiser tous les objets dans le controleur puis d'appeller la méthode de l'objet métier en passant en paramètre tous les objets déjà initialisés (mais personnellement je trouve ça très pourri). Voilà si qqn a compris, est-ce qu'il (ou elle) pourrait m'aider à clarifier cette situation ? Merci d'avance |
|
|
00
|
|
|
#2 |
![]() ![]() |
Bon, il y a plusieurs choses :
- Tes contrôleurs, si ce sont les contrôleurs "graphiques", ceux appelés par les "cliques" souris, ces contrôleurs ne doivent pas avoir de logique métier. Il doivent simplement faire le lien entre l'IHM et les objets métiers. - Les objets métier maintenant...il y en a de 2 sortes. Les objets que l'on pourrait nommer "entité" et les objets que l'on pourrait nommer contrôleurs métier. Les objets entité peuvent avoir des méthodes dès lors qu'elles ne manipulent et ne dépendent que des informations directement connues par l'entité en question (attributs, relations). Les objets contrôleurs métier possèdent eux des méthodes métier qui sont "trans objets métier" - Les contrôleurs graphique appellent les objets contrôleur métier. Ils peuvent éventuellement se charger de l'adaptation des objets métier pour présenter un modèle d'objets adpaté à l'IHM. Tu peux aussi intercaler une couche supplémentaire entre les 2 types de contrôleurs. On parle alors de couche application dont l'objectif est d'adapter les objets métier aux besoins spécifiques d'une application/IHM. C'est dans ce genre de couche que l'on retrouve la fabrication d'objet dits DTO ou VO. - Pour les entités qui connaissent les DAO, pas de soucis. C'est souvent comme cela que ça se passe quand on n'utilise pas de framework de persistence et que l'on veut pouvoir naviguer de manière transparente dans un modèle objet.
__________________
http://ego.developpez.com |
|
|
00
|
|
|
#3 | ||||||
|
Membre du Club
![]() |
Merci pour ta réponse.
Tu peux me dire si on parle le même langage : Citation:
Citation:
Citation:
Citation:
Citation:
Citation:
Alors là j'avoue que j'ai du mal à avaler ceci. C'est contraire à la vision que je me fais du découplage. Une couche métier qui contient une référence vers la couche données ? glurps ... d'ailleurs j'avais trouvé une conversation sur le même forum qui semblait affirmer le contraire : http://www.developpez.net/forums/arc...p/t-70661.html Sur le 4eme post, l'auteur dit notamment : "ton objet métier ne doit pas avoir de dépendances avec aucune couche (pas de lien avec le dao comme tu l'as fait)". Personnellement c'est aussi la vision que j'ai et qui (sauf erreur de ma part) est décrite dans nombre d'ouvrages. D'où mon incompréhension Peux-tu m'éclairer ? |
||||||
|
|
00
|
|
|
#4 |
![]() ![]() |
On est donc d'accord.
Pour le lien entre entité métier et DAO, je m'explique : - Le lien entre Entité et DAO n'est pas un réel problème dès lors que tu travailles sur la base d'interfaces = les entités connaissent les DAO au travers d'interfaces - Quand tu as par exemple un objet Commande qui a des LigneDeCommande. Tu as une collection de LigneDeCommande au niveau des objets Commande. Si tu veux faire du lazy-loading des LigneDeCommande (chargeement à la demande), tu as plusieurs solutions : 1- Tu utilises un framework de persistance et là tu n'as a priori pas de dépendance avec un DAO puisque le framework prend tout en charge 2- Dans le getLigneDeCommande de Commande tu gères le chargement des objets LigneDeCommande et donc tu as besoin d'un DAO pour déclencher la requête la première fois 3- Tu créés des collections typées qui elles utilisent le DAO et se chargent du chargement. Dans ce cas, la dépendance n'est pas directe mais tu as quand même une dépendance entre ta couche entité métier et ta couche DAO. Tu peux avoir ces situations même sans lazy-loading mais dès lors que cela a du sens que ton entité retourne des objets qu'elle connait. La meilleure solution, en générale et selon moi, est d'utiliser un framework de persistance pour que tout cela soit transparent. Enfin, ce peut être une décision de ta part de ne pas gérer les relations entre objets = ne pas faire de la navigation dans le modèle objet en t'adressant aux objets eux-mêmes mais ne passant toujours par un tier. Dans ce cas, effectivement, les entité métier n'auront pas besoin de DAO. Bref, il n'y a pas une seule solution comme d'habitude, tout est affaire de choix réfléchi en fonction du contexte.
__________________
http://ego.developpez.com |
|
|
00
|
|
|
#5 | |||
|
Membre du Club
![]() |
(Je rappelle que j'utilise NHibernate)
Citation:
J'ai lu a qq part qu'on pouvait aussi utiliser des DTO pour faire le lien entre la couche DAO et la couche métier (en .NET on peut même utiliser un DataSet qui est purement un objet sérializable) Citation:
Néanmoins j'ai l'impression que nous n'avons pas résolu mon problème de départ. Maintenant que, je pense, tu as saisi ma manière de travailler, vois-tu une solution efficace pour gérer ce problème qui était le fait d'avoir quasiment toute la logique métier dans les controleurs de cas d'utilisation, du fait de ne pas pouvoir travailler sur les objets métier eux-même, faute d'objets non initialisés ? Ou alors doit-je inclure cette dépendance supplémentaire : Citation:
Peux-tu également m'orienter vers d'éventuels articles/ouvrages qui appuient ta pensée ? Merci |
|||
|
|
00
|
|
|
#6 | |
![]() ![]() |
Citation:
De toute manière, vu que tu utilises NHibernate, l'histoire des DAO n'a pas énormément d'importance tout au moins par rapport à la connaissance que peuvent ou ne peuvent pas en avoir les entités métier. Pour le cas de tes contrôleurs de cas d'utilisation. En fait, il faut distinguer plusieurs choses : - Les données métier = entités métier = les données de l'approche données-traitements. Ces classes n'ont pas vraiment d'intelligence métier - les classes "contrôleurs métier" = les traitements de l'approche données-traitements. Là il faut y mettre les traitements métier = tes contrôleurs de cas d'utilisation. Cette couche travaille avec les entités métier. - Eventuellement, tu peux ajouter une couche "applicative" au dessus de cela. C'est cette couche qui va enchainer les traitements métier (les opérations de tes contrôleurs de cas je pense) en fonction des besoins de l'IHM et en fonction de ton architecture en terme de tiers physiques. Et c'est elle qui va transformer les entités métier en DTO pour l'IHM Dans le cas où tu créés cette couche "application", c'est probablement elle qui est en fait plutôt une couche "contrôleur de cas d'utilisation". Dans ce cas tes contrôleurs de cas d'utilisation sont plutôt les contrôleurs métier. Résumé : EM = entité métier DAO = Data Access Object CM = contrôleur métier CA = contrôleur applicatif DTO = Data transfer object Les CM manipulent des EM et les DAO les CA utilisent les CM et font les transformations DTO - EM nécessaires (dans les 2 sens)
__________________
http://ego.developpez.com |
|
|
|
00
|
|
|
#7 |
|
Membre du Club
![]() |
Je pense que je comprends mieux.
Donc dis moi si je me trompe : En gros ce qui me manque dans ma conception c'est une couche applicative comme tu dis. Mes controleurs de cas d'utilisations qui effectivement sont très gros à force de détenir toute la logique de l'application + la logique métier je devrais finalement les scinder en objets controleurs métiers, spécialisés. Ce que j'appellais controleurs de cas d'utilisation deviendraient alors des controleurs applicatif, qui manipulent des controleurs métier et renvoient les DTO à l'IHM. La logique métier réside donc entièrement dans ces controleurs métiers mais du coup mes "objets métier" à proprement parler ne contiennent finallement pas grand chose (comme c'est déjà le cas actuellement). Ce ne sont que de simples "réprésentation version objet des tables de la base", avec leurs getters et leurs setters. Si je résume il y a donc comme couches : Présentation : IHM + Code Behind Application : Controleurs de cas d'utilisations Métier : Controleurs Métier + Entités métier Couche d'accès aux données : DAO Mapping ORM C'est à peu près correct là ? Encore une fois si tu as des liens sur le sujet ça serait sympa, parce que je peine à trouver de la doc sérieuse sur le sujet. Merci |
|
|
00
|
|
|
#8 |
![]() ![]() |
pour la doc, je vais voir cela plus tard.
Sinon, tu as tout compris. Maintenant, attention de ne pas empiler les couches sans réfléchir. Dans certains cas, peut être que tes contrôleurs applicatif peuvent taper dans les DAO
__________________
http://ego.developpez.com |
|
|
00
|
|
|
#9 |
|
Membre du Club
![]() |
Si quelqu'un possède des liens sur le sujet qu'il n'hésite pas à m'en faire part.
En tout cas merci pour cette enrichissante discussion |
|
|
00
|
|
|
#10 |
|
Membre habitué
![]() Inscription : avril 2005 Messages : 206 ![]() |
C’est une discussion très intéressante. Je suis à la recherche de bons tutoriaux sur le découpage en couches, et si possibles avec des exemples en c# ou VB.Net, ou Delphi.net ou Delphi.win32. Avez-vous des liens ?
Merci |
|
|
00
|
|
|
#11 |
|
Membre du Club
![]() |
Salut,
Il y a une mine d'informations au niveau des petshop DNG qui sont des exemples de conceptions en couches faites par DNG Dans le menu de gauche du site, tu peux aisément consulter les rubriques : PetShop DNG, SOA, AOP ... Par la même occasion j'ai mis en ligne un schéma pour résumer un peu ce qui a été dit dans cette discussion et que je m'efforce d'appliquer dans mes projets : http://img97.imageshack.us/img97/3013/couchests9.png Donc si quelqu'un pouvait confirmer que je raconte pas trop de conneries ça serait cool ! Bonne lecture. P.S : Merci Nip pour l'info |
|
|
00
|
|
|
#12 |
|
Membre habitué
![]() Inscription : avril 2005 Messages : 206 ![]() |
ok merci pour ces infos.
|
|
|
00
|
|
|
#13 |
|
Membre du Club
![]() |
J'aimerais obtenir une précision sur ce dont nous avons discuté précédemment.
Imaginons que nous mettons en oeuvre la solution décrite. Dans notre solution Les Controleurs de Cas d'utilisations (généraux) accèdent/déleguent à des controleurs métiers plus spécifiques. Or une question peut se poser : Les controleurs Metiers travaillents-ils avec des instances d'objets déjà initialisés par les Controleurs de CU, ce qui revient à dire que les controleurs de CU initialisent/chargent dans un premier temps les objets métiers grâce aux DAO, puis transmettent ensuite ces objets déjà initialisés aux méthodes des controleurs métiers ? Ou bien, a contrario, doit-on passer directement des identifiants et des valeurs scalaires au controleur métier, laissant le soin à celui ci d'initialiser lui même les objets dont il a besoin pour travailler ? Prenons un exemple pour clarifier : Un employé possède certaines absences. Imaginons que l'on veuille enregistrer une nouvelle Absence. Déroulons le scénario : L'utilisateur clique sur le bouton enregister (IHM). Appel de la méthode d'enregistrement d'absence du Controleur de CU en transmettant l'identifiant de l'employé en paramètre 2 solutions :
Attention, cet exemple est simpliste, il n'y a qu'un seul objet à charger. Si on avait beaucoup d'objets qui entrent en jeu, il faudrait envoyer tous les identifiants en paramètre. De même si on veut mettre à jour une absence existante, on aurait le choix entre
Voilà j'aimerais avoir votre avis sur cette question Merci
|
|
|
00
|
|
|
#14 |
|
Membre du Club
![]() Inscription : septembre 2004 Messages : 101 ![]() |
Post intéressant !
Je suis actuellement confronté à des problématiques assez similaires (plateforme DotNet - C# - appli client lourd). Contrairement à ce que j'ai cru comprendre que tu faisais, je partirais plutot sur le fait que ma couche application implémente uniquement des objets métiers (et non DAO) comme structure de création, recherche, mise à jour et suppression. Le but étant de bénéficier au maximum des avantages du modèle objet dans mes applications. Je suis encore en conception, et ton avis m'interesse tout autant J'aimerais également avoir ton avis sur l'outil de mapping ORM que tu utilise (peut-être plutot sur ce post) |
|
|
00
|
|
|
#15 |
![]() ![]() |
Ce que tu appelles contrôleur de UC sont peut être ce que l'on appelle aussi contrôleur applicatif (dans les archi 5-tiers = IHM-Application-Metier-Accès données-Données)
Regardes il y a eu il y a qq temps un thread sur la manipulation de ValueObject et BusinessObject, cela peut t'intéresser. En résumé, les contrôleur applicatifs (tes contrôleur de UC) recoivent des VO, les transforment en BO (ils utilisent donc les DAO) et passent les BO aux contrôleurs métier.
__________________
http://ego.developpez.com |
|
|
00
|
|
|
#16 |
|
Membre du Club
![]() |
Merci ego c'est exactement ça.
Les controleurs UC sont ce que tu appellais au début de ce post les controleurs applicatifs, les VO sont ce que j'appellais les DTO... Donc ça correspond effectivement à ma première solution : les controleurs UC (ou Controleurs Applicatifs) recoivent/envoient des DTO vers/de l'IHM, transforment ceux-ci en objets métiers en les initialisant via les DAO (donc tu réponds bien à ma question), et transmettent ces objets initialisés aux controleurs métiers. Voilà j'espère que ça n'aura pas éclairé que moi Merci ego |
|
|
00
|
|
|
#17 | ||
|
Membre du Club
![]() |
Je réponds ici à Exsilius :
Citation:
De plus je suis curieux de savoir comment tu initialises les associations de tes objets métiers ? Est-ce que tu as une référence vers un gestionnaire dans chacun de tes objets métiers ? N'hésite pas à apporter des précisions ! Citation:
Je n'aurais pas la prétention de dire que c'est le meilleur framework ORM pour l'instant mais en tout cas il est suffisamment complet pour résoudre la majorité des problématiques dans ce domaine. Par contre son apprentissage est long, je l'utilise régulièrement depuis près d'un an et je suis loin d'en maitriser toutes les subtilités. La seule chose que je peux dire à ce sujet, c'est que généralement l'utilisation d'un framework de persistance modifie la façon de concevoir son application. Les objets métiers étant initialisés par le framework lui même, il n'est plus nécessaire d'avoir des références vers des DAO dans les objets métier eux même, il faut donc légèrement revoir la façon de concevoir son application (les puristes me corrigeront si je raconte n'importe quoi) |
||
|
|
00
|
|
|
#18 |
|
Membre habitué
![]() Inscription : avril 2005 Messages : 206 ![]() |
Il y a deux ou trois choses pour lesquelles j’aimerais des précisions…
Les DTO ou VO, entre les contrôleurs graphiques et contrôleurs métiers (contrôleurs de cas d’utilisation), de quoi s’agit-il ? En C#, j’ai utilisé une DataGridView, avec comme datasource une TbinlingList d’objets, par exemples articles. Comment représenter cela avec ce modèle en couches IHM, objets graphiques, contrôleurs, objets métiers et éventuellement DTO/VO ? Ce que la TBindList contient, ce sont des objets métiers, non ? Ets-ce que dans ce cas, on peut dire que l’IHM communique directement avec ces objets métiers ? edit : avez-vous de bons livres à conseiller, en français ou en anglais ? |
|
|
00
|
|
|
#19 | |
|
Membre du Club
![]() |
Les DTO (Data Transfer Object) ou VO (Value Object) sont des objets de transfert de données entre les différents tiers de l'application. Ce sont de simples structures de données (getters, setters) avec des types de bases, et donc facilement sérialisables pour être transportés entre 2 tiers physiques.
En .NET j'irais même jusqu'à dire qu'un DataSet peut jouer le rôle de DTO puisqu'il est facilement sérialisable, ne contient en général que des types de bases et peut facilement être affecté à un DataGrid ou autre. Personnellement pour l'instant je crée mes DTO moi même. Citation:
Ensuite, tout est question du projet. Dans un petit projet on s'en fout un peu, mais pour les gros projets ça peut être quand même intéressant de bien séparer les couches (IHM -> application -> métier) Donc pour répondre plus précisemment à ta question, moi en fait j'utilise un ObjectDataSource en ASP.NET (je sais pas trop comment ça fonctionne en Win32). Quand j'ai besoin d'afficher des données, l'object data source instancie le controleur applicatif et execute la méthode de récupération de données (select). Le controleur applicatif délègue le soin au(x) controleur(s) metier(s) de récupérer différentes données. Une fois que le controleur Applicatif a récupéré tout ce dont il a besoin, il instancie un DTO, remplit ses attributs, et le renvoie le DTO ainsi construit. Ma couche IHM manipule donc toujours des DTO. |
|
|
|
00
|
|
|
#20 | ||||
|
Membre habitué
![]() Inscription : avril 2005 Messages : 206 ![]() |
Citation:
De plus, comment traites-tu les objets qui en contiennent d’autres ? Citation:
Citation:
Citation:
Par exemple, supposons que les règles métiers autorisent un utilisateur à faire certaines actions en fonction de l’état d’un objet. Cet objet, à travers un VO, est présenté à l’utilisateur. L’utilisateur modifie son état grâce à l’IHM. Puis, toujours grâce à l’IHM, il essaie une certaine action. Le contrôleur graphique informe le contrôleur applicatif, qui va vérifier si l’action est autorisée ou pas. Le contrôleur applicatif doit vérifier l’état de l’objet dans le VO, par exemple un dataset. Mais si c’est l’objet métier lui-même qui contient les méthodes de vérification, le contrôleur ne pas appeler ces méthodes, puisque l’objet métier n’est pas vraiment là, c’est juste un objet VO à destination de l’IHM… Je ne sais pas si je suis bien clair. Ce qui me perturbe, c’est qu’il me semble que les objets métiers peuvent contenir des méthodes qui influent sur les possibilités de l’utilisateur, et que je ne vois pas comment ces méthodes sont invoquées quand l’objet métier est sérialisé dans un VO, et que ce VO sert de datasource… |
||||
|
|
00
|
Copyright © 2000-2013 - www.developpez.com