L'ORM è un anti-pattern? [chiuso]


58

Ho avuto una discussione molto stimolante e interessante con un collega su ORM e sui suoi pro e contro. Secondo me, un ORM è utile solo nei casi più rari. Almeno nella mia esperienza.

Ma non voglio elencare i miei argomenti in questo momento. Quindi ti chiedo, cosa ne pensi di ORM? Quali sono i pro e i contro?



2
Sì. A meno che tu non abbia un'applicazione CRUD generica che non fa nulla di valore con il database, nel qual caso non dovresti utilizzare un database relazionale.
Raynos,

1
@derphil: potresti voler renderlo meno ampio, altrimenti questo verrà chiuso. Se ritieni che sia un anti-pattern, forse indica perché e poi chiedi in quali situazioni è appropriato questo anti-pattern (ma potrebbe essere ancora troppo ampio).
FrustratedWithFormsDesigner,

2
@derphil, ci sono molti controargomenti nei commenti a quel post sul blog, li hai letti?
Péter Török,

2
E solo un'altra prova del perché non hai bisogno di un ORM: medium.com/@wrong.about/you-dont-need-an-orm-7ef83bd1b37d
Zapadlo

Risposte:


83

C'è un insieme piuttosto ampio e vario di difficoltà concettuali e tecniche quando si cerca di avvicinarsi a un database relazionale da un angolo orientato agli oggetti. Queste difficoltà sono note collettivamente come disallineamento dell'impedenza relazionale all'oggetto e l' articolo di Wikipedia correlato è estremamente informativo. L'articolo ne identifica parecchi, non vedo alcun modo ragionevole di descriverli qui. Solo per darti un'idea generale, sono catalogati come:

  • disallineamenti
    • Concetti orientati agli oggetti
    • Differenze del tipo di dati
    • Differenze strutturali e di integrità
    • Differenze manipolative
    • Differenze transazionali
  • Risoluzione della mancata corrispondenza dell'impedenza
    • Minimizzazione
    • Architetture alternative
    • compensazione
  • contesa
  • Differenze filosofiche

Penso che se ti prendi il tempo di leggere l'articolo capirai che il fatto che l'ORM sia talvolta descritto come un anti-pattern è in effetti inevitabile. I due domini sono così diversi che qualsiasi approccio per trattare l'uno come l'altro è di default un anti-pattern, nel senso che un anti-pattern è un modello che va contro la filosofia di un dominio.

Ma non penso che il termine debba applicarsi a tutto ciò che essenzialmente funge da ponte tra due domini molto diversi. Etichettare un modello come anti-modello ha senso solo all'interno del suo dominio. Quindi la questione se si tratti di un anti-pattern o no è irrilevante.

Ma è utile? Sì, ORM è uno degli anti-pattern più utili in circolazione. Capirai perché solo se ti trovi in ​​una situazione pratica in cui dovrai scambiare database in un progetto. O anche l'aggiornamento a un'altra versione dello stesso database. ORM è una di quelle cose che capisci pienamente solo quando ne hai davvero bisogno.

Ovviamente, poiché tutto ciò che è utile, ORM è altamente soggetto ad abusi. Se pensi che in qualche modo sostituisca la necessità di sapere tutto sul database su cui lavori, allora tornerà e ti morderà. Difficile.

Infine, lasciami collegare senza vergogna un'altra delle mie risposte , sul relativo "Il modello ActiveRecord segue / incoraggia i principi di progettazione SOLID?" domanda, che per me è una domanda molto più rilevante di "è un anti-schema".


5
+1 per lavorare nell'espressione "mancata corrispondenza dell'impedenza". Parole d'ordine per geek, ma mi piacciono anche loro!
Hardmath,

Totalmente d'accordo ... controlla che questo link sia così ben spiegato: seldo.com/weblog/2011/08/11/orm_is_an_antipattern
sandino

42

Questo è simile a chiedere "un trapano elettrico è un anti-schema?". Gli ORM si sono guadagnati un buon posto nella mia cassetta degli attrezzi, riducendo il mio codice del boilerplate e sono ancora in grado di utilizzare SQL personalizzato, se necessario. Quindi, se si tratta di un anti-schema, quale modello va contro?

La mia risposta è no, ci sono molti ORM maturi che rendono la tua vita molto più semplice e rendono il tuo codice più comprensibile. Questo in ogni modo significa che non è necessario comprendere SQL, al contrario.


11
+1 Anche io penso che sia molto utile, c'è un apprendimento di una curva. Ma è molto bello non dover popolare manualmente pojos, ecc.
NimChimpsky,

18

