Tabelle di ricerca: sono una perdita nel modello di dominio?


10

Stai costruendo un sistema che tiene traccia delle aziende. Quelle aziende hanno contatti. Questi contatti sono spesso specialisti che rispondono solo a determinati tipi di domande, come fatturazione / pagamento, vendite, ordini e assistenza clienti.

Utilizzando Domain Driven Design e un'architettura di cipolla, ho modellato questo con i seguenti tipi:

  • Azienda
    • Ha contatti
  • Contatto
    • Ha tipi di contatti
  • ContactType (enum)
  • CompanyRepository (interfaccia)
  • EFCompanyRepository (definito in un assembly esterno, utilizza EntityFramework, implementa CompanyRepository)

Il nostro team ha un'opinione divisa su come modellare il database per questa applicazione.

Lato A: The Lean DDDers:

  • È compito del dominio definire quali tipi di contatto sono validi per un contatto. L'aggiunta di una tabella al database per confermare che i ContactTypes sconosciuti non vengono salvati è un segno di un dominio che perde. Diffonde la logica troppo lontano.
  • L'aggiunta di una tabella statica al database e al codice corrispondente è dispendiosa. In questa applicazione il database risolve un problema: persiste e restituiscilo. Scrivere una tabella aggiuntiva e il corrispondente codice CRUD è dispendioso.
  • Modificare la strategia per la persistenza dovrebbe essere il più semplice possibile. È più probabile che cambi le regole di business. Se decido che SQL Server costa troppo, non voglio ricostruire tutta la convalida che ho inserito nel mio schema.

Lato B: i tradizionalisti [che probabilmente non è un bel nome. The DBCentrists?]:

  • È una cattiva idea avere dati nel database che non hanno senso senza leggere il codice. I report e gli altri consumatori devono ripetere da soli l'elenco dei valori.
  • Non è molto il codice per caricare i dizionari di tipo db su richiesta. Non ti preoccupare.
  • Se la fonte di questo è il codice e non i dati, dovrò distribuire bit invece di un semplice script SQL quando cambia.

Nessuna delle due parti ha ragione o torto, ma una di esse è probabilmente più efficiente a lungo termine, contando i tempi di sviluppo per lo sviluppo iniziale, i bug, ecc. Da che parte sta - o c'è un compromesso migliore? Cosa fanno gli altri team che scrivono questo stile di codice?


Preferisco avere tabelle di ricerca nel database e avere codice (modelli T4 in .NET) che genera gli enummi per me in base alle tabelle di ricerca nel mio codice dell'applicazione.
programmatore

@JasonHolland Il modello T4 esegue effettivamente una query? Altrimenti non sono sicuro di come generi più di un enum vuoto con il nome previsto.
Drew


Per una tabella con valori statici, quanto codice CRUD devi scrivere? Scriverlo ed essere fatto.
JeffO,

2
L'argomento tradizionale di CRUD-ist sul "bene, non ha senso riferire" non è un punto di partenza. Non appena si introducono altre responsabilità che il sistema ha (vale a dire, reportistica), è stato riscontrato un requisito aziendale che deve essere gestito in modo appropriato. Il database è lì per archiviare e caricare lo stato protetto delle applicazioni; consentire la segnalazione su crea un accoppiamento tra l'applicazione e le persone che necessitano dei rapporti. Se DDD riguarda qualcosa, si tratta di separare questi contesti.
Matt

Risposte:


4

Adottando l'architettura DDD e cipolla, hai deciso che il database è secondo al tuo modello di dominio. Ciò significa che non ci sarà nessun altro a fare operazioni sul database diverso dal modello. Se ai tradizionalisti non piace, avrebbero dovuto obiettare in primo luogo all'uso del DDD.

La prima cosa è chiara: è necessaria la "tabella di ricerca" nel modello. Il tuo modello deve distinguere tra diversi tipi di contatti. Ciò significa che mantiene un elenco fortemente tipizzato di tutti i tipi. È inoltre necessario eseguire il mapping da quei tipi forti ai valori serializzati nel database. Questa mappatura può essere all'interno del modulo del database. Ma l'elenco di tutti i possibili tipi rimarrà comunque nel modello. E se il modello deve essere una singola fonte di verità, non può essere all'interno del database. O almeno, quando l'elenco cambia nel modello, deve cambiare nel database. E niente ma!


2

Gli oggetti di dominio smettono di essere oggetti di dominio quando attraversano un confine di processo . Anche se il database è solo un archivio di persistenza, ad un certo punto in futuro le esigenze dell'azienda causeranno una modifica al modello di domaim che è incompatibile con la storia persistente e avrete comunque bisogno di un livello anticorruzione ....

Detto questo, penso che ai tuoi DBCentrists manchi la barca. I modellatori di domini affermano di aver bisogno di un archivio di persistenza. "I rapporti e altri consumatori" hanno bisogno di qualcosa su cui possano interrogare, qualcosa con indici decenti, come è stato notato nei commenti.

Chi ha introdotto il vincolo che tutte queste diverse preoccupazioni dovevano essere supportate da un database? Cosa succede se ci ripeti.

Parola chiave di ricerca: CQRS.


1

Ho trovato meglio archiviare gli enum come loro rappresentazione di stringhe nel database e non includere una tabella di ricerca.

Ovviamente il rovescio della medaglia è che utilizza più spazio su disco e non è normalizzato.

Il lato positivo è che il campo mantiene il suo significato nel db, ad esempio non si ottengono numeri magici corrispondenti al valore int dell'enum e non è necessario gestire il controllo delle versioni di una tabella di ricerca quando l'enum cambia.

Non sono sicuro che lo definirei come una differenza tra DDD e Trad. È più un centralista di database vs codice è il migliore a mio avviso


chiedendosi se i database stessi abbiano una tale caratteristica enum in questi giorni
herzmeister,

Immagino che dipenda dal DB, con MSSQL puoi fare tutti i tipi di cose folli con CLR. Ma sono fermamente d'accordo con il lato "DB cattivo, codice buono" quando si tratta di cose del genere
Ewan,

@herzmeister <3 PostgreSQL postgresql.org/docs/9.4/static/datatype-enum.html , Ewan Il DB è il codice una volta accettate le procedure memorizzate. (PLv8 è meraviglioso).
Sirisian,

@Sirisian sai che fonde la cosa? Io ho una domanda simile. "scala?"
Ewan,

Vuoi dire che fa un prodotto incrociato per trasformare l'enum in una stringa? Probabilmente no. Non sono sicuro di come sia implementato, ma è più veloce rispetto all'utilizzo di una tabella separata. Si ridimensiona. Trovato anche questo: stackoverflow.com/questions/2318123/… Sembra ancora una valutazione valida 5 anni dopo. (Tendo a scrivere programmi altamente accoppiati a PostgreSQL, quindi uso tutte le funzionalità, ma non tutti possono farlo).
Sirisian,

0
  • Finché si utilizza un database relazionale, è necessario mantenere le tabelle normalizzate in misura ragionevole. La normalizzazione aiuta a prevenire l'inserimento e l'aggiornamento di anomalie.
  • La relazione one-app <-> one-database non è più comune, più app possono utilizzare più database e un singolo database può essere utilizzato da più app, quindi avere il database imporre l'integrità referenziale il più possibile.
  • RDBMS è tuo amico.
  • Puoi invece utilizzare un archivio di valori-chiave e fare tutto nel 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.