Много составляющих в if - - Признак плохого кода #6


3 3

Не люблю, когда в операторе if производиться много проверок, даже если их отсортировали по смыслу. Даже если я знаю, что проверки отсортированы, мне все равно приходиться думать, а что каждая из них делает.

func foo (something) {
   if (something.isActive &&
      something.StartDate < DateTime.Now && 
     (something.EndDate == null ||  something.EndDate > DateTime.Now) &&
     User.CurrentUser == something.Creator && canEdit(something)) {
   }
}

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

func foo (something) {
   bool isActive = something.isActive && something.StartDate < DateTime.Now && 
     (something.EndDate == null ||  something.EndDate > DateTime.Now);

   bool hasAccess =   User.CurrentUser == something.Creator && canEdit(something);

   if (isActive && hasAccess) {
   }
}

Да, строчек кода получилось больше, но if стал простым и понятным, я сразу же глядя на код могу сказать, что происходит две проверки.

А можно создать свойства или методы:

bool isActive(something) {
  return something.isActive && something.StartDate < DateTime.Now && 
      (something.EndDate == null ||  something.EndDate > DateTime.Now);
}

bool hasAccess(something) {
 return User.CurrentUser == something.Creator && canEdit(something);
}

func foo (something) {
   if (isActive(something) && hasAccess(something)) {
   }
}

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

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

// check if it is active and if we have access
func foo (something) {
   if (something.isActive &&
      something.StartDate < DateTime.Now && 
     (something.EndDate == null ||  something.EndDate > DateTime.Now) &&
     User.CurrentUser == something.Creator && canEdit(something)) {
   }
}

И он сказал, что любит комментарии, потому что они дают понять, что происходит в проверках. А я люблю красивый код, который проще в поддержании и не нуждается в комментариях. Мой вариант как раз такой, он в комментариях не нуждается.


Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку уже лайкнули 3 человек


Комментарии

Покемон

12 Декабря 2020

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


Михаил Фленов

12 Декабря 2020

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


Денис Сепетов

13 Декабря 2020

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

И да, выделять целую функцию под одну строчку - это тоже нормально, а в некоторых случаях - почти обязательно для удобочитаемости кода. Например, в одной из старых версий Navision очень мало встроенных средств для форматирования даты. Например, нет даже готовой функции (или параметра), чтобы результат функции TODAY() сразу получить в формате ГГГГММДД. Приходится колхозить в т. ч. и преобразованием через строку. Зачем этот колхоз в общем коде светить?


Добавить Комментарий

Еще что-нибудь

Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

Без проблем вступаю в неразборчивые разговоры по e-mail. Стараюсь отвечать на письма всех читателей вне зависимости от страны проживания, вероисповедания, на русском или английском языке.

Пишите мне