zaartix
@zaartix

Сервис с переведенным словарем параметров. Что-то не так?

Есть сервис (предположим StaticList), где хранятся всякие списки параметров, к примеру:
public static function getCommissions()
    {
        $list = [
            [
                'key' => self::COMMISSION_NO_PROXY,
                'name' => self::$translator->trans('_No proxy phone, no commission_'),
                'projects' => ['all']
            ],
            [
                'key' => self::COMMISSION_ANSWERS,
                'name' => self::$translator->trans('_Commission_'),
                'projects' => ['1']
            ],
        ];
        return $list;
    }

там в качестве значения key - константы, которые иногда в контролерах достаются и сверяются, поэтому оно статик.
В некоторых моделях я использую методы, вроде getCommissionText, которые возвращают уже не ключ, записанный в базе, а по ключу достают текстовое значение из этого сервиса. Соответственно единственный способ достучаться до сервиса из сущности (модели), это статичный вызов метода, вроде StaticList::getTextForKey($this->commission_key)

Есть у меня стойкое ощущение, что я творю дичь и можно как-то корректнее организовать эту схему, т.к. много проблем возникает из-за статичных вызовов этого сервиса (например конструктор не вызывается, соответственно нет интерфейса translator из-за этого).
Резюмирую:
Должен быть файл с листингом параметров, их переведенных (локализованных) названий и должен быть способ из модели (сущности) легко доставать сразу текстовое локализованное значение параметра.

Как бы вы решили эту задачу?
  • Вопрос задан
  • 38 просмотров
Решения вопроса 1
@dosim86
Существующий подход вполне уместен, т.к. доступ к сервису из модели - это плохая практика и отображение локализованного текста из модели - это не задача модели, хотя поле name можно изменить на тип json в СУБД.

В данном случае рекомендую переименовать сервис StaticList на ComissionManager и не делать статическим методы getCommissions и getTextForKey, т.к. конструкция self::$translator все равно требует начальной ручной инициализации объекта класса Translation, то пусть этим занимается неявно сам конструктор. Далее уже сервис ComissionManager достаточно внедрять как зависимость в нужном методе контроллера и вызывать $сomissionManager->getTextForKey($model->commission_key), подставляя модель явно, но можно короче и гибче $сomissionManager->getText($model).

Конечно можно пойти дальше и создать интерфейс ComissionInterface c методом getKey и добавлять его к моделям, которые будут работать с комиссиями. Тогда реализация метода getText будет выглядеть так:
public getText(ComissionInterface $model)
{
    $key = $model->getKey();
    $text = ...
    return $text;
}

Таким образом сервису ничего не нужно знать о моделях, т.к. достаточно того, что они реализуют интерфейс ComissionInterface, который гарантирует, что метод getKey точно будет в модели. Т.е. абстрагируемся от конкретных классов моделей.

У Вас типичная ситуация когда люди пытаются решить проблему одним большим методом или классом. Следуйте принципу единственной ответственности класса и метода.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
REDSTART Калининград
от 80 000 до 100 000 руб.
от 90 000 до 160 000 руб.
Радюшин и Компания Тольятти
от 50 000 до 100 000 руб.
20 янв. 2019, в 00:12
16000 руб./за проект
19 янв. 2019, в 23:33
110000 руб./за проект