web-dev-qa-db-fra.com

Ancien objet CLR simple et objet de transfert de données

POCO = Objet ancien ancien CLR (ou supérieur: classe)

DTO = objet de transfert de données

Dans ce post , il y a une différence, mais franchement, la plupart des blogs que j'ai lus décrivent POCO de la manière dont le DTO est défini: les DTO sont de simples conteneurs de données utilisés pour déplacer des données entre les couches d'une application.

POCO et DTO sont-ils la même chose?

388
Patrick Peters

Un POCO suit les règles de la POO. Il devrait (mais ne doit pas obligatoirement) avoir le comportement d'état et . POCO vient de POJO, inventé par Martin Fowler [ anecdote ici ]. Il a utilisé le terme POJO comme un moyen de rendre plus sexy le rejet des implémentations lourdes du framework. POCO devrait être utilisé dans le même contexte en .Net. Ne laissez pas les frameworks dicter la conception de votre objet.

Le seul but d'un DTO est de transférer un état et ne devrait avoir aucun comportement. Voir l'explication de Martin Fowler d'un DTO pour un exemple d'utilisation de ce modèle.

Voici la différence: POCO décrit une approche de la programmation (bonne vieille programmation orientée objet), où DTO est un motif utilisé pour "transférer des données" à l'aide d'objets.

Bien que vous puissiez traiter les POCO comme des DTO, vous courez le risque de créer un modèle de domaine anémique si vous le faites. De plus, il existe une discordance dans la structure, car les DTO doivent être conçus pour transférer des données, et non pour représenter la vraie structure du domaine métier. Le résultat est que les DTO ont tendance à être plus plats que votre domaine actuel.

Dans un domaine de complexité raisonnable, il est presque toujours préférable de créer des POCO de domaine distincts et de les traduire en DTO. DDD (Domain Driven Design) définit la couche anti-corruption (un autre lien ici , mais la meilleure chose à faire est de l'acheter book ), qui est une bonne structure qui clarifie la ségrégation.

555
Michael Meadows

C'est probablement redondant pour moi de contribuer puisque j'ai déjà énoncé ma position dans l'article de mon blog, mais le dernier paragraphe de cet article résume en quelque sorte les choses:

Donc, en conclusion, apprenez à aimer le POCO et assurez-vous de ne pas répandre d’informations erronées disant que c’est la même chose qu’un DTO. Les DTO sont de simples conteneurs de données utilisés pour déplacer des données entre les couches d’une application. Les POCO sont des objets métier à part entière, dont la seule exigence est qu'ils sont Persistence Ignorant (aucune méthode get ou save). Enfin, si vous n'avez pas encore consulté le livre de Jimmy Nilsson, sélectionnez-le dans les piles de votre université locale. en C # et c’est une excellente lecture.

BTW, Patrick J'ai lu le POCO comme un article de style de vie, et je suis tout à fait d'accord, c'est un article fantastique. C'est en fait une section du livre de Jimmy Nilsson que j'ai recommandée. Je ne savais pas qu'il était disponible en ligne. Son livre est vraiment la meilleure source d'informations que j'ai trouvée sur POCO/DTO/Repository/et d'autres pratiques de développement DDD.

49
Rudy

POCO est simplement un objet qui ne dépend pas d'un framework externe. C'est PLAIN.

Qu'un comportement POCO ait ou non un comportement immatériel.

Un DTO peut être POCO comme un objet de domaine (qui aurait généralement un comportement riche).

En règle générale, les DTO sont plus susceptibles de créer des dépendances sur des cadres externes (par exemple, des attributs) à des fins de sérialisation, car ils sortent généralement à la frontière d'un système.

Dans les architectures typiques de style Onion (souvent utilisées dans une approche largement DDD), la couche de domaine est placée au centre et ses objets ne doivent donc pas, à ce stade, avoir de dépendances en dehors de cette couche.

27
Neil

J'ai écrit un article sur ce sujet: DTO vs Value Object vs POCO .

En bref:

  • DTO! = Objet de valeur
  • DTO ⊂ POCO
  • Objet de valeur ⊂ POCO
15
Vladimir

Je pense qu'un DTO peut être un POCO. DTO concerne davantage l'utilisation de l'objet, tandis que POCO correspond davantage au style de l'objet (découplé des concepts architecturaux).

Un exemple où POCO est différent de DTO est lorsque vous parlez de POCO dans votre modèle de domaine/modèle de logique métier, qui est une belle représentation de OO de votre domaine problématique. Vous pouvez utiliser les POCO tout au long de l'application, mais cela pourrait avoir des effets secondaires indésirables tels que des fuites de connaissances. Les DTO sont par exemple utilisés depuis la couche de service avec laquelle l'interface utilisateur communique. Ils sont une représentation plate des données et ne sont utilisés que pour fournir des données à l'interface utilisateur et pour communiquer les modifications à la couche de service. La couche service est chargée de mapper les deux manières de DTO aux objets de domaine POCO.

Mise à jour Martin Fowler dit que cette approche est une route difficile à prendre et ne doit être prise que s'il existe un décalage important. entre la couche de domaine et l'interface utilisateur.

6
Davy Landman

Un des principaux cas d'utilisation d'un DTO consiste à renvoyer des données à partir d'un service Web. Dans ce cas, POCO et DTO sont équivalents. Tout comportement dans le POCO serait supprimé lorsqu’il est renvoyé par un service Web. Par conséquent, le fait qu’il ait ou non un comportement importe peu.

1
John Saunders

voici la règle générale: DTO == mal et indicateur de logiciels sur-conçus. POCO == bien. Les modèles "d'entreprise" ont détruit le cerveau de nombreuses personnes dans le monde Java EE. s'il vous plaît ne répétez pas l'erreur dans .NET land.

1
benmmurphy

TL; DR:

Un DTO décrit le modèle de transfert d'état. Un POCO ne décrit rien. C'est une autre façon de dire "objet" en POO. Il vient de POJO (Java), inventé par Martin Fowler qui le décrit littéralement comme un nom plus sophistiqué pour "objet" car "objet" n'est pas très sexy.

Un DTO est un modèle d'objet utilisé pour transférer l'état entre les couches concernées. Ils peuvent avoir un comportement (c'est-à-dire techniquement être un poco) tant que ce comportement ne mute pas en état. Par exemple, il peut avoir une méthode qui se sérialise.

Un POCO est un objet simple, mais ce que l'on entend par "simple", c'est qu'il n'est pas spécial. Cela signifie simplement que c'est un objet CLR sans motif implicite. Un terme générique. Il n'est pas fait pour fonctionner avec un autre cadre. Donc, si votre POCO a, par exemple, [JsonProperty] ou des décorations EF, alors je dirais qu'il ne s'agit pas d'un POCO.

Voici quelques exemples de différents types de modèles d'objet à comparer:

  • Modèle de vue: utilisé pour modéliser les données d'une vue. Possède généralement des annotations de données pour faciliter la liaison et la validation. Dans MVVM, il agit également en tant que contrôleur. C'est plus qu'un DTO
  • objet valeur: utilisé pour représenter les valeurs
  • racine agrégée: utilisé pour gérer l'état et les invariants
  • Gestionnaires: utilisé pour répondre à un événement/message
  • Attributs: utilisé comme décoration pour traiter des problèmes transversaux
  • Service: utilisé pour effectuer des tâches complexes
  • Controller: utilisé pour contrôler le flux de demandes et de réponses
  • Factory: utilisé pour configurer et/ou assembler des objets complexes à utiliser lorsqu'un constructeur n'est pas assez bon. Également utilisé pour décider quels objets doivent être créés au moment de l'exécution.
  • Repository/DAO: utilisé pour accéder aux données

Ce ne sont que des objets, mais notez que la plupart d'entre eux sont généralement liés à un motif. Donc, vous pouvez les appeler "objets" ou vous pouvez être plus précis sur son intention et l'appeler par ce qu'il est. C'est aussi pourquoi nous avons des modèles de conception; décrire des concepts complexes en quelques œuvres. DTO est un motif. La racine agrégée est un modèle, View Model est un modèle (par exemple, MVC et MVVM). POCO n'est pas un modèle.

Un POCO ne décrit pas un motif. C'est simplement une manière différente de faire référence aux classes/objets dans la POO. Pensez-y comme à un concept abstrait. ils peuvent faire référence à n'importe quoi. OMI, il existe une relation à sens unique, car une fois qu'un objet atteint le point où il ne peut servir qu'un seul but, il n'est plus un objet POCO. Par exemple, une fois que vous marquez votre classe avec des décorations pour la faire fonctionner avec un cadre, ce n'est plus un POCO. Donc:

  • Un DTO est un POCO
  • Un POCO n'est pas un DTO
  • Un modèle de vue est un POCO
  • Un POCO n'est pas un modèle de vue

La distinction entre les deux consiste à maintenir des modèles clairs et cohérents afin de ne pas dépasser les préoccupations et d’engendrer un couplage étroit. Par exemple, si vous avez un objet métier qui possède des méthodes pour passer d'un état à un autre, mais qui est également décoré avec des décorations EF pour l'enregistrement sur SQL Server ET JsonProperty afin qu'il puisse être renvoyé sur un noeud final d'API. Cet objet serait intolérant à changer et serait probablement jonché de variantes de propriétés (par exemple, UserId, UserPk, UserKey, UserGuid, où certains d'entre eux sont marqués pour ne pas être enregistrés dans la base de données et d'autres marqués pour ne pas être sérialisés JSON sur le noeud final de l'API).

Donc, si vous deviez me dire que quelque chose était un DTO, alors je m'assurerais probablement qu'il n'a jamais été utilisé pour autre chose que l'état de mouvement. Si vous me disiez que quelque chose était un modèle de vue, alors je m'assurerais probablement qu'il ne soit pas sauvegardé dans une base de données. Si vous me disiez que quelque chose était un modèle de domaine, alors je m'assurerais probablement qu'il ne dépend d'aucun élément en dehors du domaine. Mais si vous me disiez que quelque chose était un POCO, vous ne me diriez pas grand chose du tout.

0
Sinaesthetic

Les classes DTO sont utilisées pour sérialiser/désérialiser des données provenant de différentes sources. Lorsque vous voulez désérialiser un objet depuis une source, peu importe la source externe: service, fichier, base de données, etc., vous voudrez peut-être seulement en utiliser une partie, objet. Après cela, vous copiez ces données sur le XModel que vous souhaitez utiliser. Un sérialiseur est une belle technologie pour charger des objets DTO. Pourquoi? une seule fonction suffit pour charger (désérialiser) l'objet.

0