Когда имя метода Java слишком длинное? [закрыто]


173

В последние недели я видел, как некоторые парни используют действительно длинные имена для метода или класса (50 символов), обычно это делается для того, чтобы улучшить читаемость, и я считаю, что такое длинное имя является показателем того, что мы пытаясь сделать много или слишком много в классе методов, если нам нужно такое длинное имя, однако я хотел бы знать, что вы, ребята, думаете об этом.

Примером является:

getNumberOfSkinCareEligibleItemsWithinTransaction

19
ДА, это «кодовый запах» ... c2.com/cgi/wiki?LongMethodSmell
Дэн Розенстарк

23
Если длина> 666 символов, значит, у вас есть проблема.
Томас Эдинг

8
@ yar в вашем примере, противоположность «длинного метода» - это «короткий метод», который считается хорошей вещью. Так что это явно не относится к имени метода; это относится к строкам кода (или что-то подобное). например, f()это очень короткая функция, но это определенно не очень хорошая практика ... и кое-что вы должны сказать некоторым математикам по программированию там :)
sfussenegger

3
@ sfussenegger, это правда. Но я держу пари на корреляции между длиной имени метода и длиной метода. f()Возможно, это не очень хорошая функция, но этот $()парень похож на рок-звезду в мире методов Javascript.
Дэн Розенстарк

7
@yar ссылка, которую вы дали сослалась на длину методы в строках, а не длина методы имени .
Торбьерн Равн Андерсен

Ответы:


398

Имя в Java или любом другом языке слишком длинное, когда существует более короткое имя, которое в равной степени передает поведение метода.


65
Математически элегантно
Ricket

304
Так, например, boolean doesShorterNameExistThatEquallyConvaysTheBehaviorOfTheMethod(String s)должен быть рефакторинг boolean isTooLong(String s).
z5h

6
Я не совсем согласен, так как вы не только хотите передать поведение, но и придерживаться соглашения проекта и языка. Так что в Python вы можете сказать, eligible_items_cntно в Java вы обычно говорите getEligibleItemsCount.
flybywire

17
@flybywire: Любое соглашение, которое заставляет вас писать слишком длинные имена, имеет сомнительную выгоду.
МАК

20
@MAK @ С. Лотт насчет getLength()VS. length()? Я действительно люблю смотреть на автозаполнения после ввода 'get' или 'set' - поэтому я бы предпочел конвекцию, а не лаконичность в этом случае.
sfussenegger

202

Некоторые методы для сокращения длины имен методов:

  1. Если вся ваша программа, или урок, или модуль посвящены «предметам ухода за кожей», вы можете отказаться от ухода за кожей. Например, если ваш класс называется SkinCareUtils, это приводит вас кgetNumberOfEligibleItemsWithinTransaction

  2. Вы можете изменить внутри , чтобы в ,getNumberOfEligibleItemsInTransaction

  3. Вы можете изменить Транзакцию на Tx, что и приводит вас к getNumberOfEligibleItemsInTx.

  4. Или, если метод принимает параметр типа, Transactionвы можете полностью удалить InTx:getNumberOfEligibleItems

  5. Вы меняете число на количество: getEligibleItemsCount

Теперь это очень разумно. И это на 60% короче.


11
Кроме того, 5) поместит getEligibleItems()и getEligibleItemsCount()рядом друг с другом в алфавитно упорядоченных списках (например, автозаполнение или Javadoc)
sfussenegger

4
И, как это обычно бывает, более короткое имя соответствует правилу хайку.
сал

2
@mercator Использование стандартного соглашения, такого как getElptableItems over countElptableItems, уменьшает вероятность двусмысленности в утверждении. Менее двусмысленное в отношении того, что метод должен делать, повышает читабельность. Если не вдаваться в подробности метода, метод, который «считает», менее ясен, чем то, что метод, который «получает», выполняет в долгосрочной перспективе.
Билл

53
Мне не нравится сокр как Tx, Cnt, grphи так далее ... (кстати, Txне хватает для «передачи» или «передатчик»)
Meinersbur

14
Да, я согласился с тобой, пока ты не решил использовать "Tx".
Ponkadoodle

183

Просто для разнообразия, субъективный ответ: 65536 символов.

A.java:1: представление UTF8 для строки "xxxxxxxxxxxxxxxxxxxx ..." слишком длинное для пула констант

