8

Sto espandendo/convertendo un'applicazione legacy Web Form in un'applicazione MVC completamente nuova. L'espansione è sia dal punto di vista della tecnologia che del caso di utilizzo aziendale. L'applicazione legacy è un Database Driven Design (DBDD) ben fatto. Quindi per es. se hai diversi tipi di Dipendenti come Operatore, Supervisore, Custode del Negozio ecc. e devi aggiungere un nuovo tipo, vai e aggiungi alcune righe in un paio di tavoli e voilà, l'interfaccia utente ha automaticamente tutto per aggiungere/aggiornare il nuovo tipo di dipendente. Tuttavia la separazione dei livelli non è così buona.Progettazione basata su domini o progettazione guidata da database per un'applicazione Web MVC

Il nuovo progetto ha due obiettivi primari

  • estensibilità (per momento e le esigenze di pipeline futuri)
  • prestazioni

ho intenzione di creare il nuovo progetto di sostituzione del Database Driven Design (DBDD) con un Domain Driven Design (DDD) tenendo presente il requisito di estensibilità. Tuttavia, il passaggio da una progettazione guidata da database a una progettazione basata su domini sembra avere un impatto inverso sui requisiti delle prestazioni se si confronta con le prestazioni dell'applicazione legacy DBDD. Nell'applicazione legacy qualsiasi chiamata per i dati dell'interfaccia utente interagirebbe direttamente con il database e tutti i dati sarebbero restituiti sotto forma di un DataReader o (in alcuni casi) di un DataSet.

Ora con una rigida DDD sul posto qualsiasi chiamata per i dati verrà instradata attraverso il livello aziendale e il livello di accesso ai dati. Ciò significherebbe che ogni chiamata inizializzerebbe un oggetto business e un oggetto di accesso ai dati. Una singola pagina dell'interfaccia utente potrebbe necessitare di diversi tipi di dati e, trattandosi di un'applicazione Web, ogni pagina potrebbe essere richiesta da più utenti. Inoltre, essendo un'applicazione Web MVC senza stato, ogni richiesta richiede l'inizializzazione di oggetti business e oggetti di accesso ai dati ogni volta. Quindi, per un'applicazione stateless MVC, il DBDD è preferibile a DDD per le prestazioni.

O c'è un modo in DDD per raggiungere entrambi, l'estensibilità che fornisce DDD e le prestazioni fornite da DBDD?

+0

Considerato come un'interessante domanda perché prende alla lettera i meccanismi dietro i vari progetti in modo così letterale. Molto spesso queste discussioni sono troppo astratte per essere utili. Questo è molto diretto. Sono ansioso di vedere quali sono le risposte (io stesso non ne ho idea). –

+0

Ho un paio di domande prima di iniziare a pensare: 1. Che cosa sono esattamente i requisiti di prestazione? Quanto veloce dovrebbe rispondere l'applicazione. Se tutte le domande dovessero essere risposte in 1 sec O 0.5 secondi per il recupero dei dati e 1 secondo per gli aggiornamenti? 2. Avete già alcune metriche per l'applicazione corrente e quanto più lento dovrebbe funzionare un MVC? –

+0

Ho le metriche per le operazioni correnti del database dell'applicazione. Ad eccezione del reporting che può comportare complicate operazioni con dati pesanti e può richiedere alcuni minuti, il CRUD impiega meno di un secondo mentre le operazioni di recupero dei dati massime avvengono entro 2 - 3 secondi a livello di database. Quanto più lento sarà l'applicazione MVC, la domanda è tutto su – devanalyst

risposta

6

Avete preso in considerazione una qualche forma di interrogazione della query di comando in cui gli aggiornamenti sono attraverso il modello di dominio eppure le letture arrivano come DataReader? Il DDD in piena regola non è sempre appropriato.

+0

