tl;dr Can I have a repository depend on another repository, where they both implement the same interface?I am working on a website analytics system that involves getting data from different sources. One of these sources is very slow for large datasets and the other is deprecated and we are moving away from it.interface TrafficInterface{    public function getVisits(DateTime $from, DateTime $to);}I already have an interface (TrafficInterface) for retreiving the data from either source. 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 is used to access the data from the current tracking system.class LegacyTrafficRepository implements TrafficInterface{    public function getVisits(DateTime $from, DateTime $to)    {        // get old data that is stored locally    }}LegacyRepository is used to access data from the old system that is stored locally as JSON files.I want to create further repositorys that use TrafficRepository and LegacyRepository as dependencies.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 reduces the problem with the slow API. As the data from the API will not change after the current period (day, week, ...) it can be cached forever.It wraps TrafficRepository and handles adding data to the cache when it is not already there.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 handles combining data from each of the sources so we seem to have a single source for the data.Is there a a name for this system (other than copmosition)?Are there any problems associated with this?Are there better alternatives?
Should I nest repositories like Russian dolls?
design patterns;object oriented;repository;composition
Is there a a name for this system (other than copmosition)?Kind of. Having an interface, and then an implementation that implements the interface, while also wrapping another instance of the interface (your CachingTrafficRepository should really work against any TrafficInterface, not just TrafficRepository) is called the Decorator Pattern. Caching is a classic example where it can be used. Your TransitionalTrafficRepository is the classic Composite Pattern.Outside of the flexibility note above, these seem like fine cases for these patterns and you're unlikely to find better alternatives - except perhaps eliminating the need for them.