Partager via


Cet article a fait l'objet d'une traduction automatique.

Cutting Edge

Les professionnels de l'et op de données objets de transfert

Dino Esposito

Contenu

Procédures des critères pour BLL
Modèles basés sur un objet pour BLL
La couche de service
Présentation des objets de transfert de données
Autres avantages de DTO
Inconvénients de DTO
Références des entités directement
Le mode intermédiaire
Approche mixte

Presque chaque développeur et architecte sont s'accordent sur le suivant, bien que relativement perdre, définition de la couche business logic (BLL, Business Logic LAYER) d'une application logicielle : la couche BLL est la partie de l'application de logiciel concerne les performances des tâches professionnelles. Code de la couche BLL fonctionne sur les données qui tente d'entités de modèle dans le domaine du problème, factures, les clients, commandes et ainsi de suite. Opérations de la tentative BLL pour modéliser des processus professionnels.

Dans les coulisses de cette définition largement acceptée se situe un nombre de détails de clé qui restent undefined et non spécifiée. Modèles de conception existent pour aider les architectes et concepteurs code transformer définitions lâche dans projets. En général, modèles de conception BLL ont une vue légèrement différente. Modèle des opérations et les données elles souvent servir de point de départ de conception de la couche BLL.

Dans cet article, après un bref actualisateur sur des modèles basés sur les objet procédures et pour organiser la couche BLL, je me concentrerai sur un côté de ce problème, objets de transfert de données, qui si pas efficacement résolus au niveau de l'architecture, peut avoir un profond impact sur le développement du projet.

Procédures des critères pour BLL

Lorsqu'il s'agit de conception de la couche BLL, vous pouvez démarrer à partir des-cas d'utilisation qui ont émergé pendant la phase d'analyse. En règle générale, vous obtenez une méthode pour chaque interaction nécessaire entre l'utilisateur et le système de codage. Chaque interaction constitue une transaction logique qui inclut toutes les étapes d'échéance, de collecte d'entrée pour effectuer la tâche et des accès de base de données à actualiser l'interface utilisateur. Cette approche est appelée le modèle de script de transaction (TS).

Dans Terminal Server, vous concentrer sur les actions requises et n'est pas réellement construire un modèle conceptuel du domaine comme gravitational Centre de l'application.

Pour déplacer des données, vous pouvez utiliser les objets conteneur qui peuvent répondre à. Dans l'espace Microsoft .NET, cela signifie essentiellement l'utilisation de conteneurs de données ADO.NET tels que des DataSets et DataTables. Ces objets sont un type d'objet super-array, avec une recherche, l'indexation et des fonctions de filtrage. En outre, DataSets et DataTables peut être facilement sérialisé dans différents niveaux et même persistant localement dans des scénarios hors connexion.

Le modèle de Terminal Server n'est pas imposer un modèle particulier pour la représentation de données (et n'empêche pas les soit). En règle générale, les opérations sont regroupées sous méthodes statiques dans un ou plusieurs classes de point d'entrée. Vous pouvez également opérations peuvent être implémentées que les commandes dans une approche de modèle de commande. Organisation d'accès aux données est laissée au développeur et entraîne généralement blocs de code ADO.NET.

Le modèle de Terminal Server est relativement simple à configurer ; en même temps, il évidemment n'est pas adaptée qui Eh bien, mesure que la complexité de l'application se développe. Dans l'espace de .NET, un autre modèle obtenu large acceptation au fil des années : le modèle de table module. En bref, le modèle de table module propose une vision centrée sur base de données de la couche BLL. Elle nécessite que vous créez un composant métier pour chaque table de base de données. Appelé la classe de module de la table, le composant métier regroupe les données et le comportement ensemble.