Esiterei a chiamare qualcosa un "anti-pattern" che per la prima volta è stato chiamato un pattern da Martin Fowler e da allora è stato abbracciato in quasi tutti i moderni linguaggi di programmazione. (Vedi l'articolo di Wikipedia su ActiveRecord .)

Un buon ORM può portare a molto meno codice (e molto meno ripetizione) in un progetto, e nulla è così fortemente correlato ai bug della quantità di codice originale.

Gli ORM sono generalmente progettati per gestire i casi d'uso più comuni per lavorare con i database. Le query complesse potrebbero aver ancora bisogno di essere scritte in modo esplicito. Ma sconsiglio vivamente di scrivere query esplicite per ogni interazione con il database. Nella maggior parte dei casi, è una perdita di tempo.


12
"Esiterei ad andare contro le argomentazioni dell'autorità"
Raynos,

3
@Raynos: Vuoi dire ... stai dicendo ... Fowler potrebbe essere stato ... SBAGLIATO?!?! shock & rantolo Eresia! Blasphemy !! : P;)
FrustratedWithFormsDesigner

9
@Raynos - Forse l'autorità non è l'argomento migliore, ma l'OP ha detto "nella mia esperienza". Questo è essenzialmente un appello all'autorità personale, quindi penso che sia ragionevole contrastare con un appello all'autorità e al consenso. Inoltre, il termine "anti-pattern" si riferisce alle opinioni. Ho fornito esempi di ciò che pensano gli altri.
Nathan Long,

3
@NathanLong Stavo solo sottolineando che popolarità e correttezza sono ortogonali.
Raynos,

1
FWIW Data Mapper è probabilmente il modello che più si avvicina a un ORM. ActiveRecord è un modello diverso, sebbene certamente correlato.
JasonTrue,

11

Usare un ORM invece di apprendere SQL è una pessima idea. Se non conosci esattamente il tipo di SQL generato, se non capisci i problemi di N + 1 e come ottimizzarlo, sicuramente causerà più danni che benefici. Sento però che sono molto più produttivo usando un ORM. Preferisco Rails ActiveRecord, che non cerca di fingere che non ci sia un database e non si frappone se devi solo scrivere SQL. Temo tuttavia che alcune persone possano fidarsi degli idiomi che vedono troppo profondamente, senza una profonda comprensione di ciò che stanno facendo.


11

La mia esperienza: sto usando NHibernate con Linq2NHibernate.

Professionisti:

  • Si sbarazza di "Magic Strings", o almeno offre un posto una volta sola per metterli
  • Mi permette di lavorare in un paradigma OO per tutto il tempo
  • Il codice è più facile da leggere
  • Il codice creato in alto è più facile da modificare
  • Ti consente di scambiare il tuo vero database relazionale senza mantenere 2 repository separati (fatto raramente, ma questo è un grande vantaggio se ne hai bisogno).

Contro:

  • Il codice è più difficile da scrivere , perché
  • Non è un'astrazione sufficiente - devi ancora avere un'intima familiarità con ciò che sta facendo in background

Dirò che non è all'altezza della promessa che la maggior parte delle persone inizialmente spera. Non darei la colpa a qualcuno per aver detto che è un anti-schema. Trovo, nel mio caso, che ho ancora bisogno di fare test di integrazione con un database SQLite per assicurarmi che le mie query Linq2NHibernate funzionino davvero. Quindi, davvero, se stai comunque eseguendo test di integrazione contro un vero database relazionale, quel tipo di elimina il problema con le "stringhe magiche".

Se dovessi iniziare un nuovo progetto, non sono sicuro di usare un ORM o meno. Probabilmente lo farei, ma non posso dire con certezza che dovresti. Direi che è come la differenza tra la scelta di C ++ o Java / .NET per il tuo progetto: hai bisogno della flessibilità che ottieni lavorando a un livello inferiore, o preferiresti lavorare a un livello superiore e (presumibilmente) essere più produttivo? La risposta normale è quella di lavorare a un livello quanto più alto possibile . Questo di solito significa usare un ORM.


6

Il punto di forza di un ORM è che ti consente di modellare il comportamento dell'applicazione usando tecniche orientate agli oggetti. In un mondo attentamente ingegnerizzato, hai un livello dell'applicazione in cui la lingua del business incontra ordinatamente la lingua del team di sviluppo. L'ORM è un fattore abilitante di ciò, se l'ORM viene utilizzato in modo ragionevole.

Il punto debole è che il numero di persone che in realtà ottengono davvero una programmazione orientata agli oggetti è piuttosto piccolo. Molte persone scrivono spaghetti e polpette, con oggetti altamente accoppiati che hanno uno scarso comportamento proprio e il comportamento effettivo finisce in orribili classi di "Servizio" e "Manager" da 8000 righe, e quel codice è spesso così contorto che tutti hanno paura di cambiarlo perché non riescono a capire quali saranno gli effetti collaterali.

Inoltre, molte persone non ottengono davvero il modello relazionale. Un ORM non li aiuterà a ottenerlo, e non li aiuterà estraendo il modello relazionale. Ti consente solo di concentrarti presto sul tuo livello di dominio e di ottenerlo subito prima di iniziare a preoccuparti troppo della progettazione del database. Se applicato correttamente, con l'aiuto di strumenti di migrazione di schemi sensibili e ORM può aiutarti a prevenire l'accumulo di debito del codice.

