Обновить
1

Пользователь

Отправить сообщение
Хочу уточнить, как я понял, Вы считаете, что такой подход:

class RestrictionService
{
      //...
     public function blockUser(int $id, string $reason): void
     {
           $user = $this->repository->get($id);
           
           if ($user->isBlocked) {
                  throw new UserWasAlreadyBlockedException(); 
           } 

           $user->isBlocked = true;
           $user->blockedAt = \new DateTime();
           //more magic ...
           $user->reason = $reason;
           $user->blockedCounter++;
     } 
}

лучше чем:
$user->block($reason);

class User
{
     public function block(string $reason): void
     {
           if ($this->isBlocked) {
                  throw new UserWasAlreadyBlockedException(); 
           } 

           $this->isBlocked = true;
           $this->blockedAt = \new DateTime();
           //more magic ...
           $this->reason = $reason;
           $this->blockedCounter++;
     }
}


+ второго подхода:
  • Не нарушается инкапсуляция, в первом случае кто-то может заблокировать пользователя в обход сервиса, или же написать отдельную «похожую» логику в другом месте и при след изменениях вы получите баг, что где-то блокировка работает не так, а во втором вы четко контролируете процесс изменения состояния блокировок через определенное поведение.
  • Мне, как новому разработчику, проще разобраться, так как контракт описан в одном месте и не размазан по cервисам всего проекта.
  • Проще писать юнит тесты. Я надеюсь вы их пишете. У меня когда-то был проект, где в тестах мокали с десяток сервисов — не самое лучше занятие разгребать dependency hell, где один сервис вызывает другой, а тот третий и пятый, и так далее.
  • Первый подход больше близок к процедурному, нежели к объектному ориентированному — вы можете спокойно заменить ваши модели на массивы, а сервисы на функции (процедуры).


В наших проектах мы пишем логику и там и там, мы пишем юнит тесты на наши сущности и на сервисы, и стараемся последних писать как можно меньше и использовать больше для оркестрации действий.
Извините, но вы сами себе противоречите:
Модель — простой объект со свойствами, не содержащий бизнес-логики


Должен стремиться к соблюдению принципов GRASP, ...


Так как ваши модели полностью нарушают первый и базовый принцип — Information Expert, а логика в вынесенная в сервисы приводи к увеличению Coupling и уменьшению Cohesion.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность