Objets Valeur vs Entité (Conception pilotée par le domaine)


90

Je viens de commencer à lire DDD. Je suis incapable de saisir complètement le concept d'objets Entity vs Value. Quelqu'un peut-il s'il vous plaît expliquer les problèmes (maintenabilité, performances, etc.) qu'un système pourrait rencontrer lorsqu'un objet Value est conçu comme un objet Entity? L'exemple serait génial ...


2
Ici, j'ai écrit une liste complète (IMO) des différences entre les deux: enterprisecraftsmanship.com/2016/01/11/…
Vladimir

Réponses:


108

Réduite à la distinction essentielle, l'identité compte pour les entités, mais n'a pas d'importance pour les objets de valeur. Par exemple, le nom de quelqu'un est un objet de valeur. Une entité client peut être composée d'un nom de client (objet de valeur), d'une liste <Order> OrderHistory (liste d'entités) et peut-être d'une adresse par défaut (généralement un objet de valeur). L'entité client aurait un identifiant, et chaque commande aurait un identifiant, mais pas un nom; généralement, dans le modèle objet de toute façon, l'identité d'une adresse n'a probablement pas d'importance.

Les objets de valeur peuvent généralement être représentés comme des objets immuables; la modification d'une propriété d'un objet de valeur détruit essentiellement l'ancien objet et en crée un nouveau, car vous n'êtes pas aussi concerné par l'identité que par le contenu. Correctement, la méthode d'instance Equals sur Name renverrait "true" tant que les propriétés de l'objet sont identiques aux propriétés d'une autre instance.

Cependant, la modification d'un attribut d'une entité comme le client ne détruit pas le client; une entité client est généralement modifiable. L'identité reste la même (au moins une fois que l'objet a été conservé).

Vous créez probablement des objets de valeur sans vous en rendre compte; chaque fois que vous représentez un aspect d'une entité en créant une classe à granularité fine, vous avez un objet de valeur. Par exemple, une classe IPAddress, qui a certaines contraintes sur les valeurs valides mais est composée de types de données plus simples, serait un objet de valeur. Un EmailAddress peut être une chaîne ou un objet de valeur avec son propre ensemble de comportements.

Il est fort possible que même les éléments qui ont une identité dans votre base de données n'aient pas d'identité dans votre modèle d'objet. Mais le cas le plus simple est un composite de certains attributs qui ont du sens ensemble. Vous ne voulez probablement pas avoir Customer.FirstName, Customer.LastName, Customer.MiddleInitial et Customer.Title lorsque vous pouvez les composer ensemble en tant que Customer.Name; il y aura probablement plusieurs champs dans votre base de données au moment où vous pensez à la persistance, mais votre modèle d'objet s'en fiche.


Où se situent les objets mutables non partagés? Si dans l'univers entier il n'existe qu'une seule référence à un objet, l'identité de l'objet sera sans importance même si elle est modifiable. Tel que je le vois, une chose est une entité s'il existe une référence qui pourrait être utilisée observer un aspect d'état qui pourrait changer sans que cette référence ait été utilisée pour le changer . Si une chose ne s'attache pas au monde extérieur et qu'elle est immuable ou qu'une seule référence à elle existe n'importe où dans l'univers, alors le scénario ci-dessus ne peut pas se produire et c'est une valeur.
supercat

Quelque chose comme an int[1]peut être une valeur mutable non partagée, une valeur immuable partageable (si aucune des choses qui contiennent des références n'y écrira jamais), ou une entité (si deux références ou plus existent, et l'une d'elles peut être utilisée pour écrire valeurs qui peuvent être lues en utilisant l'autre). Malheureusement, je ne connais aucun support de langage en Java ou .NET pour empêcher les objets de classe qui encapsulent des valeurs mutables de se transformer accidentellement en entités.
supercat

@supercat, Si vous voulez dire pas de support simple direct, je serais d'accord, mais je le fais en éliminant l'accès public aux constructeurs, en utilisant uniquement des usines statiques pour créer de nouvelles instances et en restreignant tout accès à l'état via des propriétés en lecture seule (pas de setters) .
Charles Bretana

36

Tout objet défini collectivement par tous ses attributs est un objet de valeur. Si l'un des attributs change, vous avez une nouvelle instance d'un objet de valeur. C'est pourquoi les objets de valeur sont définis comme immuables.

Si l'objet n'est pas entièrement défini par tous ses attributs, il existe un sous-ensemble d'attributs qui composent l'identité de l'objet. Les autres attributs peuvent changer sans redéfinir l'objet. Ce type d'objet ne peut pas être défini comme immuable.

Une façon plus simple de faire la distinction consiste à considérer les objets de valeur comme des données statiques qui ne changeront jamais et les entités comme des données qui évoluent dans votre application.


7

Types de valeur:

  • Les types de valeur n'existent pas seuls, cela dépend des types d'entités.
  • L'objet de type valeur appartient à un objet de type d'entité.
  • La durée de vie d'une instance de type valeur est limitée par la durée de vie de l'instance d'entité propriétaire.
  • Trois types de valeurs: de base (types de données primitifs), composite (adresse) et collection (mappage, liste, tableaux)

