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":
-
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. -
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.
-
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.