Dans le modèle module table, la couche BLL est divisée en un ensemble de composants à granularité grossière, chacun représentant une table de base de données entière. Est strictement orienté table, le modèle de table module prête à l'aide de comme jeu d'enregistrements de données structures pour transmettre les données dans. Conteneurs de données ADO.NET ou, mieux encore, personnalisée et typée version ADO.NET conteneurs constituent le choix naturel.

La nécessité d'une vue conceptuelle plus le domaine du problème se produit, les modèles BLL qui ont travaillé pendant des années dans l'espace .NET doivent évoluer plus. Les architectes ont tendance à construire un modèle entité/relation qui représente le domaine du problème et observez technologies telles que LINQ-vers-SQL et Entity Framework que les outils concrètes pour vous aider à.

Modèles basés sur un objet pour BLL

Le modèle de table module repose sur les objets, mais il n'est pas vraiment un modèle basé sur les objets pour la logique métier de modélisation. Il possède des objets, mais ils sont objets représentant des tables, pas les objets représentant le domaine du problème.

Dans une conception orientée objet, la logique métier identifie les entités et exprime toutes les interactions requises et autorisées entre les entités. Au final, l'application est considérée comme un ensemble d'objets liés et interfonctionnement. Ensemble d'objets mappage à des entités, ainsi que certains objets spéciaux effectuant des calculs formulaire le modèle de domaine. (Dans Entity Framework, vous exprimer le modèle de domaine en utilisant Entity Data Model [EDM]).

Il existe différents niveaux de complexité dans un modèle de domaine qui propose des modèles différents, généralement le modèle d'enregistrement Active ou le modèle modèle de domaine. Une bonne mesure de cette complexité est l'écart entre le modèle d'entité qu'avoir en tête et le modèle des données relationnelles que vous souhaitez créer pour stocker des données. Un modèle de domaine simple est une dans laquelle vos entités mapper étroitement aux tables dans le modèle de données. Un modèle n'est pas donc simple requiert mappage à charger et enregistrer les objets de domaine dans une base de données relationnelle.

Le modèle d'enregistrement active est une solution idéale lorsque vous avez besoin un modèle de domaine simple ; sinon, lorsqu'il est préférable de concevoir des entités et relations indépendamment des aucune notion de base de données, le modèle modèle de domaine est la solution idéale.

Le modèle d'enregistrement active est similaire à ce que vous obtenez à partir d'un modèle d'objet LINQ à SQL (le modèle defaultgenerated avec le Concepteur d'entités dans Entity Framework Version 1.0). À partir d'une base de données existante, vous créez des objets mappent une ligne dans une table de base de données. L'objet aura une propriété pour chaque colonne de table du même type et avec les mêmes contraintes. La formulation d'origine du modèle d'enregistrement active recommande que chaque objet rend lui-même responsable de sa propre persistance. Cela signifie que chaque classe d'entité doit comprennent des méthodes telles qu'Enregistrer et charger. Entity Framework ni LINQ à SQL cela cependant, comme les deux persistance délégué à une infrastructure intégrée O/RM qui agit comme la couche accès aux données réelles, comme illustré figure 1 .

fig01.gif

Figure 1 architecture en couches A – le PatternUsed de modèle de domaine pour la couche BLL

La couche de service

Dans la figure 1 , vous ne voyez une section logique de la couche BLL appelée «couche service» située entre la couche de présentation et la couche qui prend en charge de persistance. En bref, la couche de service définit une interface pour la couche présentation déclencher des actions système prédéfinie. La couche de service dissocie présentation et de logique métier et représente la façade pour la logique de présentation pour appeler le composant BLL. La couche de service effectue son propre travail regardless of comment la logique métier est organisée en interne.

