Некоторые из предложений этой статьи ироничны. К другим следует относиться серьезно. Это зависит от читателя, чтобы отделить их. Начните с этих предложений.
Как долго должен быть метод в Java?
Этот вопрос я задаю много раз во время интервью. Нет лучшего ответа. Есть стили программирования, и разные стили просто разные, и многие могут быть в порядке. Я абсолютно согласен с тем, что кто-то говорит, что метод должен быть как можно более коротким, но я также могу принять методы длиной от 20 до 30 строк. Выше 30 строк я бы немного неохотно.
«Когда я писал этот код, только Бог, и я понял это. Теперь только Бог ».
Цитата от неизвестного программиста. Последняя четверть ХХ. века.
Самое главное, что код читабелен. Когда вы пишете код, вы понимаете это. По крайней мере, вы думаете, что понимаете, что вы хотели кодировать. То, что вы на самом деле закодировали, может быть другой историей. И здесь возникает важность читабельности, а не записи.
Когда вы реорганизуете код, содержащий какой-то длинный метод, и вы разбиваете метод на множество небольших методов, вы фактически создаете древовидную структуру из линейного кода. Вместо одной строки за другой вы создаете небольшие методы и перемещаете в них действительные команды. После этого небольшие методы вызываются с более высокого уровня. Почему это делает код более читабельным?
Прежде всего потому, что у каждого метода будет имя. Это то, что есть у методов, и в Java нам нравятся разговорные имена на верблюжьих ножках.
1
2
3
|
private void pureFactoryServiceImplementationIncomnigDtoInvoker(IncomingDto incomingDto){ incomingDto.invoke(); } |
Но почему это лучше, чем встраивание кода и использование комментариев?
1
2
|
// pure factory service implementation incoming dto invoker incomingDto.invoke(); |
Возможно, это потому, что вам нужно дважды ввести pureFactoryServiceImplementationIncomnigDtoInvoker
? Я знаю, ты не будешь печатать это дважды. Вы скопируете, вставите его или воспользуетесь некоторой функцией автозаполнения IDE, и по этой причине тип, заменяющий ‘Incoming’ на ‘Incomnig’, на самом деле не имеет значения.
Когда вы разбиваете код на маленькие методы, имена становятся формой комментариев.
Очень похоже на то, что мы делаем в модульных тестах с использованием JUnit 4.0 или новее. Старые версии должны были начинать тестовые методы с буквального test...
но это не было хорошей идеей. Это было обнаружено давно. (Мне просто интересно, когда Go туда доберется.) В наши дни Groovy (и особенно спок) позволяет нам использовать целые предложения с пробелами и новыми строками в качестве имен методов в модульных тестах. Но, к счастью, эти имена методов не следует вводить дважды. Они перечислены и вызваны Junit через отражение и, таким образом, они действительно являются тем, чем они являются на самом деле: документацией.
Тогда возникает вопрос: почему древовидная структура лучше линейной?
Вероятно, так работает наш мозг. Мы смотрим на метод и видим, что в нем есть два-три вызова метода. В нем может быть простая структура ветвей или петель, возможно, одна вложенная в другую, но не намного глубже этой. Это просто, и если имена методов выбраны правильно (я имею в виду, действительно, в хорошем, содержательном и говорящем ключе), их легко понять, легко прочитать.
Мы можем, используя навигационную помощь IDE, перейти к методам, и мы можем сосредоточиться на ограниченном контексте метода, который мы рассматриваем. Есть грубое правило:
Вы должны быть в состоянии понять, что метод делает за 15 секунд.
Если вы дольше смотрите на метод и не знаете, что он делает, значит, он слишком сложный. Некоторые люди лучше понимают структуру кода, другие испытывают трудности в этом. Я нахожусь в последней группе, поэтому, когда я проверяю код, я много раз предпочитаю меньшие и более простые методы. Я отказываюсь от кода, который должен быть объединен, или я реорганизую его самостоятельно в зависимости от роли, фактической задачи, которую я выполняю. Юниоры, с которыми я работаю, думают, что я строг и разборчив. Правда я медленный. Сложность кода должна быть совместима с самой слабой цепочкой: любой из команды (включая возможных будущих сопровождающих в течение следующих 20 лет, пока код окончательно не будет удален из производства) должен легко понимать и поддерживать код.
Много раз, глядя на историю мерзавцев, я вижу рефакторинг пинг-понга. Например, метод
1
2
3
4
5
6
7
|
Result getFrom(SomeInput someInput){ Result result = null ; if ( someInput != null ){ result = someInput.get(); } return result; } |
реорганизован в
1
2
3
4
5
6
7
8
9
|
Result getFrom(SomeInput someInput){ final Result result; if ( someInput == null ){ result = null ; } else { result = someInput.get(); } return result; } |
а потом наоборот.
Один короче, а другой более декларативный. Является ли проблема повторного рефакторинга назад и вперед? Скорее всего, но не точно. Если это случается всего несколько раз и разными людьми, об этом не стоит слишком беспокоиться. Когда код подвергается рефакторингу, разработчик чувствует, что код больше привязан к себе. Больше чувства «это мой код», что важно. Хотя хороший разработчик не боится трогать и модифицировать любой код. (что может произойти? тест не пройден? и что? тест? какой тест?) Обратите внимание, что не все разработчики являются хорошими разработчиками. Но кто такой хороший разработчик в конце концов? Это относительно. Есть лучшие разработчики, и там не так хорошо. Если вы видите только хороших разработчиков, которые лучше вас, то, вероятно, вам повезло. Или нет.
Ссылка: | Случайные идеи о стиле кода от нашего партнера JCG Питера Верхаса из блога Java Deep . |