Как улучшить архитектуру и убрать дублирование? Вкратце, есть пользователи, у них есть роли и они привязаны к какому-то воркспейсу. На основании этих двух условий нужно проводить те или иные действия. Первая версия контроллераuserService = $userService; $this->twig = $twig; $this->authorizationChecker = $authorizationChecker; $this->security = $security; } public function index(): Response { if ( $this->authorizationChecker ->isGranted(User::ROLE_SUPER_ADMIN) ) { $users = $this->userService->getAll(); $content = $this->twig->render('admin/users.html.twig', [ 'users' => $users ]); return new Response($content); } if ( $this->authorizationChecker ->isGranted(User::ROLE_CUSTOMER_ADMIN) ) { /** @var User $user */ $user = $this->security->getUser(); $users = $this ->userService ->findByRoleAndWorkspaceId( User::ROLE_TEAM_MEMBER, $user->getWorkspace()->getId() ); $content = $this->twig->render('user/users.html.twig', [ 'users' => $users ]); return new Response($content); } throw new AccessDeniedException(); } public function read(string $id): Response { if ( $this->authorizationChecker ->isGranted(User::ROLE_SUPER_ADMIN) ) { $user = $this->userService->getById($id); $content = $this->twig->render('admin/user.html.twig', [ 'user' => $user ]); return new Response($content); } if ( $this->authorizationChecker ->isGranted(User::ROLE_CUSTOMER_ADMIN) ) { $user = $this->userService->getByIdAndWorkspaceId($id); $content = $this->twig->render('user/user.html.twig', [ 'user' => $user ]); return new Response($content); } throw new AccessDeniedException(); } } Добавятся еще другие методы crud и в них будет тоже проверка похожая данной и вызовы разных методов из сервиса. Я не уверен в правильности данного решения Я рассматриваю вариант с переносом проверки роли пользователя в сервис и вызовом соответствующего метода, а методы контроллера станут выглядеть примерно такpublic function index(): Response { $users = $this->userService->getAll(); if ( $this->authorizationChecker ->isGranted(User::ROLE_SUPER_ADMIN) ) { $content = $this->twig->render('admin/users.html.twig', [ 'users' => $users ]); return new Response($content); } if ( $this->authorizationChecker ->isGranted(User::ROLE_CUSTOMER_ADMIN) ) { $content = $this->twig->render('user/users.html.twig', [ 'users' => $users ]); return new Response($content); } throw new AccessDeniedException(); } Какой вариант более предпочтительный и какие проблемы могут возникнуть?
Оба варианта имеют свои плюсы и минусы, но перенос проверки роли пользователя в сервис может быть более предпочтительным в данной ситуации.
Плюсы:
Уменьшение дублирования кода - проверка роли пользователя будет выполнена один раз в сервисе, а не в каждом методе контроллера.Улучшение читаемости и поддерживаемости кода - логика проверки роли будет централизована в одном месте (в сервисе), что упростит его понимание и изменение.Возможность повторного использования - если в будущем потребуется использовать эту логику проверки в других местах приложения, она будет доступна из сервиса.
Однако, при таком подходе возможны следующие проблемы:
Нарушение принципа единственной ответственности (Single Responsibility Principle) - сервис должен быть ответственен за выполнение бизнес-логики, а не за проверку ролей пользователей. Возможно, стоит рассмотреть разделение этой логики на отдельные сервисы.Усложнение тестирования - при проверке роли в контроллере ее можно легко протестировать, но если она переносится в сервис, потребуется добавить дополнительные тесты для этого сервиса.
Итак, в конечном итоге, предпочтительный вариант зависит от конкретной архитектуры вашего приложения и вашего предпочтения. Важно учитывать принципы SOLID и подходить к решению проблемы с точки зрения читаемости, поддерживаемости и расширяемости кода.
Оба варианта имеют свои плюсы и минусы, но перенос проверки роли пользователя в сервис может быть более предпочтительным в данной ситуации.
Плюсы:
Уменьшение дублирования кода - проверка роли пользователя будет выполнена один раз в сервисе, а не в каждом методе контроллера.Улучшение читаемости и поддерживаемости кода - логика проверки роли будет централизована в одном месте (в сервисе), что упростит его понимание и изменение.Возможность повторного использования - если в будущем потребуется использовать эту логику проверки в других местах приложения, она будет доступна из сервиса.Однако, при таком подходе возможны следующие проблемы:
Нарушение принципа единственной ответственности (Single Responsibility Principle) - сервис должен быть ответственен за выполнение бизнес-логики, а не за проверку ролей пользователей. Возможно, стоит рассмотреть разделение этой логики на отдельные сервисы.Усложнение тестирования - при проверке роли в контроллере ее можно легко протестировать, но если она переносится в сервис, потребуется добавить дополнительные тесты для этого сервиса.Итак, в конечном итоге, предпочтительный вариант зависит от конкретной архитектуры вашего приложения и вашего предпочтения. Важно учитывать принципы SOLID и подходить к решению проблемы с точки зрения читаемости, поддерживаемости и расширяемости кода.