Please note: although my question relates to DDD, I am also interested in this from an architectural and OO design perspective. This question may also be a simple case of CQRS and/or interface segregation. Code examples are in Swift as this is the first language that comes to my head right this second, but this is unimportant.
Nel mio dominio, ho il concetto di Panorama
che viene scaricato e visualizzato all'utente. Implementazione-saggio: Panorama
s verrà scaricato dall'API di Google Street View, memorizzato nella cache e quindi archiviato localmente sul dispositivo.
Ho letto che va bene nascondere qualsiasi cosa un repository deve fare per raggiungere il suo obiettivo dietro la sua API pubblica - non importa se sta salvando / leggendo da un database, o da un endpoint API.
Con questo in mente, ho creato la seguente interfaccia che apparterrà al livello dominio:
protocol Panoramas
{
public function findAll(): [Panorama]
public function findOne(_ lat: Double, lon: Double)
public function delete(_ panorama: Panorama)
public function save(_ panorama: Panorama)
}
Il mio primo problema è questo: non riesco a chiamare save()
sull'API di Google Street View, né posso chiamare delete()
. Quindi il mio primo pensiero è stato "leggere e scrivere modelli" e interfacciare la segregazione.
protocol Panoramas
{
public function findOne(_ lat: Double, lon: Double)
}
protocol QueryablePanoramas: Panoramas
{
public function findAll(): [Panorama]
}
protocol ModifiablePanoramas: QueryablePanoramas
{
public function delete(_ panorama: Panorama)
public function save(_ panorama: Panorama)
}
E vorrei quindi creare le seguenti implementazioni concrete nel livello infrastruttura:
struct StreetviewApiPanoramaRepository: Panoramas { /** ... **/ }
struct InMemoryPanoramaRepository: ModifiablePanoramas { /** ... **/ }
struct DatabasePanoramaRepository: ModifiablePanoramas { /** ... **/ }
Comunque penso che mi manchi qualcosa. Panoramas
è un problema relativo al dominio. Ma Queryable
o Modifiable
: questi sono tecnici per me. È un modello comune? Vuoi nominarli in modo diverso? Come posso migliorare su questo?
-
Modifica: per peggiorare le cose, il Panorama memorizzato internamente è per un file .
struct Panorama {
public let id: Int // Unique id from the database
public let filepath: String // The location of the file on-disk
}
- Il mio archivio di caricamento del database carica i dati tramite un ORM e con il percorso del file memorizzato nel database, ho bisogno di leggere il file per restituirlo. Quindi la mia entità nel database contiene un valore
filepath
che richiede un secondo passaggio per leggere il file in memoria. - Il repository di caricamento della memoria carica semplicemente l'immagine dalla memoria.
- Il repository di caricamento api legge il file da una chiamata API.
Il problema qui è che un repository dovrebbe restituire un'entità valida. Ma in alcuni casi, ho bisogno di salvare l'immagine in un file e poi memorizzarla, in altri ho bisogno di caricare da una chiamata API.
Penso di aver incasinato il mio modello di dati qui. Per favore aiuto:)