En tant qu'un développeur .NET, vous êtes tout à fait familiarisé avec les gestionnaires d'événements dans les formulaires Web ou Windows. La méthode Button1_Click canonique appartient à la couche de présentation et exprime le comportement du système après l'utilisateur a cliqué sur un bouton donné. Le comportement du système, plus précisément, le cas d'utilisation vous implémentez, peuvent nécessiter une interaction avec les composants BLL. En règle générale, vous devez instancier le composant BLL et puis le script. Le code nécessaire pour le composant de script peut être aussi simple que l'appel du constructeur et éventuellement une méthode. Plus souvent, cependant, ce code est assez complet avec des branches et devrez peut-être appeler dans plusieurs objets ou attendre une réponse. La plupart des développeurs faire référence à ce code comme logique d'application. Par conséquent, la couche de service est l'endroit de la couche BLL où vous stocker logique d'application, tout en conservant distinct et séparé de logique de domaine. La logique de domaine est n'importe quelle logique vous pliez dans les classes qui représentent des entités de domaine.

Dans la figure 1 , les blocs de modèle service couche et de domaine sont éléments distincts de la couche BLL, bien qu'ils probablement appartiennent à des assemblys différents. La couche de service sait que le modèle de domaine et fait référence l'assembly correspondant. L'assembly de couche de service, au lieu de cela, est référencé à partir de la couche présentation et représente le seul point de contact entre n'importe quelle couche de présentation (qu'il Windows, Web, Silverlight ou mobile) et la couche BLL. la figure 2 montre le graphique des références qui se connectent les différents acteurs. La couche de service est une sorte de médiateur entre la couche de présentation et le reste de la couche BLL. En tant que tel, il conserve les clairement séparées mais faiblement couplés afin qu'ils soient parfaitement en mesure de communiquer. Dans la figure 2 , la couche de présentation ne contenir toute référence à l'assembly de modèle de domaine. C'est un choix conception clé pour les solutions plus superposés.

fig02.gif

La figure 2 graphique des références entre les acteurs de participant

Présentation des objets de transfert de données

Lorsque vous avez une vision basée sur le domaine de l'application, vous ne pouvez pas aider mais étudier sérieusement données objets de transfert. Aucune solution à plusieurs couches basée sur LINQ to SQL ou Entity Framework n'est l'abri de ce problème de conception. La question est, comment devez vous déplacer des données à et à partir de la couche présentation ? Autrement dit, doit la couche de présentation contenir une référence à l'assembly de modèle de domaine ? (Dans un scénario de Entity Framework, l'assembly de modèle de domaine est simplement la DLL créée hors du fichier EDMX.)

Dans l'idéal, la conception doit ressembler à la figure 3 , où les objets made-to-measure sont utilisés pour passer des données à partir de la couche présentation à la couche de service et sauvegarder. Ces objets conteneur ad hoc prennent le nom des objets de transfert de données (DTO).

fig03.gif

La figure 3 communication entre une couche présentation andService Layer

Un DTO est simplement une classe de conteneur expose les propriétés, mais aucune méthode. Un DTO est utile lorsque vous devez valeurs du groupe dans des structures ad hoc pour passer des données.

Du point de vue design pure, DTO constituent une solution très proche de parfaitement. DTO permettent de mieux dissocier présentation à partir de la couche de service et le modèle de domaine. Lorsque les DTO sont utilisées, la couche de présentation et la couche de service partagent contrats de données plutôt que de classes. Un contrat de données est essentiellement une représentation des données qui échangent des composants qui interagissent neutre. Le contrat de données décrit les données que reçoit un composant, mais il n'est pas une classe spécifique au système, comme une entité. À la fin de la journée, un contrat de données est une classe, mais il est plus comme une classe d'assistance spécifiquement créée pour une méthode de service particulier.

Une couche de DTO isole le modèle de domaine à partir de la présentation, ce qui entraînera un couplage lâche et transfert de données optimisée.

Autres avantages de DTO

L'adoption de contrats de données ajoute beaucoup de souplesse et la couche de service, par la suite à la conception de l'application entière. Par exemple, si les DTO sont utilisées, une modification dans la configuration requise qui force un déplacement vers un autre volume de données n'a aucune incidence sur la couche de service ou même le domaine. Vous modifiez la classe DTO impliquée en ajoutant une nouvelle propriété, mais laissez l'interface globale de la couche de service intacts.

Il est important de noter qu'une modification de la présentation probablement signifie une modification dans un des cas d'utilisation et, par conséquent, dans la logique d'application. Car la couche de service rend la logique d'application, dans ce contexte, une modification dans l'interface de couche de service est toujours acceptable. Toutefois, dans mon expérience, modifications répétées de l'interface de couche de service peuvent conduire à la conclusion incorrecte est modifié dans les objets de domaine, les entités, peuvent enregistrer vous modifications supplémentaires dans la couche de service. Cela ne se produire dans des équipes well-disciplined ou lorsque les développeurs ont une compréhension approfondie de la séparation des rôles qui existe entre le modèle de domaine, la couche de service et le DTO.

Comme le montre la figure 4 , lorsque DTO sont utilisées, vous devez également une couche de carte DTO pour adapter un ou plusieurs objets entité à une autre interface requises par le cas d'utilisation. En procédant ainsi, vous implémentez réellement le modèle «Carte», parmi les modèles de conception classique et les plus populaires. Le modèle de carte convertit essentiellement l'interface d'une classe dans une autre interface qui attend un client.

fig04.gif

La figure 4 cartes DTO dans la couche BLL

Référence à La figure 4 , la couche carte est responsable pour lire une instance de la classe OperationRequestDTO entrant et de création et de nouvelles instances de OperationResponseDTO de remplissage.

Lorsque exigences modifier et forcer des modifications dans une couche de service basé sur le DTO, tout ce que vous avez à faire est mise à jour les données publiques de contrat du DTO et ajustement l'adaptateur de DTO correspondant.

Les avantages découplage de DTO ne fin ici. En outre, pour subsistent heureusement les modifications apportées à la présentation, vous pouvez saisir modifications aux entités dans le modèle de domaine sans impact sur les clients que vous devrez peut-être.

N'importe quel modèle de domaine réaliste contient des relations, tels que les commandes par client et commande au client, qui forment un lien entre les entités Customer et Order double. Avec DTO, vous aussi contourner le problème de gestion des références circulaires pendant la sérialisation d'objets d'entité. DTO peuvent être créés pour exécuter un flux plat de valeurs qui, si nécessaire, sérialiser simplement correctement les limites. (Je vous renvoie à ce point dans un instant.)

Inconvénients de DTO

Du point de vue design pure, DTO sont un avantage réel, mais est présent théorique confirmée par l'application pratique, trop ? En plusieurs points ouvert architecture, la réponse est, elle dépend.

Des centaines d'entités dans le modèle de domaine est définitivement une bonne raison pour considérant alternatives à une approche simple basée sur les DTO. Dans les projets volumineux avec autant d'entités, DTO ajoutent un niveau remarquable de complexité (supplémentaire) et de travail à effectuer. Dans court pure, solution DTO 100 % est souvent simplement une solution pénible 100 pour cent.

Lors de la complexité ajoutée à une solution par DTO mesure normalement à la cardinalité du modèle de domaine, le nombre réel de DTO nécessaires peut être que plus fiable déterminé les cas d'utilisation et l'implémentation de la couche de service. Une formule correcte pour l'estimation DTO combien vous avez besoin consiste à examiner le nombre de méthodes dans la couche de service. Le nombre réel peut être plus petite si vous parvenez à réutiliser un DTO dans plusieurs appels de couche de service ou supérieure si votre DTO groupe certaines données de l'utilisation de types complexes.

En résumé, le seul argument contre l'utilisation de DTO est le travail supplémentaire nécessaire pour écrire et de gérer le nombre de classes DTO résultantes. Il n'est pas, cependant, une simple a d'importance de laziness un programmeur. Dans les projets volumineuses, découplage présentation de la couche de service vous en coûte plusieurs centaines de nouvelles classes.

Notez également qu'un DTO n'est pas simplement la copie de chaque entité que vous avez peut-être léger. Supposons que deux cas d'utilisation distinctes vous obliger à renvoyer une collection de commandes, par exemple, GetOrdersByCountry et GetOrdersByCustomer. Les informations à placer dans le «commander» sont très probablement différentes. Vous devez probablement plus (ou moins) détails GetOrdersByCustomer que dans GetOrdersByCountry. Cela signifie que DTO distinctes sont nécessaires. C'est la raison pour laquelle des centaines d'entités sont certainement une mesure rapide de complexité, mais le nombre réel de DTO peut être déterminé uniquement en examinant le cas d'utilisation.

Si les DTO ne sont pas toujours optimales, quelle serait une approche alternative viable ?

La seule alternative à l'utilisation de DTO est pour référencer l'assembly modèle domaine à partir de dans la couche présentation. De cette façon, vous établir un couplage étroit entre les couches. Et étroitement couplées couches peuvent être un problème encore pire.

Références des entités directement

Une condition première, n'est pas donc évidente pour activer le lien d'entités directement à partir de la couche de présentation est qu'il est acceptable pour la couche de présentation recevoir des données dans le format des objets d'entité. La présentation doit parfois des données en une manière particulière. Une couche carte DTO existe uniquement les données qui requis par le client. Si vous n'utilisez pas cependant de DTO, la tâche de mise en forme des données correctement doit être déplacée vers la couche de présentation. En fait, au mauvais endroit dans lequel pour formater des données fins d'interface utilisateur est le modèle de domaine lui-même.

En réalité, vous pouvez effectuer sans DTO uniquement si la couche de présentation et la couche de service sont trouver dans le même processus. Dans ce cas, vous pouvez facilement faire référence à l'assembly d'entité à partir de dans les deux couches sans traiter les épines problèmes comme la sérialisation d'accès distant et les données. Cette considération mène à une autre bonne question : où doit ajuster la couche de service ?

Si le client est une page Web, la couche de service est de préférence locale pour le serveur Web qui héberge la page. Dans les applications ASP.NET, la couche de présentation est toutes les classes code-behind et vit côte à côte avec la couche de service dans le même AppDomain. Dans un tel scénario, chaque communication entre la couche de présentation et la couche de service produit en cours et objets peuvent être partagées avec supplémentaires ne vous inquiétez. Les applications ASP.NET sont un bon scénario où vous pouvez essayer une solution qui n'utilise pas la couche supplémentaire de DTO.

Technology-Wise, vous pouvez implémenter la couche de service via objets .NET simples ou les services Windows Communication Foundation (WCF) local. Si l'application est réussie, vous pouvez facilement augmenter l'évolutivité en déplaçant vers la couche de service à un serveur d'applications distincts.

Si le client est une application de bureau, la couche de service est généralement déployée sur un niveau différent puis accès à distance à partir du client. Tant que le client et le serveur distant partagent la même plate-forme .NET, vous pouvez utiliser remoting techniques (ou plus, les services WCF) pour implémenter la communication et toujours utiliser objets d'entité natif sur les deux extrémités. L'infrastructure WCF va s'occuper de marshaling des données dans différents niveaux et pompe dans les copies des entités natives. En outre, dans ce cas vous pouvez organiser une architecture qui n'utilise pas DTO. Éléments modifier considérablement si les plates-formes client et serveur sont incompatibles. Dans ce cas, vous ne disposez d'aucun risque pour lier les objets natifs et les appeler à partir du client ; par conséquent, vous êtes dans un scénario pur orientée service et à l'aide de DTO est uniquement possible.

Le mode intermédiaire

Les DTO sont l'objet d'un choix de conception important qui affecte l'implémentation de toute communication entre la présentation et le serveur principal du système.

Si vous employez DTO, vous maintenir le système faiblement couplés et ouverte vers une variété de clients. DTO constituent le choix idéal, si vous pouvez vous permettre. DTO ajouter une importante programmation surcharge à un système réel. Cela ne signifie pas que DTO ne doivent pas être utilisés, mais ils entraîner une prolifération de classes pouvez prefigure vraiment un cauchemar de maintenance dans les projets avec quelques objets entité centaines et même plusieurs cas d'utilisation.

Si vous êtes sur le même temps un fournisseur et consommateur de la couche de service et si vous avez un contrôle total sur la présentation, il peut être avantages dans référençant l'assembly de modèle d'entité à partir de la présentation. De cette façon, toutes les méthodes de la couche de service sont autorisés à utiliser des classes entité en tant que les contrats de données de leurs signatures. L'impact sur conception et le codage est clairement relativement plus doux.

Si vous souhaitez utiliser des DTO ou pas n'est pas un point facile à généraliser. Pour être efficace, la décision finale doit toujours effectuée examinant les détails du projet. Au final, une approche mixte est probablement que vous allez effectuer la plupart du temps. Personnellement, j'ont tendance à utiliser entités autant que possible. Cela se produit pas, car je suis pureté et la conception en mode minimal, mais pour une question plus simple de pragmatism. Avec un modèle d'entité qui tient compte des entités uniquement 10 quelques cas d'utilisation, à l'aide DTO jusqu'à la ne poser aucun problème significatif. Vous et obtenez conception claire faible couplage. Toutefois, avec des centaines d'entités et l'utilisation cas, le nombre réel de classes pour écrire, maintenir et tester approche ominously l'ordre des milliers. N'importe quel réduction possible de complexité qui répond aux conditions requises est plus de bienvenue.

En tant qu'architecte, toutefois, vous devez toujours être sur l'alerte pour reconnaître les signes indiquant la distance entre le modèle d'entité et ce que la présentation attend est importante, voire impossible couvrir. Dans ce cas, vous devez prendre la gamme (et plus sûre nettoyage) de DTO.

Approche mixte

Les applications en couches aujourd'hui réservent une section de la couche BLL à la couche de service. La couche de service (également appelée la couche d'application) contient la logique d'application ; autrement dit, les règles d'entreprise et les procédures sont pour l'application mais pas pour le domaine. Un système comprenant plusieurs parties frontales va exposer un seul élément de logique de domaine via les classes d'entité, mais ensuite chaque frontal aura une couche métier supplémentaire spécifique aux cas d'utilisation qu'il prend en charge. C'est ce qui correspond à la couche de service (ou application).

La logique d'application déclenché à partir de l'interface utilisateur, les scripts les entités et les services dans la logique métier. Dans la couche de service, vous implémentez les cas d'utilisation et exposez chaque séquence d'étapes via une méthode à granularité grossière de la présentation à appeler.

Dans la conception de la couche de service, vous pouvez souhaiter appliquer quelques méthodes conseillées, adopter l'orientation service et partager des contrats de données au lieu de classes d'entité. Cette approche est idéale en théorie, il souvent incompatible avec le monde réel, tel qu'il finit par ajout trop surcharge dans projets avec des centaines d'entités et scénarios d'utilisation.

Il s'avère qu'une approche mixte qui utilise des données uniquement lorsque l'utilisation des classes ne peut pas les contrats, est souvent la solution plus acceptable. Sans en tant qu'architecte, vous devez apporter cette décision légèrement. Violation de règles de conception est autorisé, tant que vous savez ce que vous êtes en train de faire.

Envoyez vos questions et commentaires pour Dino à Cutting@Microsoft.com.

Dino Esposito est un architecte à IDesign et co-auteur de Microsoft .NET: Architecting Applications for the Enterprise (Microsoft Press, 2008). Basé en Italie, Dino intervient régulièrement au secteur événements dans le monde entier. Vous pouvez joindre son blog à weblogs.ASP. net/despos.