Come gestire i campi calcolati complessi in un ORM

8

Nella nostra API abbiamo alcuni tipi di dati centrali che devono essere "decorati" (per così dire) dopo il recupero dal database con i valori calcolati. Si accede al database tramite un ORM che segue una dinamica Tabella / Entità strongmente ispirata al livello del database CakePHP 3, in cui un oggetto Tabella viene utilizzato come intermediario tra il database e l'applicazione che accetta e distribuisce le righe come istanze dell'oggetto modello. Quindi, invece di recuperare i dati dal database e restituirli, è necessario sottoporre a pre-elaborazione i dati restituiti prima che sia effettivamente utilizzabile. Ecco alcuni casi d'uso che sono venuti per spiegare meglio cosa intendo:

  • Gli oggetti hanno valori numerici che vengono tradotti in etichette user-friendly (normalmente questa è una logica che manterrò esclusivamente sul client, ma per ragioni di sicurezza aziendale alcuni di questi dati devono essere tenuti solo sul server, un po 'di un caso limite)
  • Gli oggetti devono avere un valore di valutazione associato che viene estratto dall'ultima valutazione aggiunta
  • Basato su una combinazione di valori calcolati come questo e valori memorizzati, viene costruito un oggetto di pianificazione complesso

Da soli, ognuno di questi individualmente è in realtà piuttosto semplice da eseguire con una semplice operazione map() sul set di risultati restituito. La stessa cosa vale quando vuoi più valori calcolati, puoi semplicemente fare più operazioni sulla mappa per calcolare e aggiungere quei campi se necessario.

Detto questo, questo approccio ha due principali svantaggi:

  1. Significa che devi eseguire un ulteriore passaggio di postelaborazione ovunque desideri lavorare con questi valori calcolati, che non sono particolarmente ASCIUTTI
  2. Alcune di queste trasformazioni dipendono da altre trasformazioni che vengono eseguite per prime, altrimenti non hanno i dati disponibili per lavorare con

Per gestire entrambi, ho pensato che l'approccio migliore sarebbe stato spostare questo codice nell'ORM, quindi modificare l'ORM in modo che l'interfaccia consenta (esternamente) l'accesso ai campi virtuali calcolati allo stesso modo in cui tratta con colonne del database. Internamente potrebbe quindi mappare questi campi virtuali alle funzioni di trasformazione e determinare internamente eventuali trasformazioni di dipendenza necessarie per risolvere il secondo problema.

(Per inciso, mi chiedo se questo rimuova anche la necessità che le righe restituite siano oggetti reali anziché semplici hash. In questo momento ogni riga crea un nuovo oggetto con il set di dati del campo su di esso, ma se tutto il calcolo o la modifica dei dati viene spostato fuori dal modello, quindi l'oggetto diventa semplicemente un sacchetto di proprietà - una hashmap, essenzialmente, senza una propria logica interna. Che potrebbe non essere effettivamente una cosa negativa, credo)

    
posta moberemk 29.06.2015 - 17:36
fonte

2 risposte

3

Puoi utilizzare il livello repository per i casi sopra citati.

[Repository] Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

Un repository per caso, che utilizza ORM per leggere i dati, li arricchisce e restituisce.

Quindi, avresti un modo unificato per accedere a tali istanze e nascondere il modo in cui tali istanze vengono create dall'esterno. Inoltre, ciò consentirebbe di passare da ORM a query SQL raw senza modificare l'interfaccia esposta.

    
risposta data 23.03.2016 - 23:33
fonte
0

Sono d'accordo con @potfur. La divisione tra gli "oggetti dati", che rappresentano i dati nel database e la loro rappresentazione "aziendale", che incapsula logica aggiuntiva, calcolo, ecc., IMHO è la giusta direzione. Il modo in cui i dati vengono rappresentati per un determinato dominio / azienda e ciò che viene archiviato tecnicamente, può essere completamente diverso. L'implementazione della logica di business con oggetti che rappresentano il dominio aiuta ad aggiungere il valore per il cliente e facilita la comunicazione. Per quanto riguarda l'ORM, si menzionano problemi di scalabilità. Penso che un ORM sia un anti-modello. Sebbene sia molto utile in scala ridotta / media, quando si parla di scalabilità, inizia a fallire. Quello che potresti fare è aggiungere un livello di memorizzazione nella cache per le "entità aziendali", quindi non devi calcolarli ogni volta.

    
risposta data 26.03.2016 - 22:25
fonte