Pull to refresh

Comments 23

Любые догмы — это булшит, головой надо думать. С одной стороны да, нужно ограничивать вложенность условий по возможности, но «не используйте else» — это уже сектанство какое-то. Ну и остальные пункты тоже из той серии.
Автор предлагает это как упражнения, а не как догмы. Просто попробовать на каком-нибудь небольшом проекте эти правила, чтобы улучшить свои навыки ООП.
И превратить небольшой проект в сферическое ООП в вакууме, с классами у которых не больше 2х аттрибутов?) Это упражнения чего? Как писать код в отрыве от реальности?

Не бывает императивного, хоть сколько то серьезного кода, в котором в ветвлениях нет else, или в котором в классах только по 2 аттрибута (почему 2 вообще?). Это синтетические правила и синтетические упражнения, и я не очень понимаю как они должны помочь писать хороший реальный код.
Бывает. Вот пример enterprise-quality кода, который соответствует всем правилам, изложенным в статье. Проект уже обсуждался на хабре.

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

Оригинал:
...
public class NoFizzNoBuzzStrategy implements IsEvenlyDivisibleStrategy {

        public boolean isEvenlyDivisible(int theInteger) {
                if (!NumberIsMultipleOfAnotherNumberVerifier.numberIsMultipleOfAnotherNumber(theInteger, NoFizzNoBuzzStrategyConstants.NO_FIZZ_INTEGER_CONSTANT_VALUE)) {
                        if (!NumberIsMultipleOfAnotherNumberVerifier.numberIsMultipleOfAnotherNumber(theInteger, NoFizzNoBuzzStrategyConstants.NO_BUZZ_INTEGER_CONSTANT_VALUE)) {
                                return true;
                        } else {
                                return false;
                        }
                } else if (!NumberIsMultipleOfAnotherNumberVerifier.numberIsMultipleOfAnotherNumber(theInteger, NoFizzNoBuzzStrategyConstants.NO_BUZZ_INTEGER_CONSTANT_VALUE)) {
                        if (!NumberIsMultipleOfAnotherNumberVerifier.numberIsMultipleOfAnotherNumber(theInteger, NoFizzNoBuzzStrategyConstants.NO_FIZZ_INTEGER_CONSTANT_VALUE)) {
                                return true;
                        } else {
                                return false;
                        }
                } else {
                        return false;
                }
        }
        
}


Исправляем на один уровень вложенности в методе:
...
public class NoFizzNoBuzzStrategy implements IsEvenlyDivisibleStrategy {

        public boolean isEvenlyDivisible(int theInteger) {
                if (NumberIsMultipleOfAnotherNumberVerifier.numberIsMultipleOfAnotherNumber(theInteger, NoFizzNoBuzzStrategyConstants.NO_FIZZ_INTEGER_CONSTANT_VALUE)) {
                                return false;
                }

                if  (NumberIsMultipleOfAnotherNumberVerifier.numberIsMultipleOfAnotherNumber(theInteger, NoFizzNoBuzzStrategyConstants.NO_BUZZ_INTEGER_CONSTANT_VALUE)) {
                                return false;
                }

                return true;
}
Ох уж эти теоретики от программирования (я не про вас, а про автора оригинальной статьи).

Ага, например, как в первом примере взять и размазать вложенные циклы по однострочным функциям. И где тут ООП? Повышение читаемости? Спорно. Чтобы понять, что происходит, придётся попрыгать по функциям, восстановить контекст, помнить цепочку вызовов и держать размерность блока циклов в голове, вместо того, чтобы просто взять и увидеть всё это в трёх несчастных строчках кода с двумя отступами.

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

Что это вообще за бредовое правило «не больше одного отступа на метод», ну кто его придумал? Кто сказал и доказал, что два отступа уже не читаются и не поддерживаются? :)
Пора вводить понятие программистский радикализм)
1. Конкретно этот пример гораздо более читаем в одном методе. Если он разрастется, тогда уже разделяем. Думаю, многие со мной согласятся.
8. У меня есть еще отчество. Тоже создавать отдельный класс? Мне кажется это самое бредовое правило. Нужно знать меру все же.
UFO landed and left these words here
UFO landed and left these words here
Многие пункты не актуальны из-за лишнего overhead'a, если оптимизировать код под производительность. Ну например для написания игры.
На C++ можно делать inline. Более того, сам компилятор решает, когда стоит сделать inline. Java умеет так делать? (просто интересно)
UFO landed and left these words here
Дело не только в inline-ах, я про 2 поля в классе. Создание постоянно мелких объектов не очень хорошо для GC и кажется это самый бредовый совет.
Добавьте в список неизменяемость данных и можно на какой-нибудь хаскель переходить.
Боже, это бред какой-то. А early return я вообще считаю злом.
А можно поинтересоваться, почему? Это единственный совет из вышеприведенных, которому я следую в большинстве случаев и он уменьшает количество отступов тела функции и повышает читабельность. Конечно, это если его использовать только в начале функции; искать return'ы в середине никто не любит.
Читабельнее. Код пишется для людей, а не метрик. С else получается более «человеческое» выражение, сразу видно, что хотел сделать автор. ИМХО

А теперь от моего любимого C# со сборкой мусора перейдем к С:
void foo()
{
  int *ptr = malloc(1234);
  ... // Тысячи строк кода
  ...
  if (bar(ptr))
    return; // Утечка
  foobar(ptr);
  ... // Тысячи строк кода
  ...
  free(ptr);
}
Пример сферический, но в целом мысль понятна. Чужой код, все очень сложно, а тебе надо чуток подправить код.
По моему пример неудачный. Здесь early return не пахнет (после первых-то тысяч строк кода).
Ну и в подобных монстрах надо все перепроверять на двадцать рядов, чтобы хоть как-то быть уверенным, что не ошибся.
Даже если поставить else-блок, нельзя гарантировать, что в него случайно не попадет вызов free. А что если вызов free вообще в середине вторых тысяч строк кода, а не в конце? :) Все решает внимательность к деталям.
Пожалуй, можно поспорить, что лучше в плане читабельности обработки ошибок: колбаса из else или goto cleanup. Особенно, если ошибка в каком-то цикле.
Интересно, как быть с правилом «Никаких классов с более чем 2 атрибутами» для сложных сущностей? Например, что-то типа «счет», у которого десяток атрибутов, каждый из которых логически не пересекается ни с каким другим.
Мне кажется, следуя этим правилам, можно написать отличные макароны из кода, чтобы понять которые придется сотни раз прыгать туда-сюда.
Sign up to leave a comment.

Articles