Slim 3 Service Layer против внедрения зависимостей модели

Я создаю приложение с использованием фреймворка Slim 3, которое в основном состоит из динамического заполнения ряда операторов выбора раскрывающегося списка, а затем создает таблицу вычисляемых данных на основе выбора.

Первоначально я собирался придерживаться макета MVC, однако, чтобы отделить уровень доступа к данным (каждая модель обрабатывает только один элемент данных), я решил поместить бизнес-логику в сервисный уровень после прочтения Инъекция зависимостей Slim Framework 3

Он структурирован как:

  • index.php - маршрутизация и DIC, где маршруты вызываются ajax с разных веб-страниц
  • /models — содержит классы для каждого элемента данных, используемого в каждом раскрывающемся списке, например. Country.class.php, Product.class.php и т. д.
  • /controllers — содержит 2 класса InputController.class.php для обработки раскрывающихся списков и CalculateController.class.php для обработки вычислений.
  • /views — содержит php-шаблоны для возврата с ответом, используя php-views
  • /services — сервисные классы для обработки бизнес-логики и возврата данных, которые должны быть переданы для просмотра контроллером.

В DIC я пытаюсь избежать передачи контейнера другим классам, однако я столкнулся с ситуацией, когда я не уверен, как правильно внедрить зависимости.

В моем файле index.php у меня есть следующий код:

//DIC
$container = $app->getContainer();

$container['view'] = function ($container) {
    return new \Slim\Views\PhpRenderer('src/views/');
};

$container['InputService'] = function($container){

    //questionable area
    $model1 = $container->get('model1');
    $model2 = $container->get('model2');
    $model3 = $container->get('model3');

    new InputService($model1, $model2, $model3);
}

$container['InputController'] = function($container){
    $service = $container->get('InputService');
    $view = $container->get('view');
    new InputController($InputService, $view);
}

Когда конкретная веб-страница загружается, отправляется первоначальный вызов ajax, который запрашивает 2 или 3 раскрывающихся представления (поскольку первые 2/3 не зависят от других вариантов в определенных обстоятельствах). Таким образом, InputService вводится с тремя моделями. Однако, если я хочу использовать тот же класс обслуживания для работы с оставшимися раскрывающимися списками, как мне внедрить правильные модели?

Несколько мыслей, которые у меня были до сих пор:

  • Внедрение всех моделей при создании экземпляра службы, однако это будет означать создание множества избыточных объектов при каждом ее вызове.

    $container['InputService'] = function($container){
    //questionable area
    
    $model1 = $container->get('model1');
    $model2 = $container->get('model2');
    $model3 = $container->get('model3');
    $model4 = $container->get('model4');
    $model5 = $container->get('model5');
    $model6 = $container->get('model6');
    $model7 = $container->get('model7');
    $model8 = $container->get('model8');
    $model9 = $container->get('model9);
    
    new InputService( /*an array of the models*/ );
    }
    
  • Создайте другой класс обслуживания для каждого последующего раскрывающегося списка, хотя это заставляет меня задаться вопросом, должен ли я отказаться от уровня обслуживания и просто поместить бизнес-логику в модели. Однако не лучше ли было бы, чтобы классы моделей собирали данные из базы данных, не беспокоясь о том, как они затем манипулируются, поскольку в будущем разные области бизнес-логики будут использовать одни и те же данные для чего-то другого?

    контроллер1 > сервис1 > 3 модели

    контроллер1 > сервис2 > 1 модель

    контроллер1 > сервис3 > 1 модель

    контроллер1 > сервис4 > 1 модель...

    или возможно:

    контроллер1 > модель1 > 3 другие модели

    контроллер1 > модель5

    контроллер1 > модель6 ...

  • Передайте контейнер контроллеру и внедрите зависимость в службу по мере необходимости для каждого вызова.


person Gothic_Anatomist    schedule 13.02.2018    source источник
comment
... классы моделей, собирающие данные из базы данных... - плохая идея. Объекты предметной области (ваши модели) не должны знать о каком-либо уровне сохраняемости или о том, что их данные сохраняются или получаются из него. Для этой задачи вы можете использовать преобразователи данных и репозитории.   -  person    schedule 14.02.2018
comment
Последний пункт тоже плох: контейнер превратился бы в -a-needle-in-the-haystack/" rel="nofollow noreferrer">локатор сервисов для контроллера с множеством недостатков.   -  person    schedule 14.02.2018
comment
@aendeerei Спасибо за ваши комментарии. Теперь я реализовал преобразователи данных и коллекцию репозиториев, чтобы разделить задачи моделей, имеющих данные, и преобразователей, получающих их. Объекты модели теперь возвращаются репозиторием. Да, последний пункт был моим последним средством, так как я не хотел проблем с сервисным локатором.   -  person Gothic_Anatomist    schedule 15.02.2018
comment
Добро пожаловать. Да, я видел, что вы пытались избежать передачи контейнера, но я хотел дать вам большую... мотивацию. Еще немного: здесь хороший статья о модельном слое. Удачи.   -  person    schedule 15.02.2018