Oggetti Value vs Entity (Domain Driven Design)


90

Ho appena iniziato a leggere DDD. Non sono in grado di cogliere completamente il concetto di oggetti Entity vs Value .. Qualcuno può spiegare i problemi (manutenibilità, prestazioni .. ecc.) Che un sistema potrebbe incontrare quando un oggetto Value è progettato come un oggetto Entity? L'esempio sarebbe fantastico ...


2
Qui ho scritto un elenco completo (IMO) delle differenze tra i due: enterprisecraftsmanship.com/2016/01/11/…
Vladimir

Risposte:


108

Ridotta alla distinzione essenziale, l'identità conta per le entità, ma non importa per gli oggetti di valore. Ad esempio, il nome di qualcuno è un oggetto valore. Un'entità cliente potrebbe essere composta da un nome cliente (oggetto valore), List <Order> OrderHistory (elenco di entità) e forse un indirizzo predefinito (in genere un oggetto valore). L'entità cliente avrebbe un ID e ogni ordine avrebbe un ID, ma un nome no; generalmente, comunque all'interno del modello a oggetti, l'identità di un indirizzo probabilmente non ha importanza.

Gli oggetti valore possono essere tipicamente rappresentati come oggetti immutabili; cambiare una proprietà di un oggetto valore distrugge essenzialmente il vecchio oggetto e ne crea uno nuovo, perché non sei interessato all'identità quanto al contenuto. Correttamente, il metodo di istanza Equals su Name restituirebbe "true" fintanto che le proprietà dell'oggetto sono identiche a quelle di un'altra istanza.

Tuttavia, la modifica di alcuni attributi di un'entità come Customer non distrugge il cliente; un'entità cliente è tipicamente mutabile. L'identità rimane la stessa (almeno una volta che l'oggetto è stato mantenuto).

Probabilmente crei oggetti di valore senza rendertene conto; ogni volta che rappresenti un aspetto di un'entità creando una classe a grana fine, hai un oggetto valore. Ad esempio, una classe IPAddress, che ha alcuni vincoli su valori validi ma è composta da tipi di dati più semplici, sarebbe un oggetto valore. Un EmailAddress potrebbe essere una stringa o un oggetto valore con il proprio insieme di comportamenti.

È del tutto possibile che anche gli elementi che hanno un'identità nel tuo database non abbiano un'identità nel tuo modello a oggetti. Ma il caso più semplice è un composto di alcuni attributi che hanno senso insieme. Probabilmente non vuoi avere Customer.FirstName, Customer.LastName, Customer.MiddleInitial e Customer.Title quando puoi comporli insieme come Customer.Name; probabilmente saranno più campi nel tuo database nel momento in cui pensi alla persistenza, ma al tuo modello a oggetti non interessa.


Dove si inseriscono gli oggetti modificabili non condivisi? Se nell'intero universo esiste solo un riferimento a un oggetto, l'identità dell'oggetto sarà irrilevante anche se è mutevole. Per come la vedo io, una cosa è un'entità se esiste un riferimento che potrebbe essere usato per osservare un aspetto dello stato che potrebbe cambiare senza che quel riferimento sia stato usato per cambiarlo . Se una cosa non si collega al mondo esterno ed è immutabile o esiste solo un riferimento ad essa ovunque nell'universo, allora lo scenario di cui sopra non può verificarsi ed è un valore.
supercat

Qualcosa come un int[1]può essere un valore mutabile non condiviso, un valore immutabile condivisibile (se nessuna delle cose che contengono riferimenti scriverà mai su di esso), o un'entità (se esistono due o più riferimenti, e uno di essi può essere usato per scrivere valori che possono essere letti utilizzando l'altro). Sfortunatamente, non conosco alcun supporto linguistico in Java o .NET per impedire agli oggetti di classe che incapsulano valori mutabili di trasformarsi accidentalmente in entità.
supercat

@supercat, se intendi nessun supporto semplice diretto, sarei d'accordo, ma lo faccio eliminando l'accesso pubblico ai costruttori, utilizzando solo factory statiche per creare nuove istanze e limitando tutto l'accesso allo stato tramite proprietà di sola lettura (nessun setter) .
Charles Bretana

36

Qualsiasi oggetto che è definito collettivamente da tutti i suoi attributi è un oggetto valore. Se uno qualsiasi degli attributi cambia, hai una nuova istanza di un oggetto valore. Questo è il motivo per cui gli oggetti valore sono definiti immutabili.

Se l'oggetto non è completamente definito da tutti i suoi attributi, esiste un sottoinsieme di attributi che costituiscono l'identità dell'oggetto. Gli attributi rimanenti possono cambiare senza ridefinire l'oggetto. Questo tipo di oggetto non può essere definito come immutabile.

Un modo più semplice per fare la distinzione è pensare agli oggetti valore come dati statici che non cambieranno mai e alle entità come dati che si evolvono nell'applicazione.


7

Tipi di valore:

  • I tipi di valore non esistono da soli, dipende dai tipi di entità.
  • L'oggetto tipo di valore appartiene a un oggetto tipo di entità.
  • La durata di un'istanza del tipo di valore è limitata dalla durata dell'istanza dell'entità proprietaria.
  • Tre tipi di valore: base (tipi di dati primitivi), composito (indirizzo) e raccolta (mappa, elenco, array)

