@PHPjedi

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

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

Типов заказа есть несколько, также способ оплаты и какие-то другие нюансы также возможны. В данный момент в одном методе у меня очень много if else. Местами я надругаюсь принципами DRY. Один код повторяется несколько раз в зависимости от условий. Я хочу развиваться дальше. Подскажите, что нужно искать, читать, чтобы создавать ту архитектуру, где можно это всё разделить? Может под каждое условие создавать отдельный класс и вызывать этот самый класс?
  • Вопрос задан
  • 545 просмотров
Решения вопроса 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 упрощает, делает код легким в поддержке/рефакторинге, понятным для человеческого глаза и чистым. В такое приложение можно быстро вносить изменения, а не разгребать простыни. Простыни не из-за феншуя не любят, а потому что поддерживать их с ростом приложения все труднее. Простые по функционалу приложения превращаются в "сложнейший проект". Поэтому сервисы обязательно, но в первую очередь классы Ларавел, т.к. они покрывают большую часть потребностей.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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