Con tutti questi servizi, come posso non essere anemico?


90

Dove tracciamo il confine tra delega e incapsulamento della logica aziendale? Mi sembra che più deleghiamo, più diventiamo anemici . Tuttavia, la delegazione promuove anche il riutilizzo e il principio DRY. Quindi, cosa è appropriato delegare e cosa dovrebbe rimanere nei nostri modelli di dominio?

Prendi le seguenti preoccupazioni come esempi:

Autorizzazione . L'oggetto dominio dovrebbe essere responsabile del mantenimento delle regole di controllo dell'accesso (come una proprietà CanEdit) o ​​dovrebbe essere delegato a un altro componente / servizio l'unico responsabile della gestione dell'accesso, ad esempio IAuthorizationService.CanEdit (oggetto)? O dovrebbe essere una combinazione dei due? Forse l'oggetto del dominio ha una proprietà CanEdit che delega a un IAuthorizationService interno per eseguire il lavoro effettivo?

Convalida . La stessa discussione di cui sopra si riferisce alla convalida. Chi mantiene le regole e chi è responsabile della loro valutazione? Da un lato, lo stato dell'oggetto dovrebbe appartenere a quell'oggetto e la validità è uno stato, ma non vogliamo riscrivere il codice utilizzato per valutare le regole per ogni oggetto di dominio. Abbiamo potuto utilizzare l'ereditarietà in questo caso ...

Creazione di oggetti . Classe di fabbrica rispetto ai metodi di fabbrica rispetto alla "novità" di un'istanza. Se utilizziamo una classe factory separata, siamo in grado di isolare e incapsulare la logica di creazione, ma a spese dell'apertura dello stato del nostro oggetto alla factory. Questo può essere gestito se il nostro livello di dominio si trova in un assembly separato esponendo un costruttore interno utilizzato dalla fabbrica, ma ciò diventa un problema se esistono più modelli di creazione. E, se tutto ciò che la fabbrica sta facendo è chiamare il costruttore giusto, che senso ha avere la fabbrica?

I metodi factory sulla classe eliminano il problema con l'apertura dello stato interno dell'oggetto, ma poiché sono statici, non siamo in grado di rompere le dipendenze attraverso l'iniezione di un'interfaccia factory come possiamo con una classe factory separata.

Persistenza . Si potrebbe sostenere che se il nostro oggetto di dominio sta per esporre CanEdit mentre delega la responsabilità di eseguire il controllo di autorizzazione a un'altra parte (IAuthorizationService) perché non avere un metodo Save sul nostro oggetto di dominio che fa la stessa cosa? Ciò ci consentirebbe di valutare lo stato interno dell'oggetto per determinare se l'operazione può essere eseguita senza interrompere l'incapsulamento. Ovviamente è necessario che iniettiamo l'istanza del repository nel nostro oggetto dominio, il che ha un odore un po 'per me, quindi generiamo un evento di dominio e consentiamo a un gestore di eseguire l'operazione di persistenza?

Vedi dove sto andando con questo?

Rockford Lhotka ha una grande discussione sulle sue ragioni per seguire la rotta Class-in-Charge per il suo framework CSLA e io ho un po 'di storia con quel framework e posso vedere la sua idea di oggetti business in parallelo a oggetti di dominio in molti modi. Ma cercando di diventare più aderente ai buoni ideali di DDD, mi chiedo quando la collaborazione diventa troppo.

Se finisco con un IAuthorizationService, IValidator, IFactory e IRepository per la mia radice aggregata, cosa rimane? Avere un metodo di pubblicazione che modifica lo stato dell'oggetto da Bozza a Pubblicato è abbastanza per considerare la classe un oggetto di dominio non anemico?

I vostri pensieri?


Ottima domanda Non ho una risposta per te dato che quasi sempre finisco per essere completamente anemico nel design per lo stesso identico motivo: usare / consumare / esporre servizi da / verso molti contesti o applicazioni diverse.
hromanko,

Grande domanda, mi piacerebbe vedere zio, martinfowler, ericevans et al. Ora per me andare via e pensare a lungo
Martijn Verburg,

Mi trovo sempre evolvendo in un modello anemico; e quindi sto lottando con questa stessa identica cosa. Ottima domanda!
L-Four,

