Читаемость и производительность не являются необходимыми противоречивыми ограничениями, но когда они есть, я стремлюсь сделать читабельностью переднее сиденье.
Чтобы улучшить читабельность, я стремлюсь следовать следующим правилам.
Правило 1 . Сохраняйте return как последнюю строку кода , что бы ни находилось посередине.Другими словами, не разбрасывайте операторы return, когда захотите, просто потому, что вы не уверены, что ваша структура if-else будет каскадно перед самым последним возвратом.
За исключением простых методов, я предпочитаю структуру типа
MyType func() {
MyType result ;
if ( condition ) {
result = result_1 ;
} else {
result = result_2 ;
}
return result ;
}
по сравнению с предположительно более простой
MyType func() {
if ( condition ) {
return result_1 ;
} else {
return result_2 ;
}
}
По моему мнению, затраты на производительность, если таковые имеются,незначительно.Однако при увеличении масштаба я нахожу первый шаблон кодирования гораздо более читабельным.
Правило 2 . Воздержитесь от запуска логики путем "эвакуации" состояний ошибки , просто чтобы убрать их с пути и освободить ваш разум.Если ваша логика хорошо продумана, эти проверки найдут свое место в логике (также посмотрите на guava для многих хороших методов инкапсуляции обычных проверок в помощниках).
Многие новички вмоя команда начала кодировать подобные вещи
MyType func (ArgType arg1,...) {
if ( arg1 == null ) {
throw new Exception ( "hey dummy, we don't take null arg1) ;
// or return null ;
}
if ( arg2 == null ) {
// you got the picture...
}
// wow at last !!! all checks done
// Combine args and return result...
}
Что я должен сказать, это уже прогресс в том, чтобы просто принимать все условия как должное
Я предпочитаю
MyType func (ArgType arg1,...) {
MyType result ;
if ( try_to_compact_all_checks_here ) {
// Combine args and return result...
} else {
// throw, log, nullify result etc
}
return result ;
}
Если условие «try_to_compact_all_checks_here» не помещается в одну строку, я даже иногда предпочитаю убираться с дороги и инкапсулирую все проверки в частную функцию.Даже если он вызывается только один раз.
Правило 3 . Сохраняйте количество строк в операторе if / else на разумном уровне (обычно оно должно умещаться на одном экране в вашей IDE) .Для этого иногда можно извлечь некоторую логику и вставить ее в частную функцию.Совершенно никаких проблем.Все современные IDE делают это для вас в 2 клика.
Таким образом, в основном предыдущий шаблон становится.
MyType func (ArgType arg1,...) {
MyType result ;
if ( checks_here ) {
// 1 to 20 lines max,
encapsulate lengthy logic in full fledged private methods.
} else {
// throw, log, nullify result etc
}
return result ;
}
Правило 4 . Внутренние IF всегда должны иметь ELSE, и этот ELSE должен отличаться от внешнего ELSE .
Объяснение: Если я получу
MyType func (ArgType arg1,...) {
MyType result ;
if ( check_1 ) {
if (check_2) {
Do the real work
} else {
treat error condition
}
} else {
same error condition as above
}
return result ;
}
Тогда, вероятно,потому что мой анализ чеков не завершен.Это случается довольно часто.
Я пытаюсь достичь
MyType func (ArgType arg1,...) {
MyType result ;
if ( check_1 && check_2) {
Do the real work
} else {
same error condition as above
}
return result ;
}
Вот и все.
Я обнаружил, что, наблюдая такого рода соглашения, я могу обрабатывать большие Java-проекты со сложной бизнес-логикой (как в ESB, веб-службах и т. д.), при очень низких затратах производительности, если таковые имеются.