2013-07-19 12 views
5

In Domain Driven Design, i servizi di dominio devono contenere operazioni che non appartengono naturalmente a un'entità.Servizi di dominio DDD: cosa deve contenere una classe di servizio?

ho avuto l'abitudine di creare un servizio per entità e di gruppo alcuni metodi al suo interno (Organization entità e OrganizationService servizio).

Ma più ci penso: OrganizationService non significa nulla, "Organizzazione" è non un servizio, è una cosa.

Quindi adesso devo aggiungere una funzionalità di copia in profondità dell'organizzazione che duplicherà un intero aggregato dell'organizzazione, quindi voglio inserirlo in un servizio.

Devo fare: OrganizationService::copyOrganization(o)?

Oppure devo fare: OrganizationCopyService::copyOrganization(o)?

Più in generale: è un "servizio" un concetto astratto contenente diverse operazioni o è un servizio un'operazione concreta?

Modifica: più esempi riportati il ​​primo non era buona:

  • StrategyService::apply()/cancel() o StrategyApplicationService::apply()/cancel()? ("Applicazione" qui non è correlata al livello applicazione;)
  • CarService::wash() o CarWashingService::wash()?

In tutti questi esempi il nome del servizio più specifico sembra il più appropriato. Dopotutto, nella vita reale, il "servizio di lavaggio auto" è qualcosa che ha senso. Ma potrei finire con un sacco di servizi ...

* Nota: questa non è una domanda sulle opinioni! Questa è una domanda precisa e rispondente sulla metodologia di Domain Driven Design. Sono sempre stanco di voti ravvicinati quando chiedo "dovrei", ma è un modo DDD di fare le cose. *

+0

Perché l'organizzazione viene clonata? La risposta a questa domanda potrebbe rivelare un po 'di più su ciò che il servizio sta effettivamente fornendo. In realtà non voglio sapere - sto solo cercando di elevare il tuo processo di pensiero nel dominio ... – MattDavey

+0

@MattDavey Vedo cosa intendi. Ma temo sia così semplice: l'utente vuole "copiare"/"duplicare" un'organizzazione esistente perché vuole crearne una nuova che assomigli molto alla precedente. Apprezzo i tuoi pensieri su questo però :) –

+0

* "l'utente vuole" copiare "/" duplicare un esistente ... "* - Sembra che l'utente abbia dato una soluzione da implementare piuttosto che un problema da risolvere! il vero problema è che creare nuove organizzazioni da zero richiede troppo tempo?Nel qual caso offri un servizio che velocizza questo processo? – MattDavey

risposta

4

Penso che sia un bene se un servizio di dominio ha solo un metodo. Ma non penso che sia una regola come se tu non dovessi avere più di un metodo su un servizio di dominio o qualcosa del genere. Se l'interfaccia astrae solo una cosa o un comportamento, è certamente facile da maitain ma la granularità del servizio di dominio dipende totalmente dal tuo contesto limitato. A volte ci concentriamo troppo sull'accoppiamento basso e trascuriamo l'alta coesione.

+2

+1 questo è quello che cercavo di suggerire nei miei commenti. Un buon servizio di dominio può astrarre più di un comportamento, ma dovrebbero solo astrarre un * problema *. – MattDavey

1

Questo è un po 'di opinione basata Volevo aggiungerlo come commento ma spazio esaurito .

I credo in che in questo caso avrà senso raggruppare i metodi in un servizio OrganizationFactory separato con un metodo di costruzione diverso.

interface OrganizationFactory{ 
     Organization createOrganization(); 
     Organization createOrganizationCopy(Organization organization); 
    } 

suppongo che sarà in accordo con esperto informazioni modello e DRY principio - una classe ha tutte le informazioni sulla creazione oggetto specifico e non vedo alcun motivo per ripetere questa logica in diversi posti.

Tuttavia, una cosa interessante è che in definizione ddd del modello di fabbrica

spostare la responsabilità per la creazione di istanze di oggetti complessi e AGGREGATI ad un oggetto separato, che può esso stesso avere alcuna responsabilità nel dominio modello ma fa ancora parte del dominio design. Fornire un'interfaccia che incapsula tutto l'assemblaggio complesso e che non richiede che il client faccia riferimento alle classi di calcestruzzo degli oggetti da istanziare.

la parola "oggetto" è in senso generico, non ha nemmeno bisogno di essere un separato classe, ma può anche essere un metodo factory (intendo sia il metodo di una classe e il metodo fabbrica modello) - in seguito Evans fornisce un esempio del metodo factory di Brokerage Account che crea istanze di Trade Order.

Il libro fa riferimento alla famiglia di modelli di fabbrica GoF e non penso che ci sia un modo speciale di decomposizione della fabbrica DDD - i punti principali sono che l'oggetto creato non è cotto a metà e che il metodo di fabbrica dovrebbe aggiungere come poche dipendenze possibili.

aggiornamento DDD non è collegata a un particolare paradigma di programmazione, mentre la domanda riguarda orientato agli oggetti decomposizione, in modo nuovo non sembra che DDD può fornire eventuali raccomandazioni speciali sul numero di metodi per oggetto .

Alcuni utenti usano strange rules of thumb, ma credo che si possa andare semplicemente con High Cohesion principle e mettere insieme i metodi con responsabilità altamente correlate. Poiché si tratta di una domanda DDD, suppongo che riguardi i servizi di dominio (ad esempio, non i servizi di infrastruttura). Suppongo che i servizi dovrebbero essere divisi in base alle loro responsabilità nel dominio.

aggiornamento 2 Comunque CarService può fare CarService::wash()/CarService::repaint()/CarService::diagnoseAirConditioningProblems() ma sarà strano che CarWashingService farà CarWashingService::diagnoseAirConditioningProblems() è come nella grammatica generativa di Chomsky - alcune dichiarazioni (frasi) nella lingua ha senso, alcuni non lo fanno. Ma se la tua frase contiene troppi argomenti (più che dire 5-7) sarà anche difficile da capire, anche se è una frase valida nella lingua.

+0

Sono d'accordo con ogni punto che fai, e realizzo che il mio esempio non era buono. La mia domanda era più generica: una classe di servizio dovrebbe realizzare solo un'operazione, o è giusto che una classe di servizio aggreghi diverse operazioni. Nuovo esempio: 'StrategyService :: apply()/cancel()' o 'StrategyApplicationService :: apply()/cancel()'? Oppure 'CarService :: wash()' o 'CarWashingService :: wash()'? –

+0

Il numero di oggetti è una cosa molto sottile - C. Alexander in pattern 'Small parking lots 'ha citato qualche altro studio che ha dimostrato che gli oggetti in una collezione di 5-7 elementi (ma non più) possono ancora essere afferrati come individui, quindi tu non è necessario limitare tutto a un metodo per classe. :-) –

+0

Ho aggiornato il titolo della mia domanda: per non parlare del numero di metodi, che cos'è un servizio? È un'azione, come la parola "servizio" nel mondo reale? O è un concetto/nome astratto che aggrega le azioni? vedere i miei esempi nel commento precedente –

Problemi correlati