Questa è stata anche la mia esperienza con DDD. Lo stiamo facendo dove lavoro e finiamo sempre per essere anemici. In precedenza (e ancora effettivamente) uso Csla. Al nostro architetto non piace che siamo anemici, ma non è stato in grado di darmi una buona risposta a cosa dovrebbe fare l'oggetto se tutte le cose che fai notare non possono essere fatte all'interno dell'oggetto. Alla fine, cercare di essere purista DDD sembra creare più lavoro di quanto valga la pena. Personalmente penso che Csla e DDD vadano d'accordo (sembrano identici in principio), se sei disposto a lasciarti alle spalle il dogma DDD.
Andy,

Ecco un esempio di alcune tecniche utilizzate per modellare il dominio dalla prospettiva comportamentale (non incentrata sui dati): medium.com/@wrong.about/…
Zapadlo,

Risposte:


66

La maggior parte della confusione sembra riguardare funzionalità che non dovrebbero esistere nel modello di dominio:

  • La persistenza non dovrebbe mai essere nel modello di dominio. Mai e poi mai. Questo è il motivo per cui ti affidi a tipi astratti come IRepositoryse una parte del modello dovesse mai fare qualcosa come recuperare una parte diversa del modello e usare l'iniezione di dipendenza o qualche tecnica simile per collegare l'implementazione. Quindi colpiscilo dal disco.

  • L'autorizzazione non fa generalmente parte del tuo modello di dominio, a meno che non sia effettivamente parte del dominio, ad esempio se stai scrivendo un software di sicurezza. I meccanici di chi è autorizzato a eseguire ciò che in un'applicazione sono normalmente gestiti ai margini del livello aziendale / di dominio, le parti pubbliche con cui l'interfaccia utente e i pezzi di integrazione sono effettivamente autorizzati a parlare: il Controller in MVC, i Servizi o il sistema di messaggistica stesso in una SOA ... ottieni l'immagine.

  • Le fabbriche (e presumo che tu intenda fabbriche astratte qui) non sono esattamente cattive da avere in un modello di dominio ma sono quasi sempre inutili. Normalmente hai una fabbrica solo quando la meccanica interna della creazione degli oggetti potrebbe cambiare. Ma hai solo un'implementazione del modello di dominio, il che significa che ci sarà sempre un solo tipo di factory che invoca sempre gli stessi costruttori e altro codice di inizializzazione.

    Puoi avere fabbriche di "convenienza" se vuoi - classi che incapsulano combinazioni comuni di parametri del costruttore e così via - ma onestamente, in generale, se hai molte fabbriche sedute nel tuo modello di dominio, stai solo sprecando linee di codice.

Quindi, una volta che hai raccolto tutti quelli, questo lascia solo la convalida. È l'unico che è un po 'complicato.

La convalida fa parte del modello di dominio, ma fa anche parte di ogni altro componente dell'applicazione. L'interfaccia utente e il database avranno le proprie regole di convalida, simili ma diverse, basate su un modello concettuale simile ma diverso. Non è davvero specificato se gli oggetti debbano avere un Validatemetodo o meno , ma anche se lo fanno, di solito lo delegheranno a una classe di validazione (non interfaccia - la validazione non è astratta nel modello di dominio, è fondamentale).

Tieni presente che il validatore è ancora tecnicamente parte del modello; non deve essere collegato a una radice aggregata perché non contiene alcun dato o stato. I modelli di dominio sono cose concettuali, che di solito si traducono fisicamente in un assembly o in una raccolta di assembly. Non preoccuparti del problema "anemico" se il tuo codice di delega risiede in stretta vicinanza al modello a oggetti; conta ancora.

Che tutto questo in realtà si riduce a è che se avete intenzione di fare DDD, bisogna capire che cosa il dominio è . Se stai ancora parlando di cose come la persistenza e l'autorizzazione, allora sei sulla strada sbagliata. Il dominio rappresenta lo stato in esecuzione di un sistema: gli oggetti e gli attributi fisici e concettuali. Tutto ciò che non è direttamente rilevante per gli oggetti e le relazioni stesse non appartiene al modello di dominio, punto.

Come regola generale, quando si considera se qualcosa appartiene al modello di dominio, porsi la seguente domanda:

"Questa funzionalità può mai cambiare per motivi puramente tecnici?" In altre parole, non a causa di cambiamenti osservabili nel mondo degli affari o nel dominio?

Se la risposta è "sì", non appartiene al modello di dominio. Non fa parte del dominio.

