Serializzazione dei dati per elaborare la logica aziendale

4

Seguendo il principio generale dell'astrazione dei dati, di solito astraggo i dati in un formato serializzato (JSON) e li passo come parametro ai moduli Business Logic (BL) in modo tale che il modulo BL veda sempre un formato coerente dei dati indipendentemente dal livello di archiviazione dati sottostante. Anche se utilizzo un ORM, utilizzo il formato serializzato di quell'ORM. Sento di avere i seguenti vantaggi.

  • serializzando i dati, ci sarebbe un controllo migliore su dati e parametri
  • Qualsiasi sviluppatore può scrivere BL senza pensare troppo all'archiviazione dei dati sottostanti
  • I wrapper possono essere scritti per nuovi database (ci sono molti wrapper già pronti per convertire i dati in JSON)
  • I test possono essere eseguiti spietatamente e senza un database (poiché il formato dei dati è serializzato)
  • Integrazione OLAP e OLTP funzionalmente più semplice da comprendere

Ho notato anche i seguenti inconvenienti

  • Un nuovo livello da aggiungere tra il database e il modulo BL (la maggior parte degli ORM oggi ha un formato JSON predeterminato)
  • Le chiamate con funzioni extra rallentano l'applicazione (ma penso che questo compromesso sia OK se confrontato con test migliori e manutenzione semplificata)
  • Un maggiore livello di astrazioni potrebbe confondere lo sviluppatore

Rendo le osservazioni di cui sopra principalmente nel contesto delle applicazioni aziendali Per seguire questa discussione, facciamo un esempio in modo che le cose possano essere discusse nel suo contesto. Assumi un database di prodotti con le colonne: Prodotto, Tariffa, Imposte e dobbiamo creare una fattura

Codice senza astrazione del database

GET rate,taxes for product X from database
multiply qty with rate and add taxes
display invoice

Codice con l'astrazione del database

  GET rate,taxes for product X from database
  Convert it into JSON
  call create_invoice function //This does all the calculations
  display invoice

Nel secondo esempio, avrei passato gli argomenti nel modulo (Product = X, Qty = 5, Rate = 5, Taxes = 0.05). Se le tasse devono essere suddivise in più di una categoria (imposta di stato = 0,03, imposta centrale = 0,02) o un fattore di sconto da aggiungere, vorrei solo aumentare il numero di parametri nelle funzioni BL in modo tale che i campi del database, le chiavi JSON e i parametri della funzione coincidono (ciò avviene automaticamente durante la serializzazione e la maggior parte degli ORM lo fanno). Ciò semplifica, nel mio approccio, estendere le funzioni e anche rendere i moduli indipendenti dai dati poiché i moduli conoscono sempre i dati che possono ricevere e anche se ricevono un nuovo parametro, possono adattarsi fornendo il codice sottostante è intelligente.

