Perché non utilizzare un ORM con DDD?

2

Ho appena finito di leggere l'eccellente libro di Scott Wlaschin " Modellazione del dominio Made Functional: Tackle Software Complexity con Domain-Driven Design e F # " in cui usa il provider di tipi F # SQL per l'accesso al database .

Anticipando la domanda ovvia, dice (p260) di non usare un ORM perché non è possibile garantire l'integrità del dominio in questo modo. Ad esempio, un ORM non può convalidare un indirizzo email, ecc. Non può gestire tipi di scelta annidati, ecc.

Tuttavia, prima nel libro (non riesco a trovarlo a caso, quindi spero di averlo citato correttamente), quando spiega come creare i limiti per ogni sezione del flusso di lavoro, dice che i dati devono essere convalidati in ogni sezione confine, consentendo al codice all'interno della sezione di assumere che sia tutto valido.

Se sì, perché non trattare le entità che escono dall'ORM e nel tuo codice come attraversano un confine e convalidarle lì? In questo modo ottieni i vantaggi dell'ORM, ma assicurati l'integrità del tuo modello.

    
posta Avrohom Yisroel 22.05.2018 - 17:17
fonte

2 risposte

7

Per essere chiari, ho detto "In F #, tendiamo a non utilizzare un mappatore di oggetti relazionale (ORM)" ma non a causa di alcun problema di convalida, piuttosto perché un grande ORM come Entity Framework è strongmente orientato agli oggetti (sorpresa !) che non sempre si adatta bene a un paradigma funzionale. Invece i F #er useranno i type provider o una libreria più semplice come Dapper.

Nel capitolo "Lavorare con i database relazionali", posso dire che puoi trattare il database in due modi diversi:

  • come sorgente non attendibile, nel qual caso si esegue la convalida nel modo usuale (come per i dati provenienti da un'API Web JSON, ad esempio)
  • come fonte attendibile, nel qual caso non si esegue la convalida e si generano eccezioni se i dati sono negativi.

Il caso si applica a seconda che il database sia condiviso con altre applicazioni, come è progettato, ecc.

Aggiornamento: mi rendo conto che la seguente frase potrebbe essere interpretata erroneamente:

Can’t we just use something like Entity Framework or NHibernate that will do all this mapping automatically? The answer is no, not if you want to ensure the integrity of your domain.

Ciò che intendevo è che tradurre un modello di dominio direttamente in un database tramite un ORM significa che si perde molta della complessità dei tipi di dominio - il "rendere gli stati illegali non rappresentabili" approccio progettuale a cui dedico un capitolo. Questo perché gli ORM non sanno come gestire le unioni a caso singolo con vincoli, tipi di scelta complessi, ecc.

Invece, ti consiglio di tradurre i tuoi oggetti di dominio in un tipo appositamente progettato per la persistenza (un "DTO") e quindi di usare quel DTO per la persistenza, non il tipo di dominio. Per archiviare / caricare il DTO puoi sicuramente usare EF o NHibernate, ma non ne ottieni molti vantaggi quando lo utilizzi in quel modo, e quindi è generalmente più facile usare i provider di tipi o un programma di mappatura leggero come Dapper.

    
risposta data 22.05.2018 - 19:23
fonte
1

Se leggi il prossimo paragrafo nel libro, lo dice:

What's special about using a type provider rather than a typical runtime library is that the SQL type provider will create types that match the SQL queries or SQL commands at compile time. If the SQL query is incorrect, you will get a compile time error, not a runtime error. And if the SQL is correct, it will generate an F# record type that matches the output of the SQL code exactly.

Quindi sembra che questo approccio fornisca alcune delle stesse garanzie che la tipizzazione statica fa in C #. Vale a dire che riceverai un errore in fase di compilazione se i tuoi tipi non si allineano.

    
risposta data 22.05.2018 - 17:40
fonte

Leggi altre domande sui tag