Come faccio a collegare un oggetto dominio in memoria ai suoi record di database senza ingombrare il dominio con problemi di database?

7

Il tuo modello di dominio contiene un set di oggetti. Sono qui per presentare un progetto collaterale, ma ho un progetto di lavoro molto più complicato che sta cadendo in ginocchio perché non ho fatto una buona separazione del database e del dominio.

In questo caso, l'oggetto è chiamato CyclingRecord.

Seguendo Onion Architecture , gli oggetti dominio non sanno nulla della loro persistenza. Tuttavia, ognuno di questi oggetti corrisponde a una voce in un datastore (potenzialmente un database, potenzialmente un file). L'ID riga non fa assolutamente parte dell'oggetto dominio e quindi non ha alcuna attività da memorizzare nell'oggetto dominio.

data CyclingRecord = CyclingRecord { date :: Day,
                                     distance :: Float,
                                     time :: Integer,
                                     description :: Maybe String }

In un linguaggio che impone una strong immutabilità (come Haskell e Clojure), identità e valore sono sinonimi. Inoltre, non c'è motivo per cui non si possa registrare più di una corsa in un giorno. Quindi, l'intero disco descrive completamente una corsa.

Quindi, se modifico un record nel dominio, quando passo gli oggetti modificati di nuovo all'infrastruttura del database, come faccio a comunicare al database che è necessario aggiornare un particolare record invece di cancellare un record esistente?

(la stessa idea dovrebbe essere estensibile in modo che io possa avere un'applicazione che manipola potenzialmente molti record in una volta sola e poi li rimanda tutti al database. Operazioni offline o sincronizzazione o semplicemente evitando attività eccessive del disco)

A meno che la risposta corretta sia effettivamente fare qualcosa come un identificatore unico per ogni corsa. Forse un UUID. Forse aggiungi un "contatore del giorno" al record. Rendilo intrinsecamente parte di un giro in bicicletta e poi fai in modo che il database dipenda da esso invece di un ID riga separato.

    
posta Savanni D'Gerinel 01.05.2012 - 19:54
fonte

4 risposte

2

La risposta corretta è creare qualcosa come un identificatore univoco per ogni corsa. Le entità hanno bisogno di identità che, in questo caso, è davvero separata dalla combinazione di data, distanza, tempo e descrizione. Stai dicendo che queste cose possono cambiare, mentre l'identità non può.

Quindi, dai loro qualcosa di immutabile - un UUID, se vuoi.

    
risposta data 01.05.2012 - 20:57
fonte
1

Sembra che il timestamp dovrebbe essere unico, perché non usarlo come chiave primaria? Nella logica di persistenza puoi pre-eliminare (eliminare sempre qualsiasi record con lo stesso timestamp, quindi inserire) o controllare se esiste già un record e inserirlo o aggiornarlo a seconda dei casi.

In alternativa, è possibile utilizzare una sorta di decoratore o oggetto companion per contenere i metadati di persistenza. La tua logica di persistenza dovrebbe avere un modo per abbinare i metadati con il record di ciclismo e crearlo o aggiornarlo quando si mantiene il record.

Se ritieni che sia davvero necessario un ID univoco, perché non assegnare un "numero di giro"? Sembra una cosa ragionevole da registrare. Potrebbe essere un numero sequenziale, oppure potresti produrlo dal timestamp (ad es. "201205011045" per una corsa che hai preso alle 10:45 il 1 ° maggio 2012).

    
risposta data 01.05.2012 - 20:58
fonte
0

Se il database ha un identificativo univoco, non vi è alcun motivo per non includerlo come parte del modello di dominio. Anche se non ha alcun altro significato (ad esempio Numero di dipendente, nome utente, indirizzo e-mail, automobile VIN, ecc.).

Altrimenti devi fare affidamento su qualche altra combinazione di campi o contare su ogni oggetto per avere un numero univoco assegnato ad esso nel mondo reale.

Questa è la chiave per l'aggiornamento o l'eliminazione dei dati (in teoria è possibile selezionare un record con qualsiasi altro numero di campi esattamente come farebbe un utente in un modulo di ricerca). Oggetti immutabili non hanno questo problema con l'aggiornamento.

    
risposta data 01.05.2012 - 21:24
fonte
0
  • L'indipendenza di persistenza (o ignoranza, non ricordo il termine corretto) è difficile e talvolta impossibile da ottenere con determinate tecnologie. Per esempio. (LINQ to SQL in uno stack di tecnologia .NET è un no-no poiché si basa interamente sulla struttura del database). Se è così, allora devi accettarlo e conviverci.

  • Non c'è niente di sbagliato nell'aggiungere un identificatore univoco al tuo modello di dominio. Se ti rende più felice, puoi creare un'annotazione per indicare che l'attributo annotato non fa parte di un modello di dominio.

  • Per quanto riguarda i controlli per vedere se l'oggetto è cambiato, puoi aggiungere una colonna timestamp. Questo è relativamente economico. Dovresti implementare il tracciamento dello stato dell'oggetto o scegliere un framework di persistenza che possa già farlo per te.

  • Un'alternativa allo stato di tracciamento è di controllare tutte le proprietà per vedere se sono state cambiate, ma questo non è sufficiente da solo.

  • La mia domanda è se puoi giustificare un così strong bisogno di completa indipendenza di persistenza? Cercare la perfezione è buono, ma a volte devi disegnare una linea.

  • Infine, la maggior parte dei problemi può essere parzialmente se non completamente risolta dai framework di persistenza dei dati esistenti.

risposta data 01.05.2012 - 21:29
fonte

Leggi altre domande sui tag