2014-10-29 8 views
5

Diciamo che ho due entità Utente e Oggetto. L'unico comportamento nel dominio tra queste due entità è che un utente può apprezzare un oggetto. Poiché non vi è alcuna restrizione sul numero di elementi che un utente può piacere, questa relazione molti-a-molti può essere grande.Progettazione basata su domini: come modellare le relazioni che sono grandi ma con pochi comportamenti

Non credo che sia ragionevole per le prestazioni avere un utente che contenga un elenco di elementi che hanno gradito nel suo modello o viceversa, dal momento che dovrò caricare una raccolta di oggetti potenzialmente ampia per aggiungi solo un elemento. Dal punto di vista della progettazione del dominio, non ha senso per me avere entrambe le entità riferimento all'altra nei loro campi, poiché nessun comportamento richiede la presenza di una raccolta di elementi o utenti.

Ho bisogno di mantenere questa relazione come l'interfaccia utente deve visualizzare un elenco di elementi che un utente è piaciuto e un elenco di utenti che è piaciuto un elemento. Il requisito può essere fornito da un modello di lettura, ma ho ancora bisogno di un concetto di dominio per acquisire questa relazione in modo che possa essere mantenuta.

Un modo che posso venire è quello di introdurre un tipo di relazione di aggregato, ad esempio UserLikeItem, e avere il metodo user.like (item) restituire un'istanza di UserLikeItem che posso quindi utilizzare UserLikeItemRepository per persistere.

È una soluzione valida? Qual è il modo naturale in DDD per modellare questo tipo di relazioni grandi ma non comportamentali?

+0

Mi piace (gioco di parole!) La soluzione, anche se non deve essere un metodo su IMO utente. Permette anche di acquisire informazioni aggiuntive come il tempo in cui l'oggetto è stato apprezzato, in quale contesto, ecc. Lo stesso AR può essere usato anche per il contrario, ma forse è necessario trovare un nome migliore per esso. – guillaume31

+0

Sono d'accordo, l'unica cosa che probabilmente aggiungerei è un 'LikeCounter' per l'oggetto, in modo da poter visualizzare il totale come il conteggio di un oggetto senza dover colpire l'origine dati' UseLikeItem'. –

+0

Un oggetto di transazione o un evento di dominio "UserLikedItem" sembra appropriato con quel poco che ci hai dato per andare avanti. –

risposta

0

Farò uno scavo a questo :), IMO se non ha un comportamento non vive nel "modello di dominio", e se una vasta maggioranza dei tuoi concetti non ha un comportamento allora non hai bisogno di un " modello di dominio ", dovresti probabilmente considerare un tipo di pattern transaction script piuttosto che un modello di dominio.

Vorrei parafrasare la tua domanda a "come faccio a mantenere molte più relazioni in modo performante" a questa domanda abbiamo più risposte, una è quella che hai menzionato l'altra potrebbe essere solo memorizzare l'elenco di id all'interno del classi.

Il modello di dominio e una rappresentazione orientata agli oggetti del backend di persistenza sono due cose distinte, il modello di dominio è innanzitutto il comportamento, quindi si pensa al comportamento e quindi si aggiungono le proprietà nel modello di dominio che sarà interessato da tale comportamento, altrimenti quello che ti serve è una "rappresentazione orientata agli oggetti del tuo backend di persistenza" (DTO)

Ma diventa complicato quando si ha il caso di un modello di dominio, ma solo un paio di concetti sono anemici e mancano di un comportamento ma questo è un domanda per un altro giorno :)

+1

Non sono d'accordo con "se non ha un comportamento non vive nel" modello di dominio "". Tutto ciò che ha un significato/un dominio definisce un concetto di dominio fa parte del dominio, indipendentemente se ha un comportamento o è una struttura di dati. – MikeSW

0

"Mi piace" è un dominio, che può essere rappresentato dall'entità.
Gli articoli hanno Mi piace -> L'oggetto contiene raccolta di Mi piace.
Questa raccolta è necessaria solo per l'aggiunta e l'eliminazione di Mi piace -> L'elemento ha una proprietà LikeCount e la raccolta di Mi piace è facoltativa per la query del repository (utilizzata solo nei metodi Item.AddLikeFrom (utente) e Item.RemoveLikeFrom (utente)).

Può sembrare, quella relazione non è comportamentale, ma in realtà è il comportamento di uno dei lati della relazione.

2

Da quando mi sono imbattuto in questo scenario qualche tempo fa, ecco la mia versione. Utente e L'articolo fa parte di diversi aggregati che non conoscono/si preoccupano l'un l'altro (anche se un elemento ha un ID utente). Un "sistema simile" (LS) è un inseguimento di inseguimento diverso diverso da che a che cosa.

Anche a LS non interessa molto l'utente o l'elemento, anche se non vedo un caso in cui qualcos'altro diverso da un utente possa piacere qualcosa, posso dire che Like implicherà sempre un ID utente (non il intero concetto di utente) e un soggetto (oggetto, VIdeo, immagine, posta ecc.).

LS mantiene semplicemente un'associazione di ID utente e un altro itemId di un determinato tipo (che può essere una stringa, se si desidera che LS non sia accoppiato a ciò che è un articolo). Ogni volta che un utente gradisce qualcosa viene emesso un comando: RegisterLikeForItem {UserId, ItemId, ItemType}. Un gestore LS memorizzerà tali informazioni e pubblicherà un evento UserLikedItem. Uno dei suoi gestori sarà un contatore che conterà quanti utenti hanno apprezzato quell'elemento. Un altro gestore può fare un elenco di quali elementi sono stati piaciuti da un utente (questo verrà interrogato dall'interfaccia utente).

Ogni handler serve un caso d'uso e probabilmente ognuno ha il proprio spazio di archiviazione. So che sembra piuttosto complicato, ma in realtà è semplice (un caso d'uso richiede un gestore e forse un deposito) e le scommesse di tutti, è molto flessibile e mantenibile. E il sistema funziona con uno o 1000 tipi di elementi.