È molto probabile che, un giorno, cambierai la tua persistenza e le tue infrastrutture di autorizzazione. Pertanto, non fanno parte del dominio, fanno parte dell'applicazione. Questo vale anche per gli algoritmi, come l'ordinamento e la ricerca; non dovresti andare a inserire un'implementazione binaria del codice di ricerca nel tuo modello di dominio, perché il tuo dominio riguarda solo il concetto astratto di ricerca, non come funziona.

Se, dopo aver rimosso tutte le cose che non contano, scopri che il modello di dominio è veramente anemico , allora ciò dovrebbe servire da una buona indicazione del fatto che DDD è semplicemente il paradigma sbagliato per il tuo progetto.

Alcuni domini sono davvero anemici. Le app di social bookmarking non hanno davvero molto di un "dominio" di cui parlare; tutti i tuoi oggetti sono fondamentalmente solo dati senza funzionalità. Un sistema di vendita e CRM, invece, ha un dominio piuttosto pesante; quando carichi Rateun'entità, c'è una ragionevole aspettativa che tu possa effettivamente fare cose con quella tariffa, come applicarla a una quantità di ordine e fargli capire gli sconti sul volume, i codici promozionali e tutte quelle cose divertenti.

Oggetti di dominio che basta tenere i dati di solito non significa che si dispone di un modello di dominio anemico, ma che non necessariamente significa che hai creato una cattiva progettazione - si potrebbe dire solo che il dominio stesso è anemica e che si dovrebbe utilizzare un metodologia diversa.


2
Inoltre, @SonOfPirate, non è del tutto improbabile che tu voglia cambiare l'intero modello di sicurezza un giorno; la sicurezza basata sui ruoli è spesso obsoleta a favore della sicurezza basata sui reclami o sui diritti o forse si desidera persino la sicurezza a livello di campo. Immagina di provare a rielaborare l'intero modello di dominio in questo caso.
Aaronaught,

1
@SonOfPirate: Sembra quasi che tu sia ancora un po 'bloccato sul vecchio modello di "livello aziendale" in cui c'era un "livello intermedio" che era fondamentalmente un'impiallacciatura sottile sul livello dati, implementando varie regole aziendali e di solito anche regole di sicurezza . Non è questo il livello del dominio. Il dominio è ciò da cui tutto il resto dipende, rappresenta gli oggetti e le relazioni del mondo reale che il sistema è destinato a gestire.
Aaronaught,

1
@ LaurentBourgault-Roy: Scusa, non ti credo. Ogni azienda potrebbe dire questo su ogni applicazione; dopo tutto, cambiare un database è difficile. Ciò non lo rende parte del tuo dominio e la logica aziendale accoppiata al livello di persistenza significa solo scarsa astrazione. Un modello di dominio è focalizzato sul comportamento, che è esattamente ciò che la persistenza non è . Questo non è un argomento su cui le persone possono inventare le proprie definizioni; è abbastanza chiaramente spiegato in DDD. Spesso non hai bisogno di un modello di dominio per CRUD o per le app di report, ma non dovresti pretendere di averne uno quando non lo fai.
Aaronaught il

1
L'autorizzazione appartiene assolutamente al livello del dominio. Chi decide quali autorizzazioni esistono? Il business fa. Chi decide chi può fare cosa? Il business fa. Abbiamo appena ricevuto una richiesta di funzionalità alcune settimane fa per modificare l'autorizzazione necessaria per modificare un determinato oggetto nel nostro sistema. Se un modello era basato su un modello principale, erano necessari privilegi più elevati per modificare (sovrascrivere i valori dal modello principale) del modello normalmente necessario. Dove appartiene quella logica se non nel dominio?
Andy,

1
Un altro tipo di autorizzazione potrebbe essere un limite di account cliente. Le persone normali del servizio clienti possono elevarlo fino a un certo punto, ma forse limiti più alti richiedono l'approvazione della direzione. Questa è la logica di autorizzazione.
Andy,

6

Autorizzazione. L'oggetto dominio deve essere responsabile del mantenimento delle regole di controllo dell'accesso

No. L'autorizzazione è una preoccupazione in sé. I comandi che non sarebbero validi a causa della mancanza di autorizzazioni dovrebbero essere respinti prima del dominio, il che significa che spesso vorremmo anche controllare l'autorizzazione di un potenziale comando per costruire l'interfaccia utente (in modo da non mostra anche all'utente la possibilità di modificare).

