@PHPjedi

Как улучшить контроллер, метод, архитектуру?

У меня есть контроллер, который получает данные пост запросом для создания заказа.

Типов заказа есть несколько, также способ оплаты и какие-то другие нюансы также возможны. В данный момент в одном методе у меня очень много if else. Местами я надругаюсь принципами DRY. Один код повторяется несколько раз в зависимости от условий. Я хочу развиваться дальше. Подскажите, что нужно искать, читать, чтобы создавать ту архитектуру, где можно это всё разделить? Может под каждое условие создавать отдельный класс и вызывать этот самый класс?
  • Вопрос задан
  • 543 просмотра
Решения вопроса 3
AmdY
@AmdY
PHP и прочие вебштучки
Вам сейчас насоветуют создать сервисы, сделать репозитории, соединить это через интерфейсы и события. Потом залетит какой-то умник и расскажет про DDD, Saga, очереди, микросервисы.
В итоге у вас простыня спагетти кода превратится в слоёный лазанья код, с огромной избыточностью и трудностями в поддержке.

Я советую сразу начать писать тесты и начать с простых методов рефакторинга вроде извлечения метода для избавления от дублирования Ссылка удалена модератором. Есть книга Фаулера "Рефакторинг"
Начинайте с этого, тогда вы будете хотя бы понимать что и зачем делаете, а не повторять карго культ.
Ответ написан
@PiloTeZ
...
- Начните выносить логику из экшенов контроллера в сервисы
- Для упрощения, первое время можете делать по принципу "один контроллер - один сервис", "один экшен - один метод сервиса". Если используете QueryBuilder в GET экшенах, это можно не выносить в сервисы, первое время только геморой получите
- Не бойтесь разбивать конроллеры на более мелкие. Если в контроллере много экшенов, или есть повторяющиеся слова в названиях экшенов, или экшены называются более, чем 2-мя словами, часто это признак, что контроллер выполняет слишком много действий. Например есть контроллер ArticlesContrller с экшенами createArticle, updateArticle, addArticleToFavorite, deleteArticleFromFavorite. Получается дичь, он будет бесконечно разрастаться и поддержка усложнится. Например если разбить на ArticlesController (create, update, delete, deactivate) и FavoriteArticlesController (add, delete), то станет ведь гораздо проще. Так же и с сервисами. Это принцип Single responsibility
- Если метод сервиса становится слишком большим, то лучше вынести его в отдельный класс. Например есть метод Orders::create(). Создайте папку orders там же где находится сервис, в нем создайте класс OrderCreator с параметрами в конструкторе, как у метода Orders::create() и сделайте один метод create(). Заюзайте его в классе Orders::create(). Далее разбейте OrderCreator::create() на мелкие приватные методы
- Старайтесь делать методы как можно меньше, тогда они будут более гибкими и вы сможете их использовать в других местах, так же и с классами
- А вообще, зачем пересказывать книги. Просто прочитайте Фаулера Рефакторинг. Пробуйте разные описанные там принципы, и не стесняйтесь делать прямо так, как там написано. Это очень важная книга, которые выведет ваш код на абсолютно другой уровень

Дополнительно
- Рекомендую вести какой-нибудь блокнот, где брать термины и описывать своими словами. То есть постараться понять его и зафиксировать то, что поняли
- Не занимайтесь перфекционизмом. Не бывает идеального кода. Читайте теорию, пытайтесь использовать на практике. Как можно больше практики основанной на теории
- Начинайте с малого. Не надо применять и читать сразу все
- Знайте меру. Если что-то узнали, не значит, что нужно теперь применять абсолютно везде, бездумно. Если считаете, что здесь это неуместно, не используйте, даже если написано иначе
- Параллельно можно пробовать применять различные принципы: SOLID, KISS, YAGNI, DRY. Вернее не SOLID, забудьте про него вообще, первое время только голову нагружать будет, а именно Single responsibility.
- В какой-то момент применяемые принципы могут показаться бессмысленными, тогда попробуйте что-нибудь сложнее CRUD. Например сделайте свой Pat project для практики
Ответ написан
@jazzus
В первую очередь нужно использовать сервисы Ларавел. Они очень хорошо работают и постоянно улучшаются. См документацию. Далее свои классы, но не просто "тупо выносить код в сервис", а разделять классы на задачи. Все не нужно выносить в сервис, т.к. тогда без разницы, что засирать - контроллер или сервис. Лучше тогда простыня в контроллере без доп файлов. Разделяй классы на логические действия, чтобы их можно было изолированно переиспользовать. Нужно активировать юзера со сложной логикой? Класс UserActivate, который ты можешь использовать в разных местах. А не UserService, который и активирует, и удаляет, и ничем от простыни в контроллерах не отличается. Жизнь тебе не упрощает. А UserActivate упрощает, делает код легким в поддержке/рефакторинге, понятным для человеческого глаза и чистым. В такое приложение можно быстро вносить изменения, а не разгребать простыни. Простыни не из-за феншуя не любят, а потому что поддерживать их с ростом приложения все труднее. Простые по функционалу приложения превращаются в "сложнейший проект". Поэтому сервисы обязательно, но в первую очередь классы Ларавел, т.к. они покрывают большую часть потребностей.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
14 июл. 2024, в 22:10
1000 руб./за проект
14 июл. 2024, в 20:18
20000 руб./за проект
14 июл. 2024, в 20:15
10000 руб./за проект