Early return or goto hell
@oleg_logХорошая статья про рефакторинг и как уйти от множественных возвратов из функции. Другими словами early return everything (дада, и тут я приклею го)
Небольшой рефакторинг небольшой функции, но с отличным доводом, как все становится проще. TLDR: меньше вложенность - радостнее жизнь.
https://blog.startifact.com/posts/refactoring-to-multiple-exit-points.html
(Спасибо Искандеру за другое имя этого/похожего паттерна https://en.wikipedia.org/wiki/Guard_(computer_science))
Но к этой же теме вспомнилась цитата Великого Дейкстры (точнее его упоминание в Clean Code от Robert C.Martin):
Some programmers follow Edsger Dijkstra’s rules of structured programming. Dijkstra said that every function, and every block within a function, should have one entry and one exit. Following these rules means that there should only be one return statement in a function, no break or continue statements in a loop, and never, ever, any goto statements.
While we are sympathetic to the goals and disciplines of structured programming, those rules serve little benefit when functions are very small. It is only in larger functions that such rules provide significant benefit.
So if you keep your functions small, then the occasional multiple return, break, or continue statement does no harm and can sometimes even be more expressive than the single-entry, single-exit rule. On the other hand, goto only makes sense in large functions, so it should be avoided.
И вот фишка в том, что Дейкстра не упоминал о каком языке речь, и даже в какой год он это говорит(кэп).
Немного пораскинув мозгами и гуглом, можно найти отличное пояснение его слов и что же таки его натолкнуло на эту мысль:
"Single Entry, Single Exit" was written when most programming was done in assembly language, FORTRAN, or COBOL. It has been widely misinterpreted, because modern languages do not support the practices Dijkstra was warning against.
"Single Entry" meant "do not create alternate entry points for functions". In assembly language, of course, it is possible to enter a function at any instruction. FORTRAN supported multiple entries to functions with the ENTRY statement.
И там же код, от вида которого больно, а если представить, что его еще кто-то может использовать и начинать выполнение из произвольных мест...ох...
https://softwareengineering.stackexchange.com/a/118793/32339
А может вывод?
В большинстве случаев быстрый возврат из функции откинет ненужные шаги и мысленно читая код будет это выглядеть так:
- объект не Х - возврат
- статус не У - возврат
- сервер не жив - возврат
- о, а вот и результат
Вместо чего-то такого:
- объект Х
- при этом статус У
- при этом сервер жив
- о, наконец-то результат
Объясняя на пальцах - контекст не накапливается. Мечта для тестов и чтения. Хотя по началу нужно привыкнуть. Кстати да, это очень популярная практика в сильно технических фирмах, стоит задуматься.
(не могу не упомянуть раст и как там не любят такое делать)