Должны ли мы заменить каждое вхождение if-else защитными предложениями?

Я видел много сценариев, в которых замена вложенных операторов if-else на защитные оговорки оказалась допустимым и подходящим подходом. Этот метод, при разумном использовании, определенно может улучшить читаемость кода и сделать его намерения более очевидными. Однако замена каждого возможного случая if-else защитными предложениями может нанести вред кодовой базе.

При применении этого шаблона для введения защитных предложений вам может потребоваться внести некоторые коррективы в код, чтобы он лучше подходил. В большинстве случаев эти корректировки требуют замены условных выражений на их прямо противоположные, поэтому вводятся отрицательные условные выражения для использования операторов раннего возврата. Если имеется много защитных предложений (с соответствующим им оператором возврата), код может стать трудным для понимания, а номинальный путь выполнения (счастливый путь) может быть слишком скрыт, чтобы его было легко обнаружить. Следующий пример пытается проиллюстрировать этот сценарий:

Если мы сравним его с его эквивалентом if-else, конечно, мы не увидим большой разницы, так как это не причудливый пример. Тем не менее, наличие оператора else и только одного оператора return позволяет легко визуализировать каждую точку принятия решения и каждую ветвь, которые могут быть выполнены при определенных условиях:

Еще один недостаток, который может привнести этот шаблон, заключается в том, что он не позволяет включать операторы, которые должны быть написаны после случая else, или, по крайней мере, делает это более сложным. Если мы посмотрим на следующий фрагмент, то увидим, что оператор регистрации выполняется после случая else. Приняв здесь защитные оговорки, мы можем быть вынуждены переместить это утверждение в другое место:

Допустим, мы применяем к нему защитные предложения. Предположим также, что мы переместили дополнительный оператор в подпрограмму, которая вызывает исходную функцию if-else:

Если бы все эти подпрограммы были приватными методами класса, это могло бы не иметь большого значения. Тем не менее, если вы видите вызывающую процедуру и ее операторы, вы можете заметить, что теперь она связана с дополнительным оператором, который, кстати, не имеет ничего общего с его основной задачей и нарушает уровень абстракции (дополнительный оператор находится на очень низкий уровень абстракции, тогда как другие вызываемые подпрограммы - нет).

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

Просто не применяйте этот шаблон в каждом операторе if-else, который вы видите. Дважды подумайте, прежде чем что-то делать, затем сделайте это и снова прочитайте код. Спросите себя, понятно ли это и не заставляете ли вы свой код соответствовать шаблону. На самом деле, вы должны делать это с каждым шаблоном, который вы изучаете: не придерживайтесь его для каждого тривиального случая. Используйте его как удобный инструмент в своем наборе инструментов, как ресурс, а не как универсальное принятое решение.