DPhil
@DPhil
Контент-менеджер

Насколько хорошая практика передавать в метод имя класса, который его вызывает?

Допустим, в CRM есть внутренний мессенджер, в нем есть две роли, условно "Начальник" и "Подчиненный", которые различаются деталями реализации. Соответственно, два контроллера: ControllerHead, ControllerEmployee.

Модель одна: Messenger. В базе messengers есть два поля, обозначающие статус прочтения сообщения: head_is_read, employee_is_read.

Я могу:
1. Реализовать два метода в модели setHeadIsRead и setEmployeeIsRead,
2. Реализовать один универсальный метод setCompanionIsRead($selfClassName) и в контроллере вызова передавать в него имя этого самого вызывающего контроллера, чтобы в методе определить, какое поле в базе изменять.

Насколько хорошая практика, изложенная во втором способе? Насколько хорошая практика передавать в метод имя класса, который его вызывает?
  • Вопрос задан
  • 201 просмотр
Решения вопроса 1
@Akela_wolf
Extreme Programmer
Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете.
С. Макконнелл


Первый вариант понятен. Вы поиском сможете найти откуда каждый метод вызывается. Имя метода четко указывает что он делает.

Второй вариант - непонятен. Во-первых, имя метода ни о чем не говорит. Чтобы понять что он делает - придется читать сам метод. Во-вторых при поиске мест вызова нужно будет постоянно проверять контекст - что за параметр передан в этот метод? А если он будет вызываться из класса-наследника одного из контроллеров? А если будут использовать трейты? А если код будет вынесен в делегат? Очень много сложностей для решения настолько простой задачи.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
vitaly_74
@vitaly_74
Проблемы которые вы можете получить используя второй вариант описал Михаил
Предложил бы реализовать второй вариант таким способом:
messages:
to | from | date | is_read
а в модельку добавить метод:
makeARead(): void;
в конструктор модельки можно передать id сообщения.
тогда если использовать ваш код то можно сделать так:
$message = new Message ($messageID)
$message->makeARead();

а создавать сообщение так:
$messages->addMessage(From, To);
если нужно сделать список сообщений прочитанными сделайте декоратор для $messages, например:
$messages = new MakedARead(
   new Messages(
      $conditionOfMessages
   )
)
return $messages->list(); //Здесь в цикле делаем все сообщения прочитанными.

Плюсы такого подхода: можно добавлять функционал на лету, не изменяя старый код, а также можно соответствовать принципам SOLID
Можно, конечно как предложено в первом ответе, вполне себе будет работать, и тут нет ничего плохого.
Ответ написан
Комментировать
Если не боитесь нагружать модель бизнес-логикой - можно сделать метод:
readBy(User $user)
И уже внутри проверять начальник это или подчинённый, и проставлять соответствующий флаг.
Ответ написан
Ваш ответ на вопрос

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

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