In che modo l'accumulo di grandi quantità di logica aziendale sugli oggetti del modello rende più difficile la creazione di contratti di assistenza efficaci?

5

Ho sentito un paio di volte che mettere la logica di business nei modelli di database è brutto in fondo.

Ho appena leggi questo nel blog di un dipendente di Rackspace: L'ORM Django tendeva anche a farci accumulare grandi quantità di logica aziendale sugli oggetti del modello, il che rendeva ancora più difficile la costruzione di contratti di assistenza efficaci.

Ma mi sembra logico che se si dispone di un modello Invoice per incapsulare un sacco di logica di fatturazione lì. Sembra molto simile a quello che ci è stato insegnato in OOP. Potresti mostrarmi come questo è sbagliato? Per favore includi un esempio pratico se possibile.

Vantaggio di "mettere la logica nei modelli"

Quello che vedo come un grande vantaggio di mettere la logica nei modelli è che gli utenti dei modelli non devono preoccuparsi di come possono usare le cose, lo usano e funzionano, non possono rompere nulla.

Lasciatemi elaborare un esempio: Quindi se non inserisci la logica nei modelli, probabilmente hai questo codice altrove, diciamo che è in api . Se vuoi cambiare uno stato di Invoice , cosa fai? Esegui invoice.state = new_state o leggi il codice api per vedere se esiste un metodo che modifica lo stato?

Questo è confuso e soggetto a errori. Come risolvi questo problema allora?

    
posta duality_ 14.02.2014 - 09:13
fonte

3 risposte

8

Wrong è una parola grossa.
Il motivo per cui non dovresti metterlo nel DB, è perché il vocabolario dei (più) sistemi DB è incredibilmente limitato. Non c'è nulla su "SELECT", "INSERT", "UPDATE", "DELETE" che ti permette di esprimere fluentemente perché qualcosa sta accadendo e a cosa è una reazione, nei termini della lingua del dominio .
Per quanto riguarda la seconda parte della tua domanda: il problema con gli ORM è che di solito ti costringono ad organizzare i tuoi oggetti di dominio in modo contrario a ciò che desideri.
Un esempio semplice e comune è che in genere si desidera incapsulare un sacco di cose all'interno delle classi di dominio, ma gli ORM devono poter accedere ai campi e alle proprietà delle classi per poterli persistere, quindi si finisce col rivelare tutto, spezzando potenzialmente l'incapsulamento.

Ciò che in genere tendo a trovare una buona idea è separare il modello ORM dal modello di dominio e creare un modo per gonfiare gli oggetti del modello di dominio dagli oggetti del modello ORM.

    
risposta data 14.02.2014 - 09:35
fonte
6

Il problema con i modelli Django (o le rotaie attive registrano lo stesso pattern) è che questo non è un modello comportamentale della tua applicazione, è un modello di dati, con queste architetture la tua applicazione è strettamente accoppiata al database. Problemi di questo tipo di applicazioni:

  • Il design del database domina il design della tua applicazione. Normalmente finisci con una tabella - > una classe.

  • Come conseguenza del progetto precedente, quando l'applicazione cresce le classi "modello" tendono a crescere e crescere, il tipico problema del "modello grasso".

  • La tua logica aziendale e la tua tecnologia di persistenza sono totalmente accoppiate, non puoi cambiare una cosa senza cambiare l'altra.

  • Per visualizzare il database come archivio dati globale, è possibile accedere a ogni tabella / modello da ogni punto dell'applicazione. Quando l'applicazione cresce, questo tipo di sistemi è molto difficile da mantenere a causa dell'elevato accoppiamento. Kent Beck ha scritto su questo molto tempo fa: link , chiama questo tipo di sistemi "connessi" a un approccio più moduler.

Per semplici applicazioni database centriche con modelli di dominio non complessi, Django ORM (o record attivo di rotaie) può fare un buon lavoro. Il problema è quando il tuo sistema cresce, molte persone nei binari e la comunità di django guardano cose come l'architettura esagonale o il Domain Driven Design per trovare modi per gestire un dominio complesso.

Per un'introduzione, questa è una bella chiacchierata da matt wayne (autore di cucumber): link , è circa rotaie, ma è esattamente lo stesso problema.

    
risposta data 14.02.2014 - 09:41
fonte
0

È una domanda simile a "dovresti fare la convalida nel livello di presentazione?"

E la risposta è la stessa: generalmente la logica di business deve andare nel livello intermedio, ma ci sono sempre delle eccezioni dove è appropriato.

Se stai mettendo molta logica nel livello dati allora stai sbagliando, stai inquinando il codice di accesso e recupero dati con un carico di altre cose che non ci appartengono e sei scrivere un programma in stile client-server.

In termini OO, il livello intermedio dovrebbe prendere un oggetto dati cliente "crudo" e un insieme di oggetti Prodotto e combinarli per produrre un oggetto Fattura che viene inviato a valle. Si noti che non vi sono dati di fatturazione direttamente memorizzati nel DB, solo clienti, prodotti e relativi ordini.

È un piccolo esempio negativo, poiché oltre a combinare i dati in un nuovo oggetto non viene applicata alcuna logica aziendale (a meno che non si abbiano regole fiscali complicate) e se tutto ciò che si sta facendo è un jiggling dei dati, è un ottimo esempio di cosa dovrebbe andare nel livello dati. Una regola empirica potrebbe essere "se devi modificare quei dati che devono andare nel livello intermedio"

    
risposta data 14.02.2014 - 09:35
fonte

Leggi altre domande sui tag