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 из-за этого).
Резюмирую:
Должен быть файл с листингом параметров, их переведенных (локализованных) названий и должен быть способ из модели (сущности) легко доставать сразу текстовое локализованное значение параметра.

Как бы вы решили эту задачу?
  • Вопрос задан
  • 40 просмотров
Решения вопроса 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 точно будет в модели. Т.е. абстрагируемся от конкретных классов моделей.

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

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

Войти через центр авторизации
Похожие вопросы