+ 1 per la raccomandazione di CQRS. Anche se devo dire che l'uso di CQRS non significa che non si stia più utilizzando il DDD "full blown". Al contrario. Proiettare DTO/Visualizzare i modelli dai propri aggregati di dominio invece di proiettarli direttamente dal database non sminuisce il livello di DDD che si sta praticando. Fare il primo rende la vita difficile e richiede uno strato di mappatura da oggetti che sono (o dovrebbero essere) progettati sugli invarianti che impongono nelle transazioni. Quest'ultimo, per me, è solo il modo pratico/ragionevole. –

+1

Questo non risolve le query di scrittura in blocco. Inoltre, non risolve il problema che a volte è necessario lavorare solo con ID e non è necessario idratare tutto (per le prestazioni).Puoi aggiungere regole a ciascuna entità, ma sei obbligato a ottenere operazioni di scrittura che coprano i dati di scrittura relativi a più entità (non importa se sono aggregati) e dovrai duplicare tali regole perché sei evitando il looping attraverso ogni entità per applicare le sue regole singolarmente (sconfigge lo scopo del DDD). – prograhammer

+0

Ecco un buon [articolo] (http://blog.sapiensworks.com/post/2013/12/16/Bulk-Actions-With-DDD-And-CQRS.aspx/) che risolve il problema che cito. Non so se la soluzione fornita risolva sufficientemente il problema. È un argomento difficile. CQRS aiuta, ma abbiamo ancora problemi di prestazioni dal lato della scrittura da affrontare. – prograhammer

1

L'utilizzo di DDD non dovrebbe avere implicazioni di prestazioni significative nello scenario. Ciò che ti preoccupa sembra più un problema di accesso ai dati. Si fa riferimento ad esso come

inizializzare un oggetto di business e di un Data Access Object

Perché 'inizializzazione' costoso? Quali meccanismi di accesso ai dati stai usando?

DDD con oggetti a vita lunga memorizzati in un database relazionale viene in genere implementato con ORM. Se utilizzato correttamente, l'ORM avrà un impatto minimo sulle prestazioni per la maggior parte delle applicazioni. E puoi sempre ripristinare le parti più sensibili alle prestazioni dell'app su SQL raw se c'è un collo di bottiglia comprovato.

Per quel che vale, NHibernate deve essere inizializzato solo una volta all'avvio dell'applicazione, dopodiché utilizza lo stesso pool di connessioni ADO.NET dei normali lettori di dati. Quindi tutto si riduce a una corretta mappatura, alla strategia di recupero ed evitando i classici errori di accesso ai dati come 'n + 1 seleziona'.

4

"Ora con un rigo DDD in atto, qualsiasi chiamata per i dati verrà instradata attraverso il livello aziendale e il livello di accesso ai dati."

Non credo che questo sia vero, e non è certamente pratico. Credo che questo dovrebbe leggere:

Ora con rigorosa DDD in atto, qualsiasi richiesta di un un'operazione verrà reindirizzato attraverso lo strato di business e lo strato di accesso ai dati.

Non c'è nulla che dice che non è possibile chiamare direttamente il livello di accesso ai dati per recuperare tutti i dati che è necessario visualizzare sullo schermo. È solo quando è necessario modificare i dati che è necessario richiamare il modello di dominio progettato in base al suo comportamento. Secondo me questa è una distinzione fondamentale. Se si itinerario tutto attraverso il vostro modello di dominio si avrà tre problemi:

  1. Tempo - ci vorrà molto più tempo per implementare la funzionalità, senza alcun beneficio.
  2. Modello di progettazione: il modello di dominio sarà piegato in modo non corretto per soddisfare le esigenze di query anziché di comportamento.
  3. Prestazioni: non a causa di un livello aggiuntivo, ma perché non sarà possibile ottenere i dati aggregati dal modello il più rapidamente possibile direttamente da una query. Consideriamo il valore totale di tutti gli ordini effettuati per un particolare cliente - è molto più veloce scrivere una query per questo piuttosto che recuperare tutte le entità dell'ordine per il cliente, iterare e sommare.

Come menzionato da Chriseyre2000, CQRS mira a risolvere questi problemi specifici.