Iniziamo con un esempio: abbiamo un'entità: Book
. Ha un'identità univoca: Isbn
- un oggetto valore che racchiude un String
. Questo è un UUID.
Anche l'entità Book
ha bisogno di un ID surrogato dal repository (sql db). Ne abbiamo bisogno in modo che possiamo ad es. trova i libri più velocemente, poiché i database li trovano per numero più velocemente che per stringa.
Da quello che ho letto, la chiave surrogata dovrebbe essere nascosta dall'interfaccia Book
s. Ma vogliamo usarlo per localizzare i libri molto più velocemente.
Come gestirlo correttamente?
[A] Possiamo semplicemente aggiungere un getSurrogateId()
(o qualsiasi altro nome migliore) in Book
. Questo inquina l'entità, ma il suo KISS.
[B] Possiamo far sì che il repository sia responsabile della ricerca delle chiavi surrogate per quelle naturali. Ad esempio, BookRepository
può avere il seguente metodo:
long toSurrogateKey(Isbn isbn) {
// lookup the cache
// if not found, lookup the db
}
per restituire la chiave surrogata - ovviamente, questi valori possono essere memorizzati nella cache localmente, quindi non abbiamo bisogno di cercare db ogni volta. Questo metodo non dovrebbe essere public
(a destra)?
[C] Possiamo andare ancora oltre: pensare alla chiave surrogata come a uno specifico repository. Book
può essere un'interfaccia e SqlBook
può essere un'implementazione creata dal repository. Questa implementazione di SqlBook
può quindi memorizzare tutte le ulteriori informazioni necessarie per il repository. In questo caso, avremmo la chiave surrogata come una delle proprietà di SqlBook
e non ci interessa che sia visibile, poiché gli utenti di SqlBook
la vedono solo come Book
, ovvero non conoscono la surrogata id.
Quindi sopra il metodo diventa (definito in SqlBook
classe):
long toSurrogateKey(Book book) {
return ((SqlBook)book).getSurrogateId();
}
L'unico svantaggio è che Book
(e altre entità) devono essere creati da una Factory che sia consapevole del repository. In altre parole, dovremmo avere un'implementazione di SqlFactory
di un factory che crea SqlBook
s per noi.
Qualche saggezza su questo?