Le mie domande generali sono

  1. Questo è un buon schema e come si chiama (mi viene in mente l'astrazione dei dati)?
  2. Pro / Contro di questo modello (a parte quelli menzionati sopra) nel contesto di applicazioni aziendali, app per dispositivi embedded, big data
  3. Esiste una differenza tra questo modello e l'ORM (lo ritengo, dal momento che ORM è principalmente un wrapper di classe per ottenere dati da un database mentre questo modello è più orientato verso la struttura dei dati)
  4. Se questo è buono, può essere facilmente compreso da un nuovo sviluppatore?
posta Ubermensch 11.01.2012 - 05:48
fonte

3 risposte

3

Molto dipende dalle tue intenzioni. La serializzazione dei dati in questo modo solo per passare alla logica di business di una singola applicazione, sembra uno spreco, quando si dovrebbe passare un oggetto nativo dall'ORM all'oggetto che incapsula BL che modificherà lo stato e restituirà l'oggetto all'ORM per la persistenza .

D'altro canto, se si dispone di più applicazioni distribuite che gestiscono diversi aspetti del dominio, quindi avvolgere il DB in un'API per fornire dati serializzati (JSON o XML) è una buona idea.

Per esempio: devo occuparmi di un database legacy fornito dal fornitore piuttosto folle in cui un grosso ostacolo è l'incapacità di modificare lo schema del DB oltre all'aggiunta della vista occasionale. Ho questo DB (così come un paio dei nostri altri data store "enterprise") racchiusi in un'API REST. La maggior parte delle nostre applicazioni rivolte agli utenti, così come i demoni che monitorano il DB per determinati eventi, comunicano con l'API. In questo modo posso avere il seguente flusso di lavoro:

  1. Le classi OR / M racchiudono ciascuna una singola tabella nel DB. Un oggetto == un record.
  2. Le classi Decorator gestiscono la presentazione, inclusa la composizione di oggetti più complessi da semplici oggetti del modello.
  3. Le classi controller rispondono alle richieste con una rappresentazione JSON dell'oggetto appropriato per l'applicazione client.
  4. Clent elabora i dati, POST o PUT dell'oggetto JSON di nuovo all'API
  5. Richieste controller per salvare l'oggetto, che viene decomposto di nuovo agli oggetti del modello e mantenuto dall'O / RM.

Ciò aggiunge una notevole complessità.

Se devi gestire archivi di dati eterogenei, applicazioni distribuite, ecc., questa è una soluzione eccellente. Ma se non hai questi requisiti, la regola generale è Non ne hai bisogno.

    
risposta data 12.01.2012 - 19:00
fonte
2

I database forniscono già un formato standard per le loro risposte e i driver del database sanno già come interpretarli / usarli. I passaggi di marshalling e antagonismo di JSON sono quindi superflui se il risultato nel suo formato non verrà trasferito su un altro sistema.

Secondo me dovresti spostarti di più verso l'incapsulamento, con oggetti e strutture nativi invece di passare un frammento di dati serializzato intorno.

L'unico vantaggio che vedo è il processo di test; è possibile iniettare metodi con dati JSON casuali e non è necessario un database. Ma è una specie di grande compromesso per così tante perdite di perfomance.

    
risposta data 11.01.2012 - 08:50
fonte
2

Di solito, lavoro in lingue / ambiente che sono più vicini ai sistemi rispetto all'esempio qui, quindi la mia risposta potrebbe essere leggermente distorta. Tuttavia, c'è un concetto / modello interessante che ho trovato con molti buoni designer.

Di solito, al fine di promuovere il codice da riutilizzare, alcune cose devono essere generalizzate. Esempi classici di generalizzazione sono libri di testo esempi di ereditarietà; e ci si rende conto che una volta un'API generica per una classe di oggetti aiuta ad evolvere i sistemi. Sappiamo tutti che è bene astrarre le funzionalità comuni rispetto a quelle specifiche in questo modo.

Tuttavia, ho visto questo con molti designer che a volte provano a fare super generalizzazione . Uno degli esempi che ho visto è una classica applicazione C ++. Invece di generalizzare mantenendo i parametri più comuni specifici di una funzione astratta (virtuale), il codice esegue super generalizzazione passando i parametri come lista arbitraria di coppie nome-valore . Ora qualsiasi funzione / metodo può essere banalmente generalizzata se tutti gli argomenti / parametri rilevanti sono serializzati e passati alla funzione e de-serializzati durante l'elaborazione.

Ma una tale super generalizzazione è pessima. Non solo aggiunge un sovraccarico all'aggiunta del processo di serializzazione / deserializzazione, ma soprattutto la semantica è persa . Ora la funzione del callee può inserire parametri arbitrari e l'intera cosa inizia a essere utilizzata in modo improprio al di là del contesto. Ti imbatti anche in parametri non gestiti, errori di ortografia, parametri fuori contesto e così via; tutto questo perché non c'è modo di controllare quale tipo di parametri può entrare.

Come regola generale, sarei sempre preoccupato di super generalizzazioni ed essere piuttosto semplice .

NOTA: il modello che hai descritto sopra NON è ORM. In ORM, in genere tratti un record DB con un Oggetto equivalente che ha lo stesso attributo. La rappresentazione basata su JSON richiede ancora la traduzione in oggetto nativo prima dell'uso.

    
risposta data 11.01.2012 - 17:27
fonte

Leggi altre domande sui tag