DoctorX
@DoctorX
Веб разработчик

Когда имеет смысл вместо сервисов использовать «обычные» классы?

Недавно начал знакомство с fw Symfony.
Как я понимаю большинство кода в проекте живёт в сервисах - глобальных классах которые подгружают друг друга как зависимости.

Есть задача:
Обойти таблицу в бд и для каждой извлечённой строки выполнить некоторую работу.

Написав сервис я обнаружил что он содержит:
конструктор куда помещаются зависимости (две фабрики и EntityManager),
Один публичный метод который принимает два параметра (пока) Entity из базы и ещё один внешний обьект.
И кучу приватных методов в которые эти два параметра и путешествуют. (именно этот момент с кучей методов практически одинаковой сигнатурой меня и смущает. Однако добавить эти параметры в конструтор я не могу. Так они не статичны а беруться из базы и мне необходимо выполнить метод)

В обычной ситуации я бы сделал класс который принимает два необходимых ему параметра в конструктор, зависимости подтягиваются синглтоном и приватные методы берут параметры из свойств.
Но это не соответствует парадигме фреймворка.

Я вижу такой вариант:
Сделать сервис - фабрику который будет на основании этих двух динамических параметров генерировать новый объект описанный абзацом выше. И при этом будет импортировать все зависимости в этот объект.

Насколько корректен такой вариант относительно первого?
Смущает количество параметров для конструктора этого нового объекта (и зависимости и параметры).

Вопрос был поднят так как я хочу логгировать каждую работу на данными отдельно. А это значить что мне надо передавать в исходный сервис ещё один параметр - логгер. И таскать его по приватным методам.
Либо просто добавить метод setLogger к объекту описанному во втором варианте.

Спасибо.
  • Вопрос задан
  • 2715 просмотров
Пригласить эксперта
Ответы на вопрос 2
@shoomyst
dumb
Нормальный код на первый взгляд.
Ну можно getBySource() вызывать в public методе, тогда можно два параметра заменить одним. Ну это уже если совсем заняться нечем.
Ну а логгер в вашем коде должен передаваться в конструктор и храниться в свойстве
Ответ написан
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Но это не соответствует парадигме фреймворка.

Это нарушает принципы инверсии зависимостей а не "парадигме фреймворка". По сути такие вот штуки ломают принципы ООП и все best-practice которые навыдумывали всякие java-разработчики (и не только java) за последние 20 лет.

Когда имеет смысл вместо сервисов использовать «обычные» классы?

Сервисы - это и есть "обычные" классы. Просто за создание этих классов отвечает отдельный компонент, он один умеет всех создавать и разруливать зависимости что бы вам не пришлось это делать руками. Другой вопрос что если взять какой PHP-DI то он это делает чуть удобнее (за счет автоконфигурации на основе нэймспейсов).

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

Словом... все это не Symfony-specific штуки, это классическое ООП и только. Если вы распишите задачу чуть по подробнее (хотя бы на уровне интерфейсов) уже можно будет подсказать что-то конкретное. Пока я не вижу ничего плохого в куче приватных методов. Главное что бы интерфейс чистым был. Что-то на уровне:

interface EntityProcessor
{
    public function process(Entity $entity);
}
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы