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

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