Автор Тема: Вопрос по архитектуре.  (Прочитано 141 раз)

0 Пользователей и 1 Гость смотрят эту тему.

Оффлайн metsys

  • Новичок
  • *
  • Сообщений: 1
  • Карма: 0
Вопрос по архитектуре.
« : Март 05, 2017, 13:31:02 »
Добрый день.
Возникла необходимость вникнуть в zf2. До этого работал с Yii/Yii2. Там имеется такое понятие как компоненты, с помощью которых можно было легко осуществить работу с paypal или mailchimp api. Всё в Yii связано везде и всюду.

Тут же я создал какой то совсем простой модуль работающий с табличкой в БД. Но так же мне нужно создать сервис который будет работать с апихой - получать данные и писать в таблицу.
После обновлениея mvc начало ругатся на getServiceLocator() в контроллере, так что я решил от него избавиться и создать factory:

public function createService(ServiceLocatorInterface $controllerLocator)
    {
        
/**
         * @var ServiceLocatorInterface $serviceLocator
         *
         * @return SubscriberController
         */
        
$serviceLocator $controllerLocator->getServiceLocator();

        return new 
SubscriberController(
            
$serviceLocator->get('Subscriber\Model\SubscriberTable')
        );
    }


сам контроллер:
/**
     * @var SubscriberTable
     */
    
private $subscriberTable;

    
/**
     * @param $subscriberTable
     */
    
public function __construct(SubscriberTable $subscriberTable)
    {
        
$this->subscriberTable $subscriberTable;
    }

    public function 
indexAction()
    {
        return new 
ViewModel([
            
'subscribers' => $this->subscriberTable->fetchAll(),
        ]);
    }


Что я хочу сделать:
  • Интерфейс для компоненты которая будет работать с API
  • Несколько компонент( я так понимаю в zf2 это сервис), которые можно будет переключать в конфиге для общения с разными API сервисов предоставляющих схожие услуги

Как мне правильно заимплементить сиё чудо. Стоит мне создавать эти сервисы в моём же модуле subscriber или делать в отдельном модуле. Как мне правильно прокидывать полученные данные в Subscriber\Model\SubscriberTable? Если я правильно понимаю то данные надо получать и сохранять в контроллере, то есть в фабрике контроллера я должен передать и сервис работающий с бд и сервис работающий с API? И если Сервис API будет в одном модуле, а сервис работы с таблицой БД в другом модуле, то как это вообще правильно сделать не опускаясь до уровня getServiceLocator()?

Оффлайн yanak

  • Опытный
  • ***
  • Сообщений: 89
  • Карма: 4
Re: Вопрос по архитектуре.
« Ответ #1 : Май 07, 2017, 13:32:02 »
Трудно ответить. В зенде нет понятия "Компонента", поэтому не ясно что имеется ввиду. По логике организации кода - есть такая штука как разделение кода с логикой приложения на слои http://design-pattern.ru/patterns/service-layer.html.

Каждый слой знает о слое ниже и о классах из своего слоя, но не знает о слоях выше. В вашем случае Table - это источник данных - самый нижний слой. Он вообще ничего не должен знать - только о том как сохранять в свою таблицу и как из нее получать.

Если я правильно все понял, то вам нужно создать сервис "Подписка", в фабрике этого сервиса передать ему сервис, который работает с внешним АПИ и второй зависимостью - вашу таблицу. Сам сервис подписки прокинуть в контроллер.

Выйдет, что контроллер - знает только о сервисе подписки, и вызывает у него метод сабскрайб. Сервис знает только о своей зависимости по работе с внешним сервисом и дергает у нее какой-то метод. Полученные данные отправляет в виде Сущности в таблицу, которая сохранит сущность. В общем, как-то так.

Чтобы сервису подписки можно было поставить другую зависимость для работы с внешним сервисом, то вводим для внешних сервисов общий интерфейс, и к нему приводим все классы, которые работают с внешними сервисами. И потом в фабрике выставляем нужный, ну или создаем несколько фабрик (по числу внешних сервисов), и в конфиге выставляем для создания класса - нужную.