La condivisione delle strategie di autorizzazione tra i livelli (nell'interfaccia utente e più avanti in un gestore di servizi o comandi) è più semplice quando l'autorizzazione è strutturata separatamente dal modello di dominio.

Una parte difficile che può essere incontrata è l'autorizzazione contestuale, in cui un comando può o non può essere consentito non solo in base ai ruoli dell'utente, ma anche ai dati / regole aziendali.

Convalida. La stessa discussione di cui sopra si riferisce alla convalida.

Vorrei anche dire di no, non nel dominio (principalmente). La convalida si verifica in contesti diversi e le regole di convalida spesso differiscono tra contesti. Raramente esiste un senso semplice, assoluto di valido o non valido quando si considerano i dati incapsulati da un aggregato.

Inoltre, come l'autorizzazione, utilizziamo la logica di convalida su più livelli: nell'interfaccia utente, nel servizio o nel gestore dei comandi, ecc. Ancora una volta, è più semplice utilizzare DRY con convalida se si tratta di un componente separato. Da un punto di vista pratico, la convalida (in particolare quando si usano i framework) richiede l'esposizione di dati che altrimenti dovrebbero essere incapsulati e spesso richiede l'attribuzione di attributi personalizzati a campi e proprietà. Preferisco di gran lunga che questi siano su classi diverse dai miei modelli di dominio.

Preferirei duplicare alcune proprietà in un paio di classi simili piuttosto che cercare di forzare i requisiti per un framework di validazione nelle mie entità. Ciò finisce inevitabilmente per creare confusione nelle classi di entità.

Creazione di oggetti. Classe di fabbrica rispetto ai metodi di fabbrica rispetto alla "novità" di un'istanza.

Uso uno strato di indiretta. Nei miei progetti più recenti, questo è un comando + gestore per creare qualcosa, ad es CreateNewAccountCommand. Un'alternativa potrebbe essere quella di utilizzare sempre una fabbrica (sebbene ciò possa essere imbarazzante se il resto di un'operazione di entità è esposto da una classe di servizio che è separata dalla classe di fabbrica).

In generale, tuttavia, cerco di essere più flessibile con le scelte progettuali per la creazione di oggetti. newè facile e familiare ma non sempre sufficiente. Penso che sia importante usare il giudizio qui e consentire a diverse parti di un sistema di usare strategie diverse secondo necessità.

Persistenza. ... perché non avere un metodo Save sul nostro oggetto dominio

Questa è raramente una buona idea; Penso che ci sia molta esperienza condivisa a supporto di ciò.

Se finisco con un IAuthorizationService, IValidator, IFactory e IRepository per la mia radice aggregata, cosa rimane? Avere un metodo di pubblicazione che modifica lo stato dell'oggetto da Bozza a Pubblicato abbastanza da considerare la classe un oggetto di dominio non anemico ???

Forse un modello di dominio non è la scelta corretta per questa parte dell'applicazione.


2
"Una parte difficile che può essere incontrata è l'autorizzazione contestuale, in cui un comando può o non può essere autorizzato non solo in base ai ruoli dell'utente, ma anche ai dati / alle regole aziendali." - E come ti avvicini a questo? Più volte, almeno per me, le nostre regole di autorizzazione sono una combinazione di ruolo e stato attuale.
SonOfPirate,