;-)


4
да, это слишком долго, когда JVM не может справиться с этим нет мо :)
Anurag

35
+1 для THE буквального ответа.
Sal

37
Технически, спецификация языка Java не имеет верхнего предела длины идентификатора. Это ограничение вашей реализации JVM. Ура!
Uckelman

13
Компилятор Sun, очевидно, не соответствует спецификации. java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 гласит: «Идентификатор - это последовательность неограниченной длины ...»
Майкл Майерс

6
В спецификации JVM это имеет верхний предел, так как сообщение об ошибке указывает. Постоянное представление пула utf8 ограничено 2 ^ 16 байтами, указанными здесь . Имена классов и методов должны храниться как utf8 в постоянном пуле.
thejoshwolfe

42

Я согласен со всеми: имена методов не должны быть слишком длинными. Я хочу добавить одно исключение:

Однако имена методов тестирования JUnit могут быть длинными и должны напоминать предложения.

Зачем?

  • Потому что они не называются в другом коде.
  • Потому что они используются в качестве имен тестов.
  • Потому что тогда они могут быть написаны как предложения, описывающие требования. (Например, используя AgileDox )

Пример:

    @Test
    public void testDialogClosesDownWhenTheRedButtonIsPressedTwice() {
        ...
    }

См. « Поведение управляемый дизайн » для получения дополнительной информации об этой идее.


5
+1 Я согласен с ним , и это также то , что я делаю, хотя JUnit 4 метода не требуется , чтобы начать с testбольше, это открывает также возможность для использования should: например , как dialogShouldCloseWhenTheRedButtonIsPressedTwice(). Или вы можете позвонить в тестовый класс , DialogShouldа затем метод closeWhenTheRedButtonIsPressedTwice(), поэтому читать их вместе: DialogShould.closeWhenTheRedButtonIsPressedTwice().
stivlo

Хотя я согласен, я бы также предположил, что слишком длинное предложение может предложить тест, который делает слишком много!
Брайан Агнью

17

Контекст "... WithinTransaction" должен быть очевидным. Вот что такое объектная ориентация.

Метод является частью класса. Если класс не означает «Транзакция» - и если он не избавляет вас от необходимости постоянно говорить «Внутри транзакции», то у вас есть проблемы.


2
Также может принимать какой-то параметр транзакции
willcodejavaforfood

3
Как вы можете видеть из ответа на лучший результат выше, перейдите к простоте малонаселенных районов вместо рекомендаций ОО. +1
Дэн Розенстарк

@yar Люди никогда не ошибаются.
CurtainDog

12

Я склонен использовать правило хайку для имен:

 Seven syllable class names 
 five for variables
 seven for method and other names

Это эмпирические правила для максимальных имен. Я нарушаю это только тогда, когда это улучшает читабельность. Что-то вроде recalculateMortgageInterest (currentRate, quoteSet ...) лучше, чем recalculateMortgageInterestRate или recalculateMortgageInterestRateFromSet, поскольку тот факт, что он включает в себя ставки и набор кавычек, должен быть достаточно ясен из встроенных документов, таких как javadoc или эквивалент .NET.

ПРИМЕЧАНИЕ: не настоящий хайку, так как это 7-5-7, а не 5-7-5. Но я все еще предпочитаю называть это хайку.


13
Классы получают семь, переменные меньше пяти, семь - для остальных
Джеймс

8
«переменные не более пяти» (менее пяти - неточно)
Джейсон С.

Меньшие имена могут привести к снижению читабельности кода.
Денис М.

10

Java имеет культуру поощрения длинных имен, возможно, потому что IDE имеют хорошее автозаполнение.

На этом сайте написано, что самое длинное имя класса в JRE InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState- 92 символа.

Что касается самого длинного имени метода, я нашел этот supportsDataDefinitionAndDataManipulationTransactions, который состоит из 52 символов.


20
Похоже, этот класс был назван именными людьми, нанятыми Департаментом резервирования, чтобы называть вещи в Департаменте резервирования.
Майкл Мэдсен

1
@MichaelMadsen: Это действительно избыточно, или это описание кадра, вложенного в другой кадр?
эндолит

PEP-8 хотел бы слово с этим именем класса.
Матин Улхак,

9

Никогда не используйте длинное слово, когда подойдет крошечное.