Entités:

  • Les types d'entités peuvent exister seuls (identité)
  • Une entité a son propre cycle de vie. Il peut exister indépendamment de toute autre entité.
  • Par exemple: Personne, Organisation, Collège, Mobile, Domicile, etc. chaque objet a sa propre identité

Sans rapport avec DDD :(
HydTechie

6

Je ne sais pas si ce qui suit est correct, mais je dirais que dans le cas d'un objet Address, nous voulons l'utiliser comme objet de valeur au lieu d'une entité car les modifications apportées à l'entité seraient reflétées sur tous les objets liés ( une personne par exemple).

Prenez ce cas: vous vivez dans votre maison avec d'autres personnes. Si nous utilisions Entity pour Address, je dirais qu'il y aurait une seule adresse à laquelle tous les objets Person sont liés. Si une personne déménage, vous souhaitez mettre à jour son adresse. Si vous mettiez à jour les propriétés de l'entité d'adresse, toutes les personnes auraient une adresse différente. Dans le cas d'un objet de valeur, nous ne pourrions pas modifier l'adresse (car elle est immuable) et nous serions obligés de fournir une nouvelle adresse pour cette personne.

Cela vous semble-t-il correct? Je dois dire que j'étais / je suis aussi encore confus au sujet de cette différence, après avoir lu le livre DDD.

Pour aller plus loin, comment cela serait-il modélisé dans la base de données? Auriez-vous toutes les propriétés de l'objet Address sous forme de colonnes dans la table Person ou créeriez-vous une table Address distincte qui aurait également un identifiant unique? Dans ce dernier cas, les personnes vivant dans la même maison auraient chacune une instance différente d'un objet Address, mais ces objets seraient les mêmes sauf pour leur propriété ID.


1
"Prenons ce cas: vous vivez dans votre maison avec d'autres personnes. Si nous utilisions Entité pour Adresse, je dirais qu'il y aurait une seule Adresse à laquelle tous les objets Personne sont liés". Je pense que chacune de ces personnes a sa propre instance d'adresse, mais il se trouve qu'elles sont égales (c'est comme si chacune d'elles pouvait avoir un billet de 5 dollars, mais cela ne veut pas dire que c'est le même billet de banque)
Prokurors

"mais cela ne signifie pas qu'il s'agit du même billet de banque" - je suppose que cela dépend de l'attribution ou non de propriétés supplémentaires au billet (par exemple, date d'émission, emplacement physique dans l'espace, etc.); sinon, ils seraient les mêmes. Et je suppose que c'est la même chose pour les logiciels: l'adresse est la même ou non en fonction des propriétés que nous devons / voulons considérer.
adrhc

4

L'adresse peut être une entité ou un objet de valeur qui dépend du processus de busies. objet d'adresse peut être une entité dans une application de service de messagerie, mais une adresse peut être un objet de valeur dans une autre application. dans les questions d'identité de l'application de messagerie pour l'objet d'adresse


2

J'ai demandé à ce sujet dans un autre fil et je pense que je suis toujours confus. Je peux confondre les considérations de performances avec la modélisation des données. Dans notre application de catalogage, un client ne change pas tant qu'il n'en a pas besoin. Cela semble stupide - mais les `` lectures '' des données client dépassent de loin les `` écritures '' et comme de nombreuses requêtes Web touchent toutes `` l'ensemble actif '' d'objets, je ne veux pas continuer à charger les clients à maintes reprises. Je me dirigeais donc vers une route immuable pour l'objet Client - chargez-le, mettez-le en cache et servez le même aux 99% des demandes (multi-threadées) qui veulent voir le client. Ensuite, lorsqu'un client change quelque chose, demandez à un «éditeur» de créer un nouveau client et d'invalider l'ancien.

Ma préoccupation est que si de nombreux threads voient le même objet client et qu'il est mutable, alors lorsqu'un thread commence à changer, il en résulte un chaos dans les autres.

Mes problèmes sont maintenant, 1) est-ce raisonnable, et 2) comment faire au mieux sans dupliquer beaucoup de code sur les propriétés.


1

3 distinction entre EntitiesetValue Objects

  • Identifiant vs égalité structurelle: les entités ont un identifiant, les entités sont les mêmes si elles ont le même identifiant. Les objets de valeur au-delà de la main ont une égalité structurelle, nous considérons deux objets de valeur égaux lorsque tous les champs sont identiques. Les objets de valeur ne peuvent pas avoir d'identificateur.

  • Mutabilité vs immuabilité: les objets de valeur sont des structures de données immuables alors que les entités changent au cours de leur vie.

  • Durée de vie: les objets de valeur doivent appartenir à des entités


1

En une phrase très simple, je peux dire, nous avons trois types d'égalité:

  • Égalité des identificateurs : une classe a un identifiant et deux objets sont comparés à leur valeur de champ id.
  • Egalité de référence : si une référence à deux objets a une même adresse en mémoire.
  • Égalité structurelle : deux objets sont égaux si tous leurs membres sont mis en correspondance.

L'égalité d'identifiant se réfère uniquement à l'entité et l'égalité structurelle se réfère uniquement à l'objet de valeur. En fait, les objets de valeur n'ont pas d'identifiant et nous pouvons les utiliser de manière interchangeable. les objets de valeur doivent également être immuables et les entités peuvent être mutables et les objets de valeur n'auront pas de table dans la base de données.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.