Controlla (evita) la modifica dei campi con effetti collaterali

0

Ho pensato a un problema di progettazione e alle possibili soluzioni nel mio. Sono abbastanza sicuro di non essere il primo ad averlo notato, ma non posso cercarlo su Google perché non conosco la denominazione standard dei diversi partecipanti.

NON è il modello di stato.

Il mio problema è che, quando si ha a che fare con ORM, finisco spesso con qualcosa del genere

Employee 
-------- 
Id       
Name     
Surname
BirthDate
DefunctionDate

E usando una mappatura di oggetti relazionali (nel mio caso JPA), termino con due entità, Employee e Contract .

Ora, la maggior parte dei campi di Employee sono solo "intranscendenti" (* 1). In realtà non influisce sull'applicazione se il nome del dipendente cambia da "John" a "Mike". Finché ho messo qualche convalida per i campi di input. Ma se, per esempio, defunctionDate cambia da null a qualche data, è necessario eseguire una logica (ad esempio, chiudere i contratti correnti, revocare l'accesso al sistema, ecc.). Chiamerei quei termini "trascendente" (* 1).

Il primo passo sarebbe aggiungere una specifica operazione che imposta tale campo setDefunctionDate e gestisce tale logica, e io sono d'accordo. Il problema che appare è come garantire che i campi non vengano aggiornati durante l'aggiornamento dei dati "cargo".

Vedo tre opzioni "facili":

  1. Ignora le modifiche in un bean: se ho un metodo update(Employee employee) , ogni volta che si esegue il metodo dovrei recuperare l'oggetto dal DB e impostare il campo "trascendente" ( defunctionDate ) del oggetto con il valore dall'oggetto memorizzato nel DB. Quel "recuperare l'oggetto dal DB" significa uno o più accessi extra al DB, che non sono una buona cosa. Inoltre, questo ha dei problemi quando c'è una cascata di modifiche.

  2. Pattern "Observer": Like 1., ma in questo caso si trova una modifica in una modifica "trascendentale" che viene attivato un listener che gestisce la logica extra.

  3. Un'altra possibile soluzione è avere un metodo per ogni campo nell'entità, ma penso che di solito sarà troppo prolisso e interromperà lo scopo di avere un ORM.

Delle opzioni precedenti, I cosa 2) sarebbe il migliore, ma non mi piace ancora il fatto degli accessi extra al DB anche quando non è stato modificato alcun campo trascendente.

L'unica soluzione che posso pensare sarebbe spostare quei campi "trascendentali" in un'entità separata, che sarebbe in una relazione uno a uno con l'entità originale. Qualcosa come

Employee
--------
Id                   Employee_Trascendent
Name       --------> ---------
Surname              Employee_Id
BirthDate            DefunctionDate

L'API consentirebbe solo la modifica diretta dell'entità Employee e DefunctionDate sarebbe modificato solo da un metodo API specifico.

Detto questo, trovo la mia soluzione un po 'complicata e, dato che non riesco a vedere alcun riferimento a qualcosa di simile, penso che forse mi manca una soluzione più ovvia.

Desidero il tuo aiuto per determinare i termini corretti per cercare idee e, se il motivo per cui propongo ha un nome, il suo nome.

* 1: Se conosci un termine migliore, per favore dimmelo, ricorda che non conosco la terminologia corretta.

    
posta SJuan76 17.11.2014 - 10:24
fonte

1 risposta

1

Come la vedo io, l'ORM non crea gli effetti collaterali, fa il tuo codice. Se chiedi a un ORM di salvare un'entità, lo fa, senza eseguire operazioni aggiuntive o dovrebbe esserci un trigger di database di qualche tipo, a mio parere personale dovresti rimuoverlo per avere più controllo nel tuo programma.

Pertanto, non preoccuparti di salvare la tua entità più volte (forse una volta nella creazione di un Impiegato una volta che conosci il nome, il cognome, la data di nascita, ecc., e poi più avanti in una fase successiva). Se il tuo programma gestisce l'immissione di queste informazioni in più passaggi, allora dovrebbe essere salvando man mano che procedi. Lo stress che metti sul database è solo leggermente superiore a quello che sarebbe altrimenti, e guarda cosa guadagni in cambio: stabilità e semplicità. Queste sono due materie prime che valgono molto di più delle prestazioni e sceglierei un programma stabile e semplice con un leggero calo delle prestazioni su un programma veloce e instabile e complicato in qualsiasi giorno della settimana.

Ti suggerisco di usare l'opzione 4. Hai una sezione dbo nel tuo programma che esegue l'effettivo dovere di salvare un Dipendente. Vi si accede da diverse aree del vostro programma, vale a dire quando è necessario aggiornare le informazioni su un Dipendente che non creerà effetti collaterali e quando è necessario aggiornare le informazioni su un Dipendente che creerà effetti collaterali. In quest'ultimo caso, dovresti eseguire tutti gli effetti collaterali in una transazione in modo tale che se gli effetti collaterali o il salvataggio effettivo di Employee falliscono, non viene fatto nulla.

Il dbo dovrebbe fornire solo i mezzi per eseguire il salvataggio nella propria transazione o come parte di un'altra transazione, ma non dovrebbe sapere quali effetti collaterali derivano dal salvataggio di Employee.

Spero che risponda alla tua domanda.

    
risposta data 17.11.2014 - 12:20
fonte