@SonOfPirate: gestori di eventi che ascoltano eventi di dominio e aggiornano tabelle molto specifiche per le esigenze delle query che controllano l'autorizzazione. Logica che controlla lo stato e determina se un ruolo o un individuo è autorizzato o meno nel gestore dell'evento (quindi le tabelle sono quasi sempre un semplice sì / no, rendendo l'autenticazione una semplice ricerca). Inoltre, non appena una di queste logiche viene utilizzata in più di un luogo, viene rifattorizzata dal gestore e in un servizio condiviso.
Quentin-starin,

1
In generale, negli ultimi anni, mi sono spostato sempre più lontano dal tentativo di consolidare tutto in un dominio o in un oggetto business. La mia esperienza sembra essere che rendere le cose più granulari e meno accoppiate sia una vittoria a lungo termine. Quindi, sebbene da un punto di vista questo metodo collochi la logica di business al di fuori del dominio (in una certa misura), supporta anche modifiche agili in seguito. Si tratta di trovare un equilibrio.
Quentin-starin,

4
Facendo riferimento alla risposta stessa qui: ho trovato il modello di stato molto utile quando si tratta di convalide che dipendono sia dalle autorizzazioni che dalle regole aziendali. Crea uno stato astratto che viene iniettato nel modello di dominio ed espone metodi che prendono l'oggetto dominio come parametro e convalidano le azioni specifiche del dominio. In questo modo se le tue regole di autorizzazione cambiano (come quasi sempre fanno), non devi mai pasticciare con il modello per adattarlo, perché le implementazioni dello stato vivono nel tuo componente di sicurezza.
Aaronaught,

1
Rimanendo in tema di autorizzazione, lasciami fare un esempio tangibile sul tavolo per vedere come (entrambi) lo gestiresti. Ho un'operazione di pubblicazione sul mio oggetto dominio che richiede che l'utente abbia il ruolo di editore e che l'oggetto sia in un determinato stato. Voglio nascondere o disabilitare il "pulsante" Pubblica nell'interfaccia utente. Come lo faresti?
SonOfPirate,

4

OK, ecco per me. Prevederò questo dicendo che:

  • L'ottimizzazione precoce (e che include la progettazione) può spesso causare problemi.

  • IANMF (non sono Martin Fowler);)

  • Un piccolo segreto sporco è che su progetti di piccole dimensioni (anche discutibilmente di medie dimensioni), è la coerenza del tuo approccio che conta.

Autorizzazione

Per me l'autenticazione e l'autorizzazione sono sempre una preoccupazione trasversale. Nel mio felice piccolo mondo Java, questo viene delegato alla sicurezza di Spring o al framework Apache Shiro.

Convalida Per me la convalida fa parte dell'oggetto, in quanto la vedo come definizione dell'oggetto.

ad es. un oggetto Car ha 4 ruote (OK ci sono alcune strane eccezioni, ma per ora ignoriamo la strana Car a 3 ruote). Un'auto semplicemente non è valida a meno che non ne abbia 4 (nel mio mondo), quindi la convalida fa parte della definizione di un'auto. Ciò non significa che non puoi avere classi di validazione helper.

Nel mio felice mondo Java utilizzo i framework di validazione Bean e utilizzo semplici annotazioni sulla maggior parte dei miei campi Bean. È facile quindi convalidare il tuo oggetto, indipendentemente dal livello in cui ti trovi.

Creazione di oggetti

Vedo le lezioni di fabbrica con cautela. Troppo spesso ho visto la xyxFactoryFactoryclasse;)

Tendo a creare un newoggetto secondo necessità, fino a quando non incappo in un caso in cui l'iniezione di dipendenza è giustificata (e dal momento che provo a seguire un approccio TDD, questo si presenta più spesso).

Nel mio felice mondo Java che è sempre più Guice, ma di Spring è ancora il re qui.

Persistenza

Quindi questo è un dibattito che si svolge in circoli e rotonde e io ho sempre due menti a riguardo.

Alcuni sostengono che se si guarda all'oggetto in modo "puro", la persistenza non è una proprietà fondamentale, è solo una preoccupazione esterna.

Altri ritengono che i tuoi oggetti di dominio implementino implicitamente un'interfaccia 'persistente' (sì, lo so che sto allungando qui). Pertanto, va bene avere i vari metodi save, deleteecc. Su di essi. Questo è visto come un approccio pragmatico e molte tecnologie ORM (JPA nel mio felice mondo Java) gestiscono gli oggetti in questo modo.

Per motivi di sicurezza trasversali, mi assicuro che le autorizzazioni di modifica / eliminazione / aggiunta / qualunque siano impostate correttamente sul servizio che chiama il metodo save / update / delete sull'oggetto. Se sono davvero paranoico, potrei anche impostare le autorizzazioni sull'oggetto dominio stesso.

HTH!


2

Jimmy Nilsson tocca questo argomento nel suo libro su DDD. Ha iniziato con un modello anemico, è passato a modelli non anemici in un progetto successivo e alla fine ha optato per modelli anemici. Il suo ragionamento era che i modelli anemici potevano essere riutilizzati in più servizi con una diversa logica aziendale.

Il compromesso è la mancanza di capacità di scoprire. I metodi che puoi utilizzare per operare sui tuoi modelli anemici sono distribuiti in una serie di servizi situati altrove.


