Должен ли контроллер передавать логику сервису?

96
16 мая 2021, 15:20

Есть сервис

class ArticleService{
    function getList(array $select, string $orderedColumnName, string $orderDirection){
       return $this->repository->getAll($select, $orderedColumnName, $orderDirection)
    }
}

Есть контроллер:

class ArticleController{
    public function one(ArticleService $service){
       return $service->getList(['*'],'id','asc');
    }
    public function two(ArticleService $service){
       return $service->getList(['id','name'],'id','desc');
    }
    public function three(ArticleService $service){
       return $service->getList(['id','name','text','created_at'],'name','asc');
    }
}

Должна ли быть такая "логика" в контроллере, если нет, то как правильно организовать методы сервиса?

P.S. Параметры может передавать через какой нить DTO объект, но формировать то его придется тоже в контроллере.

Answer 1

Условно правильное решение в данном случае — делать в сервисе отдельные методы под каждый сценарий.

Если сценарии использования описаны в виде пользовательских историй, есть связь между историей и методом.

Проблема возникает, если, как вы говорите, будет 100500 разных сценариев, под которые потребуется реализовать 100500 методов. Такая ситуация указывает на сложность предметной области и на сложность вашей программы для пользователя. Убедитесь, что это не ваша проекция потребностей пользователя: 100500 сценариев означают, что пользователь для разных целей должен делать десятки разных запросов, и это обусловлено его должностными обязанностями.

Если это действительно так, то пользователю можно предоставить один универсальный метод формирования каких надо запросов. Контроллер будет получать большой DTO-объект, который можно называть параметры запроса, и на основании его станет строить запрос (паттерн query builder — построитель запросов), который затем передаст сервису.

Я предлагаю начать с простого решения (один сценарий — один метод). До десяти сценариев (до десяти методов сервиса) такое решение проблемы не представляет.

Answer 2

Вы можете реорганизовать ваши сервисы в DataMapper'ы инкапсулируя логику подготовки данных в них.

Например:

public function one(OneDataMapper $mapper) {
    return $mapper->getList();
}

В самом классе маппера внедряете ваш репозиторий, получаете с него данные и подготавливаете их для контроллера.

READ ALSO
Кэширование изображений, отдаваемых php

Кэширование изображений, отдаваемых php

Такая ситуация: у меня есть php скрипт, который проверяет авторизирован пользователь или нет и отдает изображения, хранящиеся на этом сервере

88
Почему цикл вывода статей работает только на 1 странице?

Почему цикл вывода статей работает только на 1 странице?

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

99
php изменить elements xml

php изменить elements xml

есть такой лист хмл

188
<img src(unknown)>

<img src(unknown)>

Есть такая конструкция

94