Ho creato applicazioni in cui un ORM ha mantenuto il codice dell'applicazione semplice, leggibile e testabile e ha prestazioni ragionevoli. Ho anche mantenuto applicazioni in cui lo schema era usato in modo improprio e il codice era contorto, non verificabile, lento e fragile; si scopre che l'ORM stesso aveva poco a che fare con questo, tranne per il fatto che invece di scrivere codice errato che modellava male il dominio dell'applicazione, il team di ingegneri legacy ha scritto codice errato che modellava male il dominio dell'applicazione E codice del livello di servizio errato che trascurava tutto il valore che il loro ORM potrebbe fornire loro.

Gli ORM non ti renderanno più intelligente, ma nelle mani del giusto sviluppatore, possono portare a codice più gestibile e di qualità superiore.


Penso che questo confonda l'utilizzo di un ORM come modello per l'accesso al DB e un ORM come un generatore di codice elaborato per rendere l'accesso al DB più semplice e migliore.
gbjbaanb,

Non sono sicuro di cosa tu voglia dire. Il tuo commento non ha molto senso per me.
JasonTrue,

In quanto un ORM è un ottimo modo per accedere a un DB con un sacco di duro lavoro fatto per te, ma se lo usi come modello di progettazione per fingere che un DB sia una raccolta di oggetti, inizia a cadere. Questo è quello che pensavo stessi dicendo.
gbjbaanb,

Non credo di aver mai sostenuto l'uso di un ORM per fingere di avere un negozio di oggetti magici che non richiede di capire come funziona il database. Ho detto esattamente il contrario: se capisci bene la programmazione orientata agli oggetti E come funzionano i database, un ORM può aiutarti a produrre codice più gestibile.
JasonTrue,

5

Forse la risposta sta nel contrario della tua domanda: archiviare i dati delle tue applicazioni in qualcosa di diverso da un database relazionale è una buona idea? Quali problemi stai eliminando e quali altri problemi affronterai? Riesci a vivere senza la possibilità di eseguire facilmente i riferimenti incrociati (join) o filtrare rapidamente i record desiderati in base a più criteri? Non hai bisogno di un solido supporto per le transazioni (supponendo che la tua alternativa non ce l'abbia)? Non tutte le applicazioni richiedono un archivio dati sempre coerente e completo.

Penso che il vero anti-pattern qui possa usare un DB relazionale quando non ne hai bisogno. Se ne hai bisogno, allora hai bisogno di ORM, e sicuramente non è un anti-pattern.


1
Mentre sono d'accordo che usare un database relazionale se non ne hai bisogno è una cattiva idea, oggi che se ne usi uno hai bisogno di un ORM è ridicolo!
HLGEM,

1
Allora, come hai intenzione di ottenere i tuoi dati dentro e fuori dal database? Da qualche parte, qualcosa dovrà mappare i tuoi oggetti alla struttura relazionale e ricrearli quando vengono letti dal database. Anche se scrivi query a mano e copi i dati dentro e fuori dai set di risultati, stai eseguendo ORM.
TMN,

1
Utilizzando Procs memorizzati (l'unico modo accettabile per inserire qualsiasi tipo di dati finanziari per motivi di controllo interno) per fare tutta la manipolazione del database non è ORM nella mia mente. Non ho mai visto alcun valore per un ORM per qualcuno che conosce bene SQL. Né ho mai lavorato su un sistema (e lavoro con applicazioni Enterprise molto complesse) che dipendeva fortemente da un ORM, semplicemente non sono abbastanza buone quando ciò che fai è complesso.
HLGEM,

6
@HLGEM: E i dati che ottieni dal database? Quando si esegue una query sul database relazionale, non si mappano i risultati sugli oggetti? Nella mia esperienza, ci sono due tipi di progetti che utilizzano database relazionali: quelli che utilizzano ORM di terze parti e quelli che includono i propri ORM di scarsa qualità.
Carson63000,

2
+1 Carson. Usi qualche tipo di ORM a prescindere da cosa, a meno che tu non restituisca semplicemente DataSet grezzi e incolli quelli sul tuo codice (il reato più grave di tutto l'IMHO) poiché dovrai sempre mappare i risultati di quella procedura memorizzata sulle classi, che è esattamente ciò che Gli ORM fanno per te.
Wayne Molina,

4

ORM è uno strumento. Come tutti gli strumenti, se usati in modo appropriato, funzionano abbastanza bene. Se usato in modo inappropriato, ha bisogno di un martello più grande e del nastro adesivo.

Nel caso del progetto attuale a cui sto lavorando, sarà gestito da non sviluppatori (ingegneri meccanici, per essere precisi) e quindi deve essere semplice e facile da capire. Ci vorranno diversi anni prima che questo gruppo disponga di un budget per assumere gli sviluppatori (presumendo che il prossimo presidente non abolisca l'agenzia coinvolta), quindi le future capacità di manutenzione sono un fattore importante nelle nostre considerazioni.

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.