Sembra un requisito specifico - il riutilizzo della struttura dei dati (stress "dati") - porta a quella parte comune ridotta a semplici DTO.
Victor Sergienko,

I modelli anemici consentono un migliore riutilizzo? Sembra più un DTO, e personalmente non me ne frega niente di riutilizzare le definizioni delle proprietà. Preferirei piuttosto riutilizzare i comportamenti.
Andy,

@Andy - Concordo tuttavia se i tuoi comportamenti sono all'interno dei Servizi di dominio e operano su oggetti anemici (va bene DTO se lo desideri), quindi non aumenta il riutilizzo di tali comportamenti? Sto solo giocando l'avvocato del diavolo.
jpierson,

@jpierson Ho scoperto che i comportamenti sono in genere specifici di un caso d'uso particolare. Se c'è un riutilizzo, questo appartiene a un'altra classe, ma il consumatore non userebbe quelle classi, userebbero quelle specifiche per il caso d'uso. Quindi ogni riutilizzo è "dietro le quinte", per così dire. Inoltre, il tentativo di riutilizzare i modelli in genere rende i modelli più difficili da utilizzare per il consumatore, quindi si finisce per creare modelli di visualizzazione / modifica nel livello dell'interfaccia utente. Spesso si finisce per violare DRY per offrire un'esperienza utente più ricca (ad esempio, DataAnotations di modelli di modifica).
Andy,

1
Preferirei i moduli di dominio creati per il caso d'uso, riutilizzati dove ha senso (vale a dire, il riutilizzo può essere fatto senza modificare il comportamento molto o per niente). Quindi, invece del modello di dominio anemico, della classe di servizio e del modello di modifica, hai un unico modello di dominio modificabile intelligente. Ho trovato molto più facile da usare e mantenere.
Andy,

2

Questa domanda è stata posta molto tempo fa, ma è contrassegnata con Domain Driven Design. Penso che la domanda stessa contenga un fraintendimento fondamentale dell'intera pratica e che le risposte, compresa la risposta accettata, perpetuino un malinteso fondamentale.

Non esiste un "modello di dominio" in un'architettura DDD.

Prendiamo l'autorizzazione come esempio. Lascia che ti chieda di pensare a una domanda: immagina che due utenti diversi eseguano l'autenticazione con il tuo sistema. Un utente ha il permesso di cambiare una certa Entità, ma l'altro no. Perchè no?

Odio esempi semplici e inventati perché spesso confondono più di quanto illuminino. Ma facciamo finta di avere due domini diversi. La prima è una piattaforma CMS per un'agenzia di marketing. Questa agenzia ha molti clienti che hanno tutti contenuti online che devono essere gestiti da autori e grafici. Il contenuto include post di blog e pagine di destinazione per clienti diversi.

L'altro dominio è la gestione dell'inventario per un'azienda calzaturiera. Il sistema gestisce l'inventario da quando arriva dal produttore in Francia, ai centri di distribuzione negli Stati Uniti continentali, ai negozi al dettaglio nei mercati locali e infine al cliente che acquista le scarpe al dettaglio.

Se ritieni che le regole di autorizzazione siano le stesse per entrambe le società, allora sì, sarebbe un buon candidato per un servizio al di fuori del dominio. Ma dubito che le regole di autorizzazione siano le stesse. Anche i concetti alla base degli utenti sarebbero diversi. Certamente la lingua sarebbe diversa. L'agenzia di marketing ha probabilmente ruoli come autore postale e proprietario di beni, mentre la società di scarpe ha probabilmente ruoli come addetto alle spedizioni o responsabile del magazzino o responsabile del negozio.

A questi concetti probabilmente sono associati tutti i tipi di regole di autorizzazione che devono essere modellate nel dominio. Ciò non significa che facciano tutti parte dello stesso modello anche all'interno della stessa app. Perché ricorda che ci sono diversi contesti limitati.

Quindi forse si potrebbe considerare che un modello di dominio non anemico nel contesto dell'autorizzazione sia diverso dal contesto del routing delle spedizioni di scarpe ai negozi con un basso inventario o indirizza i visitatori del sito alla pagina di destinazione appropriata a seconda dell'annuncio su cui hanno fatto clic.

Se ti trovi con modelli di dominio anemici, forse devi semplicemente dedicare più tempo alla mappatura del contesto prima di iniziare a scrivere codice.

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.