Я не думаю, что ваш тезис «длина имени метода пропорциональна длине метода» действительно держит воду.

Возьмите пример, который вы даете: «getNumberOfSkinCareElptableItemsWithinTransaction». Для меня это звучит так, будто выполняет только одно: подсчитывает количество элементов в транзакции, попадающих в определенную категорию. Конечно, я не могу судить, не видя фактического кода для метода, но для меня это звучит как хороший метод.

С другой стороны, я видел множество методов с очень короткими и лаконичными именами, которые способствуют большой работе, например, «processSale» или когда-либо популярный «doStuff».

Я думаю, что было бы трудно дать жесткое правило о длине имени метода, но цель должна быть: достаточно длинной, чтобы передать то, что делает функция, достаточно короткой, чтобы быть читаемой. В этом примере я думаю, что getSkinCareCount, вероятно, было бы достаточно. Вопрос в том, что вам нужно различать. Если у вас есть одна функция, которая подсчитывает элементы, отвечающие требованиям ухода за кожей, в транзакциях, и другая, которая подсчитывает элементы, отвечающие критериям ухода за кожей, во что-то еще, тогда «WithinTransactions» добавляет ценность. Но если это ничего не значит для разговора о таких предметах за пределами транзакции, то нет смысла загромождать название такой лишней информацией.

Во-вторых, я думаю, что совершенно нереально предположить, что имя любой управляемой длины точно скажет вам, что делает функция во всех случаях, кроме самых тривиальных. Реальная цель состоит в том, чтобы сделать имя, которое дает читателю подсказку, и это можно запомнить позже. Например, если я пытаюсь найти код, который вычисляет, сколько антиматерии нам нужно использовать для достижения скорости деформации, если я посмотрю на имена функций и увижу «calibrateTransporter», «firePhasers» и «calcAntimatterBurn», то довольно ясно, что первые два не так ли, но третий может быть. Если я проверю и обнаружу, что это действительно то, что я ищу, будет легко вспомнить это, когда я вернусь завтра, чтобы еще немного поработать над этой проблемой. Это достаточно хорошо.

Три, длинные имена, которые похожи, сбивают с толку, чем короткие имена. Если у меня есть две функции, называемые «calcSalesmanPay» и «calcGeekPay», я могу сделать правильное предположение, которое на один взгляд. Но если они называются «CalculayMonthlyCheckAmountForSalesmanForExportToAccountingSystemAndReconciliation» и «calcMonthlyCheckAmountForProgrammersForExportToAccountingSystemAndReconciliation», я должен изучить имена, чтобы увидеть, какие именно. Дополнительная информация в названии, вероятно, контрпродуктивна в таких случаях. Это превращает полсекунды в 30 секунд.


+1 за этот плохой ответ, который пострадал.
Дэн Розенстарк

7

Создайте свой интерфейс так, как вы хотите, и сделайте реализацию соответствующей.

Например, может быть, я бы написал это как

getTransaction().getItems(SKIN_CARE).getEligible().size()

или с потоками Java 8:

getTransaction().getItems().stream()
    .filter(item -> item.getType() == SKIN_CARE)
    .filter(item -> item.isEligible())
    .count();

6

Мое правило таково: если имя настолько длинное, что оно должно появиться в отдельной строке, оно слишком длинное. (На практике это означает, что я редко превышаю 20 символов.)

Это основано на исследованиях, показывающих, что количество видимых вертикальных строк кода положительно коррелирует со скоростью / эффективностью кодирования. Если имена классов / методов начинают сильно вредить этому, они слишком длинные.

Добавьте комментарий, где объявлен метод / класс, и позвольте IDE перенести вас туда, если вы хотите получить подробное описание того, для чего он нужен.


Мне нравятся такие правила. Пока вы помните, что вы / ваша команда их выдумали случайным образом, все это хорошо. С другой стороны, я не могу отказать в этом, потому что для «показа исследования» на самом деле понадобится ссылка на это исследование или что-то об этом ...
Дэн Розенстарк

5

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


3

Когда вы в следующий раз напишите название метода, просто подумайте

"The man who is going to maintain your code is a phyco who knows where you stay"

13
Хорошо, что он просто водоросль, а не «псих»
StingyJack

2

Имя этого метода определенно слишком длинное. Мой разум имеет тенденцию блуждать, когда я читаю имена методов такого размера. Это похоже на чтение предложения без пробелов.

