Не могу правильно подобрать архитектуру для задачи, пишу что-то наподобии агрегатора сайтов.
Есть модель Account c такими полями: login, password, provider_name
Есть класс Manager, в конструктор которого передается модель Account. В классе Manager есть метод getProvider(). Который инициализирует и возвращает объект класса Provider в соответствии со значением свойства provider_name в модели Account.
На каждый агрегируемый сайт есть свой класс Provider который может имплетировать интерфейсы например: ProfileInterface, MessageInterface, NewsInterface и т.д.
Интерфейсы описывают основные методы для работы с сайтом. Что бы можно было работать в цикле (при помощи конструкции instanceof) с разными сайтами не думая о том что происходит внутри класса Provider.
Так вот получается что когда класс Provider имплементирует несколько интерфейсов - то все хорошо, но когда количество имплементируеммых интерфейсов становится больше 5-10, то файл становится не читаемым, слишком много методов в классе Provider.
Допустим есть такие провайдеры:
Social/VK/ProviderSocial/OK/ProviderSocial/Facebook/Provider
Класс Manager получая в конструкторе объект Account по полю provider_name находит нужный Provider, например
Social/VK/Provider и инициализирует его и возвращает объект Provider. То есть проводится авторизация на сайте Вконтакте в конструкторе класса Provider.
Дальше есть задача получить новости со всех аккаунтов:
foreach($accounts as $account) {
$provider = Manager::getProvider($account);
if ($provider instanceof NewsInterface) {
$news = $provider->getNews();
//...
} else continue;
}
Я первым делом вспомнил про трейты, но дело в том что методы из разных интерфейсов могут использовать друг друга (например трейт описывающий реализацию интерфейса MessageInterface использует трейт описывающий реализацию интерфейса ProfileInterface). Да и почти в каждом трейте идет работа с БД коннект которого находится в свойстве объекта Provider.
В общем трейты работают, но не эстетически красиво. Я уверен что есть более красивая реализация, только не могу ее найти.
Заранее спасибо за любое замечание и предложение =)