Dove collocare la convalida del formato in un modello di dominio "elegante" di CQRS?

5

È corretto inserire la convalida del formato negli oggetti del dominio (VO o entità) perché è il luogo naturale per un'elevata coesione e il dominio sa meglio cosa significano tutte le descrizioni / attributi / proprietà del dominio. Molti autori di DDD e autori di libri (Vaugh Vernon, Dan Bergh - e anche Eric Evans suggeriscono, ma su un aspetto diverso: l'autorizzazione, per modellare il dominio per riflettere questi argomenti) suggeriscono di progettare il modello di dominio in modo da riflettere e far rispettare un stato corretto dell'attività.

Sono d'accordo che la convalida del formato (es .: la proprietà dell'indirizzo in EmailAddress VO dovrebbe essere max ~ 250 caratteri e dovrebbe corrispondere a un'espressione regolare) dovrebbe essere implementata all'interno degli oggetti dominio. Ma questi controlli di validazione funzionano meglio con un modello di dominio che verrà utilizzato sia per le modifiche di stato che per le query di stato.

Che dire di CQRS in cui il lato comando (dove è il modello di dominio) ha poca o nessuna conoscenza sul lato di lettura. Si dovrebbe reimplementare gli stessi controlli del formato di input nel lato query dell'applicazione? In CQRS ci sono alcune responsabilità comuni sia per il comando che per il lato di query (come la convalida del formato di input), quindi le consuete implementazioni di convalida del formato che la maggior parte dei professionisti del DDD suggeriscono saranno duplicate.

Come si dovrebbe affrontare questo, senza rendere il modello di dominio (dal lato comando) anemico e senza rendersi conto dello stato degli attributi che manterrà.

Un esempio: potrebbe esserci una funzionalità che consentirebbe al proprietario di una conferenza di programmare una conferenza e modificare il numero di posti disponibili. Ma poiché la sala conferenze non è abbastanza grande, il numero massimo consentito di posti sarà 100. Quindi una regola aziendale sarebbe che: un proprietario di una conferenza non può aggiungere più di 100 posti per una conferenza programmata (anche un minimo di 1 posto necessario per la conferenza essere in uno stato valido). Quindi un metodo sarebbe su un ConferenceAR:

changeNumberOfAvailableSeats(numberOfAvailableSeats) {
    if(!isNumber(numberOfAvailableSeats) || numberOfAvailableSeats > 100 ||   
            numberOfAvailableSeats < 1) {
        throw new DomainException ...
    }  

    // Change the number of available seats ...
}

Dal lato della query potrebbe esserci una pagina dell'interfaccia utente in cui è possibile trovare tutte le conferenze programmate con un determinato numero di posti disponibili. Quindi, di nuovo, sul lato query del server dell'applicazione, ci deve essere una convalida del formato che verificherà se la query per le conferenze programmate con un numero di postazioni disponibili è un numero compreso nell'intervallo 1-100. Questa query potrebbe essere necessaria a qualcuno che desidera prenotare un certo numero di posti per una conferenza. Anche le conferenze potrebbero essere sullo stesso argomento in modo da poter vedere una conferenza con lo stesso argomento molte volte e scegliere quella più economica o con più posti disponibili.

Quindi, di nuovo, si dovrebbe reimplementare la convalida del formato su entrambi i lati di query e comando oppure esiste un'altra soluzione?

P.S. : ci sono molti duplicati di convalida del formato (sia sul lato comando che su quello della query) come la convalida del formato email o una convalida del formato valuta (se la valuta è: USD || CAD || AUD ecc ...)

P.P.S. : Un'altra domanda che è saltata fuori: il lato query dell'applicazione richiede una convalida del formato di input? Se l'input non è un formato valido, non restituirà nulla, la query non ha trovato dati relativi alla richiesta. Vedo che la convalida del formato sul lato della query è puramente una misura di sicurezza (cioè per buffer overflow). Quindi la convalida del formato di input è davvero necessaria sul lato query?

    
posta Tudor 19.06.2014 - 21:23
fonte

2 risposte

3

Penso che se gli oggetti di dominio sul lato comando sono sempre in uno stato valido, non dovresti preoccuparti che le query restituiscano risultati non validi.

Che cosa faresti, comunque, se hai scoperto un'invalidità dal lato della lettura, comunque? Dì al repository di lettura di reinserire i valori? ; -)

Se il lato di lettura dovesse avere un controllo, penserebbe che si troverebbe nell'area di qualche tipo di unità o test di integrazione, perché invece di un messaggio di errore di immissione dei dati, è un bug.

Una delle cose su CQRS è mettere da parte quelle preoccupazioni, più semplicemente avere roba in un posto. Altrimenti lo rende più difficile, non più facile (in realtà, può essere semplice o facile, altrimenti, cercare un modo migliore per implementarlo o continuare a studiarlo).

    
risposta data 10.07.2014 - 03:49
fonte
0

Se utilizzi eventi per trasferire dati, puoi probabilmente trattare molte di queste preoccupazioni semplicemente come un altro tipo di dati che il modello di lettura deve memorizzare e organizzare in modo conveniente. Ad esempio,

  • Vorresti già un listener per eventi come RoomCreated e RoomDisabled dal dominio, perché stai mantenendo una sorta di rappresentazione veloce su query di quali stanze sono disponibili, giusto? Perché non mantenere anche una variabile biggestActiveRoomSize allo stesso tempo?
  • Visualizza un evento ContactCreated o ContactEmailUpdated ? Controlla la lunghezza e aggiorna un maxEmailCharacters memorizzato.
  • Visualizza un evento PricingPosted ? Assicurati che la valuta all'interno dell'evento sia presente / aggiunta alla tua lista knownCurrencies . Ciò significa che poco dopo essere stato utilizzato, diventerà un'opzione con cui le persone possono cercare.

In altre parole, qualunque cosa provenga dal dominio è automaticamente valida e tutto ciò che vedi espande la busta di ciò che sei disposto a permettere all'utente di entrare.

Certo, questo non funziona per certe cose complesse come le espressioni regolari o se / allora la logica. Per quei casi, forse:

  • Come parte del processo di compilazione, la compilazione del modello di dominio emette un file di configurazione che può essere caricato e utilizzato dal lato della query.
  • Duplicazione totale della logica. Non ideale, ma fattibile fintanto che il lato interrogativo è molto chiaro su dove si trova la fonte autorevole e hai una procedura per aggiornare i valori che gli umani seguiranno.
  • Idea più pazza: chiedi al modello di dominio di archiviare / trasmettere un evento ogni volta che si avvia, contenente quel tipo di informazioni. Più modelli di lettura potrebbero decidere cosa (se mai) vogliono fare con esso.

Penso che dovresti pianificare la qualche duplicazione (c'è sempre qualcosa) ma quando si tratta di "quali valori o intervalli vengono effettivamente usati", proverei a renderlo solo un'altra parte del read-modello.

    
risposta data 17.07.2014 - 08:29
fonte

Leggi altre domande sui tag