Come decidere se implementare un'operazione come operazione Entità o operazione di servizio in Progettazione guidata dal dominio?

7

Sto leggendo il Domain Driven Design di Evans. Il libro dice che ci sono entità e ci sono servizi. Se dovessi implementare un'operazione, come decidere se aggiungerla come metodo su un'entità o farlo in una classe di servizio?

es. myEntity.DoStuff() o myService.DoStuffOn(myEntity) ?

Dipende dal fatto che siano coinvolte altre entità? Se coinvolge altre entità, implementare come operazione di servizio? Ma le entità possono avere associazioni e possono attraversarlo da lì anche a destra?

Dipende da apolidi o no? Ma il servizio può anche accedere alla variabile delle entità, giusto? Come nel mio materiale myService.DoStuffOn, può avere un codice come

if(myEntity.IsX) doSomething();

Il che significa che dipenderà dallo stato?

O dipende dalla complessità? Come definisci le operazioni complesse?

    
posta Louis Rhys 03.04.2012 - 10:17
fonte

4 risposte

2

Does it depend on whether other entities are involved? If it involves other entities, implement as service operation?

Questa è una buona regola empirica. Un altro: la logica che descrive un fatto fondamentale sull'entità ed è usata in più casi d'uso probabilmente appartiene all'entità. La logica che è specifica per caso d'uso probabilmente no. Entrambe sono varianti del principio di responsabilità singola.

But entities can have associations and can traverse it from there too right?

Sì, ma le entità non dovrebbero essere strettamente accoppiate in questo modo. Tranne forse nei casi in cui un'entità "contiene" un'altra e sono già strettamente concettualizzate.

Or does it depend on complexity? How do you define complex operations?

Questa è solo una regola di base della pulizia del codice: se un pezzo di codice diventa troppo grande e complesso, suddividilo. Se hai un'operazione come parte di un entitry che contiene più codice rispetto al resto dell'entità e hai già dovuto refactoring in sotto-operazioni, dovresti pensare di spostarlo completamente dall'entità.

    
risposta data 03.04.2012 - 10:31
fonte
2

Per quanto mi riguarda, cerco sempre di aggiungere un'operazione in un'entità prima di prendere in considerazione l'utilizzo di un servizio, perché è il posto naturale in cui ti troverai se l'operazione è strettamente correlata all'entità.

Solo perché un metodo coinvolge diverse entità non significa che non possa essere inserito in una di esse. In particolare, le invarianti e le regole aziendali che si estendono su diverse Entità di Aggregate sono spesso implementate nella radice di aggregazione.

Uso un servizio solo se l'operazione non sembra appartenere a nessuna delle entità esistenti. Un buon esempio di questo è il metodo TransferFunds (). Dovrebbe essere un metodo dell'account sorgente? Significherebbe che l'account sorgente può alterare il saldo dell'account di destinazione, il che sembra un po 'strano. Stessa cosa con l'account di destinazione.

Quindi questo è un caso perfetto per un FundsTransferService con il seguente metodo:

public void TransferFunds(Account source, Account destination, decimal amount)

Non dovrebbe accadere tutto questo spesso però.

Inoltre, tieni presente che non è solo un mondo di Entità contro Servizi. Hai un sacco di altri oggetti per mettere le tue operazioni in - Fabbriche, Norme, Specifiche, ecc.

    
risposta data 03.05.2012 - 14:31
fonte
1

Scegli la più intuitiva / semplice per la situazione corrispondente.

Per illustrare questo più chiaramente, lasciami scegliere nomi più specifici di "myEntity" e "DoStuff"

   myService.process(myData) // fits perfectly.

   myStatefulThingy.reset() // fits perfectly.

Nel primo caso, myData/myEntity è semplicemente alcuni dati passati a un servizio. Nella seconda, è un'operazione autonoma.

Raccomando che nel primo caso, myData/myEntity non venga alterato mentre nel secondo caso myStatefulThingy/myEntity è l'unica cosa che viene modificata.

    
risposta data 03.04.2012 - 10:35
fonte
1

Dopo questo ottimo articolo di Martin Fowler dovresti tenere la tua Business Logic nelle tue Entità e nel tuo Service Layer magro. Non penso sia una questione di complessità. Se sono coinvolte altre entità (non entità "di proprietà"), consiglierei di utilizzare il livello di servizio per la delega a Business Logic in altre entità.

Dovresti leggere questo articolo! Martin Fowler fa riferimento al libro che stai leggendo in merito al tuo problema.

    
risposta data 03.04.2012 - 10:39
fonte