tl; dr Posso avere un repository dipendente da un altro repository, dove entrambi implementano la stessa interfaccia?
Sto lavorando su un sistema di analisi dei siti web che implica l'acquisizione di dati da fonti diverse. Una di queste fonti è molto lenta per dataset di grandi dimensioni e l'altra è deprecata e ci stiamo allontanando da essa.
interface TrafficInterface
{
public function getVisits(DateTime $from, DateTime $to);
}
Ho già un'interfaccia ( TrafficInterface
) per recuperare i dati da entrambe le fonti.
class TrafficRepository implements TrafficInterface
{
private $client;
public TrafficRepository($apiClient)
{
$this->client = $apiClient;
}
public function getVisits(DateTime $from, DateTime $to)
{
// get data from an API
}
}
TrafficRepository
viene utilizzato per accedere ai dati dal sistema di monitoraggio corrente.
class LegacyTrafficRepository implements TrafficInterface
{
public function getVisits(DateTime $from, DateTime $to)
{
// get old data that is stored locally
}
}
LegacyRepository
viene utilizzato per accedere ai dati dal vecchio sistema che è archiviato localmente come file JSON.
Voglio creare altri repository che utilizzano TrafficRepository
e LegacyRepository
come dipendenze.
class CachingTrafficRepository implements TrafficInterface
{
private $repository;
public CachingTrafficRepository(TrafficRepository $repository)
{
$this->repository = $repository;
}
public function getVisits(DateTime $from, DateTime $to)
{
// check the cache for data, delegate to the repository if not
// return data
}
}
CachingRepository
riduce il problema con l'API lenta. Poiché i dati dell'API non cambieranno dopo il periodo corrente (giorno, settimana, ...), potranno essere memorizzati per sempre nella cache.
Incorpora TrafficRepository
e gestisce l'aggiunta di dati alla cache quando non è già presente.
class TransitionalTrafficRepository implements TrafficInterface
{
private $legacy;
private $caching;
public TransitionalTrafficRepository(LegacyTrafficRepository $legacy,
CachingTrafficRepository $caching)
{
$this->legacy = $legacy;
$this->caching = $caching;
}
public function getVisits(DateTime $from, DateTime $to)
{
// get data from the relevant repository
// combine data and return
}
}
TransitionalRepository
gestisce la combinazione di dati da ciascuna delle fonti in modo che sembriamo avere un'unica fonte per i dati.
- Esiste un nome per questo sistema (diverso dalla composizione)?
- Ci sono dei problemi associati a questo?
- Ci sono alternative migliori?