Коротко: глубокая вложенность if снижает читаемость; лечится инвертированными проверками и ранними выходами, которые уплощают код.

Большая вложенность if-ов и других конструкций — это реальная проблема: в крупном проекте такие места резко снижают читаемость и поддерживаемость. Лечится она «инвертированными проверками» (ранний выход), которые уплощают код. Разберём на условном примере — представляйте, что в реальности логика в разы сложнее: вызываются разные классы, методы и так далее.

Не всем очевидно, что глубокая вложенность — это беда. Но когда продукт большой и таких мест много, проблема становится ощутимой. Рассмотрим плохой пример «на кошках»:

PHP-функция getSurpriseArrayIfAvailable с глубокой вложенностью из шести if/else — «стрелка» кода

Даже без дополнительной логики он выглядит плохо — 6 уровней вложенности. А теперь представьте, что между if-ами есть ещё if-ы и вызовы сторонних функций из сторонних библиотек.

Усложним:

Та же PHP-функция с вызовами getSomeAwesomeDataFromDB внутри вложенных if — усложнённый вариант

Представьте, что логика ещё ветвистее и сложнее — как обычно и бывает в реальных проектах, даже не очень сложных.

Как уменьшить вложенность?

Есть очень действенный приём — инвертированные проверки, которые разительно сокращают вложенность. Применим их к «грязному» коду: каждая проверка теперь отталкивается от обратного, ведь мы всё равно должны прийти к одному сценарию.

Сначала уберём все else — они не нужны и только растягивают код:

Рефакторинг PHP-функции: убраны else-ветки, единый return [] в конце, вложенность сохранена

else можно не писать вовсе, если в if стоит return.

Теперь инвертируем проверки — начнём с переменной $a:

PHP-функция после разбиения условий на отдельные блоки if с ранними выходами, вложенность уменьшена

И так же переделаем проверки остальных переменных:

Финальный рефакторинг PHP: плоская структура из независимых if с guard-clauses и ранними return

В итоге вместо 6 уровней вложенности получился 1. Читаемость заметно выросла: код проще читать и понимать, а возвращаемые значения легче контролировать (не нужно искать, что делает return в else на четвёртом уровне вложенности).

На этом примере выгода, возможно, не так очевидна. Но когда проект большой, переменные называются не $a, а, например, $unholdedOperationsFromDwhSortedByTransactionTypeId, и вызовов методов в разы больше, — приём сыграет огромную роль и при написании, и при дальнейшей поддержке кода.