Entità:

  • I tipi di entità possono esistere da soli (identità)
  • Un'entità ha il proprio ciclo di vita. Può esistere indipendentemente da qualsiasi altra entità.
  • Ad esempio: persona, organizzazione, college, cellulare, casa ecc. Ogni oggetto ha una propria identità

Non correlato a DDD :(
HydTechie

6

Non so se quanto segue sia corretto, ma direi che nel caso di un oggetto Indirizzo, vogliamo usarlo come oggetto valore anziché come entità perché le modifiche all'entità si rifletterebbero su tutti gli oggetti collegati ( una persona per esempio).

Prendi questo caso: vivi a casa tua con altre persone. Se usassimo Entity for Address, direi che ci sarebbe un indirizzo univoco a cui si collegano tutti gli oggetti Person. Se una persona si trasferisce, aggiorna il suo indirizzo. Se aggiorni le proprietà dell'entità indirizzo, tutte le persone avrebbero un indirizzo diverso. Nel caso di un oggetto valore, non saremmo in grado di modificare l'indirizzo (poiché è immutabile) e saremmo costretti a fornire un nuovo indirizzo per quella persona.

Suona bene? Devo dire che ero / sono anche ancora confuso su questa differenza, dopo aver letto il libro DDD.

Andando oltre, come sarebbe modellato questo nel database? Avresti tutte le proprietà dell'oggetto Address come colonne nella tabella Person o creeresti una tabella Address separata che avrebbe anche un identificatore univoco? In quest'ultimo caso, le persone che vivono nella stessa casa avrebbero ciascuna un'istanza diversa di un oggetto Indirizzo, ma quegli oggetti sarebbero gli stessi tranne che per la loro proprietà ID.


1
"Prendi questo caso: vivi a casa tua con altre persone. Se usassimo Entity for Address, direi che ci sarebbe un indirizzo univoco a cui si collegano tutti gli oggetti Person". Penso che ognuna di queste persone abbia la propria istanza di Indirizzo, ma è semplicemente uguale (è come se ognuna di loro potesse avere una banconota da 5 dollari, ma ciò non significa che sia la stessa banconota)
Prokurors

"ma questo non significa che si tratti della stessa banconota" - Immagino che questo dipenda dal fatto che si assegnino o meno proprietà aggiuntive alla banconota (ad es. data di emissione, posizione fisica nello spazio, ecc.); altrimenti sarebbero gli stessi. E immagino sia lo stesso per il software: l'indirizzo è lo stesso o meno a seconda delle proprietà che dobbiamo / vogliamo considerare.
adrhc

4

indirizzo può essere entità o oggetto valore che dipende dal processo occupato. L'oggetto indirizzo può essere un'entità nell'applicazione del servizio di corriere, ma l'indirizzo può essere un oggetto valore in qualche altra applicazione. nell'applicazione del corriere l'identità è importante per l'oggetto indirizzo


2

Ho chiesto informazioni su questo in un altro thread e penso di essere ancora confuso. Potrei confondere le considerazioni sulle prestazioni con la modellazione dei dati. Nella nostra applicazione di catalogazione, un cliente non cambia fino a quando non è necessario. Sembra stupido, ma le "letture" dei dati dei clienti superano di gran lunga le "scritture" e poiché molte richieste Web stanno tutte colpendo il "set attivo" di oggetti, non voglio continuare a caricare i clienti più e più volte. Quindi stavo percorrendo una strada immutabile per l'oggetto Cliente: caricarlo, memorizzarlo nella cache e servire lo stesso al 99% delle richieste (multi-thread) che vogliono vedere il cliente. Quindi, quando un cliente cambia qualcosa, chiedi a un "editor" di creare un nuovo cliente e invalidare quello vecchio.

La mia preoccupazione è se molti thread vedono lo stesso oggetto cliente ed è mutabile, quindi quando un thread inizia a cambiare, ne deriva il caos negli altri.

I miei problemi ora sono: 1) è ragionevole e 2) il modo migliore per farlo senza duplicare molto codice sulle proprietà.


1

3 distinzione tra EntitieseValue Objects

  • Identificatore vs uguaglianza strutturale: le entità hanno un identificatore, le entità sono le stesse se hanno lo stesso identificatore. Gli oggetti valore oltre la mano hanno uguaglianza strutturale, consideriamo due oggetti valore uguali quando tutti i campi sono uguali. Gli oggetti valore non possono avere un identificatore.

  • Mutabilità vs immutabilità: gli oggetti valore sono strutture di dati immutabili mentre le entità cambiano durante la loro vita.

  • Durata: gli oggetti valore devono appartenere a entità


1

In una frase molto semplice posso dire, abbiamo tre tipi di uguaglianza:

  • Uguaglianza dell'identificatore : una classe ha un file id e due oggetti vengono confrontati con il valore del campo id.
  • Uguaglianza dei riferimenti : se un riferimento a due oggetti ha lo stesso indirizzo in memoria.
  • Uguaglianza strutturale : due oggetti sono uguali se tutti i membri di essi sono abbinati.

L'uguaglianza dell'identificatore si riferisce solo all'entità e l'uguaglianza strutturale si riferisce solo all'oggetto valore. Infatti gli oggetti valore non hanno id e possiamo usarli in modo intercambiabile. anche gli oggetti valore devono essere immutabili e le entità possono essere modificabili e gli oggetti valore non avranno anzi una tabella nel database.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.