В большинстве случаев наличие нескольких условных выражений внутри функции и множества уровней вложенных отступов делает исходный код таким утомительным в обслуживании, трудным для чтения и быстро непонятным — пирамида гибели.

В предыдущем эпизоде мы рассмотрели, как выйти из цикла, не нарушая правило объектной гимнастики: Только один уровень отступа на метод! В этой статье мы обсудим два примера вложенных ЕСЛИ и попытаемся шаг за шагом объяснить, как избавиться от всех этих условных структур.

Пример 1: Введение функции утверждения

Давайте погрузимся в первый пример и посмотрим, как изменить структуру кода, чтобы удалить все вложенные IF:

Для простоты я выбрал простой пример с тремя вложенными ЕСЛИ.

В нашем случае условные предложения очень простые, но мы можем представить и более сложные. Тем не менее, извлечение условий в переменные не может быть подходящим решением и может потребовать больше тестов, чем необходимо:

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

Это утверждение простое и, кроме того, возвращает результат isTrue.

Если бы функция run() вернула логическое значение, чего здесь нет, мы могли бы сжать код, чтобы он уместился в одну строку.

«когда» может быть статическим и не связанным напрямую с соответствующим классом или файлом.

Как только мы вводим функцию утверждения, мы заменяем все вложенные условия следующим образом:

Если нам все еще нужно сохранять константы, когда условия слишком сложны, мы можем сделать следующее:

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

Пример 2 — Замена IF на Math.max

Другой элегантный способ замены условных выражений может быть реализован путем проверки и возврата максимум нескольких результатов. Например, рассмотрим следующий код:

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

Итак, как мы можем устранить все эти ЕСЛИ?

В этом случае мы можем начать извлекать условия в константы, чтобы позже использовать Typescript Accessors:

SonarQube выдаст предупреждение, если мы используем более трех операторов return. По этой причине я исключил это решение.

Теперь у нас есть константы, мы перемещаем их в аксессоры следующим образом:

Одновременно я добавил позицию и коэффициент как свойства класса:

Однако я хотел бы изменить все геттеры, чтобы вместо логического значения возвращалось количество выходных:

Очевидно, имя функции было изменено, чтобы отразить нашу цель.

Теперь, когда у нас есть количество выходных для всех геттеров, замена условных выражений на Math.max становится простой:

Резюме

Как мы видим, в обоих примерах наш исходный код стал более читабельным и чистым. Ведь наша главная цель — написать красивый код — который работает 😉— .

Я не упоминал модульные тесты во время рефакторинга, потому что это выходит за рамки этой статьи, однако модульные тесты необходимы и должны сопровождать весь процесс рефакторинга.

Полный исходный код примера 2 можно найти здесь: https://github.com/elie29/if-elseif.

Каждый шаг имеет свою выделенную ветку.

Не стесняйтесь оставлять мне свои отзывы или писать мне в Твиттере @elie_nehme