La singola responsabilità (motivo per cambiare) di un'entità dovrebbe essere quella di identificarsi in modo univoco, in altre parole, la sua responsabilità deve essere individuabile.
Il libro DDD di Eric Evan, pag. 93:
la responsabilità più fondamentale delle Entità è quella di stabilire la continuità in modo che il comportamento possa essere chiaro e prevedibile. Lo fanno meglio se vengono tenuti di riserva. Piuttosto che concentrarsi sugli attributi o persino sul comportamento, eliminare la definizione dell'oggetto Entità fino alle caratteristiche più intrinseche, in particolare quelle che lo identificano o sono comunemente utilizzate per trovarlo o abbinarlo. Aggiungi solo il comportamento essenziale al concetto e agli attributi richiesti da quel comportamento.
Oltre a ciò, cerca di rimuovere il comportamento e gli attributi in altri oggetti associati all'entità principale. Al di là dei problemi di identità, le entità tendono ad adempiere alle loro responsabilità coordinando le operazioni degli oggetti di loro proprietà.
1.
... eliminare la definizione dell'oggetto ENTITY fino alle caratteristiche più intrinseche, in particolare quelle che lo identificano o sono comunemente utilizzate per trovarlo o abbinarlo. Aggiungi solo il comportamento essenziale al concetto ...
Una volta che a un'entità viene assegnato un ID univoco , viene stabilita la sua identità e quindi presumo che tale entità non abbia bisogno di alcun comportamento per mantenere la sua identità o per aiutarla a identificarsi . Quindi, non capisco che tipo di comportamento è autore riferendosi a (oltre find
e match
operazioni ) con " un comportamento che è essenziale per il concetto di "?
2.
... eliminare la definizione dell'oggetto ENTITY fino alle caratteristiche più intrinseche, in particolare quelle che lo identificano o sono comunemente utilizzate per trovarlo o abbinarlo. ... Oltre a ciò, cerca di rimuovere il comportamento e gli attributi in altri oggetti associati al core ENTITY.
Quindi qualsiasi comportamento che non aiuta a identificare l'entità, ma lo caratterizzeremmo comunque come una caratteristica intrinseca di quell'entità (ad esempio l'abbaiare è intrinseco ai cani, il volo è intrinseco agli aeroplani, la deposizione delle uova è intrinseca agli uccelli ... .), dovrebbe essere inserito in altri oggetti associati a quell'entità (esempio: dovremmo mettere il comportamento di abbaiare in un oggetto associato a un'entità cane)?
3.
Oltre a ciò, cerca di rimuovere il comportamento e gli attributi in altri oggetti associati al core ENTITY.
a) MyEntity
delegare le responsabilità A_resp
e B_resp
agli oggetti a
e b
, rispettivamente.
Anche se la maggior parte A_resp
e il B_resp
lavoro è svolto da a
e b
istanze, i clienti sono ancora serviti A_resp
e B_resp
attraverso MyEntity
, il che significa che dal punto di vista del cliente appartengono le due responsabilità MyEntity
. Quindi, ciò non significa MyEntity
anche avere A_resp
e B_resp
responsabilità e come tale sta violando SRP ?
b) Anche se lo ipotizziamo A_resp
e B_resp
non ci apparteniamo MyEntity
, MyEntity
ha ancora la responsabilità AB_resp
di coordinare le operazioni degli oggetti a
e b
. Quindi non MyEntity
viola SRP poiché almeno ha due responsabilità : identificarsi in modo univoco e anche AB_resp
?
class MyEntity
{
private A a = ...
private B b = ...
public A GetA()
{ ... }
public B GetB()
{ ... }
/* coordinates operations of objects a and b */
public int AworkB()
{ ... }
}
/* A encapsulates a single responsibility resp_A*/
/* A is value object */
class A
{ ... }
/* B encapsulates a single responsibility resp_B*/
/* B is value object */
class B
{ ... }
AGGIORNARE:
1.
Il comportamento in questo contesto si riferisce al comportamento semantico. Ad esempio, una proprietà su una classe (ovvero l'attributo su un oggetto dominio) utilizzata per identificarla in modo univoco ha un comportamento. Mentre questo non è rappresentato direttamente nel codice. Il comportamento previsto è che non ci saranno valori duplicati per quella proprietà.
Quindi nel codice non avremmo quasi mai bisogno di implementare effettivamente un comportamento (cioè un'operazione) che mantenga in qualche modo l'identità dell'entità, poiché come hai spiegato un simile comportamento esiste solo come concetto in un modello di dominio (sotto forma di un attributo ID di un'entità), ma quando traduciamo questo attributo ID in codice, parte della sua semantica viene persa (ovvero la parte che assicura implicitamente che il valore ID sia univoco viene persa)?
2.
Inoltre, una proprietà come Age non ha alcun contesto al di fuori di un'entità persona e, come tale, non ha senso spostarsi in un oggetto diverso ... Tuttavia, tali informazioni potrebbero essere facilmente archiviate in una posizione separata rispetto all'identificatore univoco, quindi il riferimento confuso al comportamento. L'età potrebbe essere un valore caricato pigro.
a) Se la Age
proprietà è lazy load, allora potremmo chiamarla un comportamento, anche se semanticamente Age
è solo un attributo?
3.
Si potrebbero facilmente avere operazioni specifiche per l'indirizzo come la verifica che si tratti di un indirizzo valido. Potresti non saperlo in fase di progettazione, ma l'intero concetto è quello di scomporre gli oggetti nelle loro parti più piccole
Mentre sono d'accordo che perderemmo contesto spostandoci Age
in un oggetto diverso, il contesto non andrebbe perso se spostassimo la DateOfBirth
proprietà in un oggetto diverso, ma di solito non lo spostiamo.
Qual è la ragione principale per cui dovremmo spostarci Address
in un altro oggetto, ma no DateOfBirth
? Perché DateOfBirth
è più intrinseco Person
all'entità o perché ci sono meno possibilità che da qualche parte in futuro potremmo aver bisogno di definire operazioni specifiche DateOfBirth
?
4. Devo dire che ancora non so se MyEntity
ha anche A_resp
e B_resp
responsabilità e perché MyEntity
anche il fatto di AB_resp
non essere considerato una violazione di SRP
EULERFX
1)
I comportamenti a cui fa riferimento l'autore sono comportamenti associati all'entità. Questi sono i comportamenti che modificano lo stato dell'entità
a) Se ti capisco correttamente, stai dicendo che l' entità dovrebbe contenere solo quei comportamenti che modificano i suoi attributi (cioè il suo stato )?
b) E i comportamenti che non modificano necessariamente lo stato dell'entità , ma sono comunque considerati come una caratteristica intrinseca di quell'entità (esempio: l' abbaiare sarebbe una caratteristica intrinseca di Dog
un'entità, anche se non modificasse Stato del cane )? Dovremmo includere questi comportamenti in un'entità o dovrebbero essere spostati su altri oggetti?
2)
Per quanto riguarda lo spostamento del comportamento su altri oggetti, l'autore si riferisce specificamente agli oggetti valore.
Sebbene la mia citazione non lo includa, ma l'autore menziona nello stesso paragrafo che in alcuni casi i comportamenti (e gli attributi ) verranno anche spostati in altre entità (anche se comprendo i vantaggi dello spostamento dei comportamenti nei VO)
3) Assumendo MyEntity
(vedere la domanda 3. nel mio post originale) non viola SRP, diremmo che una responsabilità di MyEntity
è tra l'altro anche composti da:
un. A_resp
+ B_resp
+ AB_resp
( AB_resp
coordina oggetti a
e b
)
o
b. AB_resp
+ delegare A_resp
e B_resp
agli oggetti ( a
e b
) associati a MyEntity
?
4) Il libro DDD di Eric Evan, pag. 94:
CustomerID è l'unico identificativo di ENTITY cliente (figura 5.5), ma il numero di telefono e l'indirizzo vengono spesso utilizzati per trovare o abbinare un cliente. Il nome non definisce l'identità di una persona, ma viene spesso utilizzato come parte del mezzo per determinarla.
In questo esempio, gli attributi di telefono e indirizzo sono stati spostati in Cliente, ma su un progetto reale, tale scelta dipenderà dal modo in cui i clienti del dominio vengono generalmente abbinati o distinti. Ad esempio, se un cliente ha molti numeri di telefono di contatto per scopi diversi, il numero di telefono non è associato all'identità e deve rimanere con il contatto di vendita.
un)
CustomerID è l'unico identificativo di ENTITY cliente (figura 5.5), ma il numero di telefono e l'indirizzo vengono spesso utilizzati per trovare o abbinare un cliente. Il nome non definisce l'identità di una persona, ma viene spesso utilizzato come parte del mezzo per determinarla.
La citazione afferma che solo gli attributi associati all'identità dovrebbero rimanere in un'entità . Presumo autore significa che l' entità dovrebbe contenere solo quegli attributi che sono spesso usati per trovare o abbinare questa entità , mentre TUTTI gli altri attributi dovrebbero essere spostati?
b) Ma come / dove dovrebbero essere spostati altri attributi ? Ad esempio (ipotesi qui è che l' attributo address non sia usato per trovare o abbinare Customer
e quindi vogliamo spostare l' attributo address fuori da Customer
):
se invece di avere Customer.Address
(di tipo string
) creiamo una proprietà Customer.Address
di tipo Address
, spostiamo l' attributo address in un oggetto VO associato (che è di tipo Address
) o diremmo che Customer
contiene ancora l' attributo address ?
c)
In questo esempio, gli attributi di telefono e indirizzo sono stati spostati in Cliente, ma su un progetto reale, tale scelta dipenderà dal modo in cui i clienti del dominio vengono generalmente abbinati o distinti. Ad esempio, se un cliente ha molti numeri di telefono di contatto per scopi diversi, il numero di telefono non è associato all'identità e deve rimanere con il contatto di vendita.
L'autore non ha torto qui, dal momento che se assumiamo ciascuno dei tanti numeri di telefono di contatto che Customer
appartengono solo a quel particolare Customer
, allora direi che questi numeri di telefono sono associati all'identità tanto quanto quando Customer
aveva un solo numero di telefono ?
5)
La ragione per cui l'autore suggerisce di eliminare l'entità è che quando si crea inizialmente un'entità cliente, c'è la tendenza a popolarla con qualsiasi attributo che si possa pensare di essere associato a un cliente. Questo è un approccio incentrato sui dati che trascura i comportamenti che alla fine portano a un modello di dominio anemico.
Fuori tema, ma ho pensato anemici modello del dominio risultati di muoversi comportamento di un soggetto , mentre il vostro esempio è popolando un soggetto con un sacco di attributi , il che porterebbe a Customer
dover troppo comportamento (in quanto ci sarebbe probabilmente includiamo anche Customer
i comportamenti che modificare questi attributi aggiuntivi ) e quindi in violazione di SRP?
Grazie