Лично я предпочитаю как можно меньше слов в методах. Вам помогли, если пакет и имя класса могут передать значение. Если ответственность класса очень краткая , нет необходимости в гигантском имени метода. Мне любопытно, почему там "Внутри транзакции".

"getNumberOfSkinCareElitableItemsWithinTransaction" может стать:

com.mycompany.app.product.SkinCareQuery.getNumEligibleItems ();

Затем при использовании метод может выглядеть как «query.getNumElptableItems ()»


2

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

Если более длинное имя позволяет вам передавать больше информации о значении. Однако, если имя слишком длинное, оно загромождает код и снижает способность понимать остальную часть кода. Обычно это происходит, вызывая перенос строк и выталкивая другие строки кода со страницы.

Хитрость в том, чтобы определить, какая из них лучше читается. Если переменная используется часто или несколько раз за короткий промежуток времени, может быть лучше дать ей короткое имя и использовать пояснение комментария. Читатель может легко вернуться к комментарию. Если переменная часто используется во всей программе, часто в качестве параметра или в других сложных операциях, может быть лучше сократить имя или использовать аббревиатуры в качестве напоминания для читателя. Они всегда могут ссылаться на комментарий с помощью объявления переменной, если они забывают значение.

Это не простая сделка, так как вы должны учитывать, что читатель кода, вероятно, попытается понять, а также принимать во внимание, как код будет изменяться и расти со временем. Вот почему называть вещи сложно.

Читаемость - вот почему допустимо использовать i в качестве счетчика цикла вместо DescriptiveLoopCounterName. Поскольку это наиболее распространенное использование переменной, вы можете потратить наименьшее количество места на экране, объясняя, почему она существует. Более длинное имя будет просто тратить время, усложняя понимание того, как вы тестируете условие цикла или индексируете в массив.

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


1

Как и с любым другим языком: когда он больше не описывает единственное действие, которое выполняет функция.


1

Я бы сказал, использовать комбинацию хороших ответов и быть разумным.

Полностью, четко и наглядно опишите, что делает метод.

Если имя метода кажется слишком длинным - рефакторинг метода сделать меньше.


1

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

Но! Если имя кажется слишком длинным, значит, оно слишком длинное. Чтобы обойти это, нужно написать код таким образом, чтобы вы находились в контексте, а имя было коротким, но дублировалось в других контекстах. Это как когда вы можете сказать «она» или «он» по-английски вместо чьего-либо полного имени.


1

Это слишком долго, когда слишком многословно объясняет, о чем идет речь.

Например, эти имена функционально эквивалентны.

в Java: java.sql.SQLIntegrityConstraintViolationException

в Python / Django: django.db.IntegrityError

Спросите себя, в пакете SQL / db, сколько еще типов ошибок целостности вы можете придумать? ;) Следовательно db.IntegrityError, достаточно.


Вы всегда можете поспорить наоборот. Когда он подробно объясняет, о чем идет речь, очевидно, что метод делает, иначе это может вызвать путаницу и спровоцировать неправильное использование метода.
Йонас Гейрегат

0

Имя идентификатора слишком длинное, если оно превышает длину, которую может обработать ваш компилятор Java.


3
Какой?! Я не понимаю, почему за это проголосовали. Вопрос не задавал для необходимого условия, только достаточного!
Uckelman

0

Здесь есть два способа или точки зрения: один из них заключается в том, что на самом деле не имеет значения, как долго длится имя метода, если это как можно более описательно, чтобы описать, что делает метод (базовое правило лучших практик Java). С другой стороны, я согласен с сообщением flybywire. Мы должны использовать свой интеллект, чтобы попытаться максимально сократить имя метода, но не уменьшая его информативность. Информативность важнее :)


0

Имя слишком длинное, если оно:

  • Занимает более 1 секунды, чтобы прочитать
  • Занимает больше оперативной памяти, чем вы выделяете для своей JVM
  • Что-то нелепо названо
  • Если более короткое имя имеет смысл
  • Если это происходит в вашей IDE

Честно говоря, имя должно только сообщать его цель разработчикам, которые будут использовать его как публичный метод API или должны поддерживать код, когда вы уходите. Просто запомни ПОЦЕЛУЙ (будь проще, глупый)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.