Коли назва методу Java занадто довга? [зачинено]


173

Останні тижні я бачив, як деякі хлопці використовували дійсно довгі імена для методу чи класу (50 символів), це зазвичай за умови, що це покращує читабельність, на мою думку, таке довге ім'я - це показник того, що ми намагаючись зробити багато чи занадто багато в класі методів, якщо нам потрібна така довга назва, однак я хотів знати, що ви думаєте про це.

Приклад:

getNumberOfSkinCareEligibleItemsWithinTransaction

19
ТАК це "запах коду" ... c2.com/cgi/wiki?LongMethodSmell
Дан

23
Коли це> 666 символів, то ви знаєте, що у вас проблема.
Томас Едінг

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

3
@sfussenegger, це правда. Але я ставлю на співвідношення між довжиною імені методу та довжиною методу. f()може не бути чудовою функцією, але цей $()хлопець схожий на рок-зірку у світі методів Javascript.
Dan Rosenstark

7
@yar посилання, яку ви дали послалася на довжину методи в рядках, а не довжина методи імені .
Thorbjørn Ravn Andersen

Відповіді:


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. Ви змінюєте числоOff за рахунком: getEligibleItemsCount

Тепер це дуже розумно. І це на 60% коротше.


11
додатково 5) поставлять getEligibleItems()і getEligibleItemsCount()поруч один з одним в алфавітному порядку упорядковані списки (наприклад, автодоповнення або javadoc)
sfussenegger

4
І, як зазвичай це відповідає дійсності, коротша назва відповідає нормі хайку.
саль

2
@mercator Використання стандартної конвенції на зразок getEligibleItems over countEligibleItems знижує ймовірність неоднозначності у виписці. Менш неоднозначне щодо того, що метод повинен зробити, збільшує читабельність. Не дивлячись далі на метод, метод, який «підраховує», менш зрозумілий, ніж те, що метод, який «отримує», виконується в довгостроковій перспективі.
Білл

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

14
Так, я погодився з вами, поки ви не вирішили використовувати "Tx".
Понкадоудле

183

Тільки для зміни не суб'єктивна відповідь: 65536 символів.

A.java:1: Представлення UTF8 для рядка "xxxxxxxxxxxxxxxxxxxx ..." занадто довго для постійного пулу

;-)


4
так, це занадто довго, коли JVM не можу впоратися з цим не мо :)
Anurag

35
+1 для THE буквального відповіді.
саль

37
Технічно специфікація мови Java не має верхньої межі довжини ідентифікатора. Це обмеження для вашої реалізації JVM. Ура!
uckelman

13
Компілятор Sun, очевидно, не відповідає специфікаціям. java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 каже: "Ідентифікатор - це послідовність необмеженої довжини ..."
Майкл Майерс

6
У специфікації JVM це має верхню межу, так як повідомлення про помилку вказує. Постійне представлення пулу utf8's обмежується 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" повинен бути очевидним. Ось в чому полягає об'єктна орієнтація.

Метод є частиною класу. Якщо клас не означає "Transaction" - і якщо це не врятує вас від того, щоб постійно говорити "WithinTransaction", у вас виникли проблеми.


2
Також можна взяти якийсь параметр транзакції
willcodejavaforfood

3
Як ви можете зрозуміти з вищезазначеної відповіді, перейдіть на простоту простого замість поради OO. +1
Дан Розенстарк

@yar Люди ніколи не помиляються.
CurtainDog

12

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

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

Це великі правила для максимальних імен. Я порушую це лише тоді, коли це покращує читабельність. Щось на зразок recculateMortgageInterest (currentRate, quotesSet ...) краще, ніж preraculateMortgageInterestRate або перерахуватиMortgageInterestRateFromSet, оскільки той факт, що він включає ставки та набір лапок, повинен бути досить зрозумілим із вбудованих документів, таких як javadoc або еквівалент .NET.

ПРИМІТКА: Не справжній хайку, оскільки це 7-5-7, а не 5-7-5. Але я все ж вважаю за краще називати це хайку.


13
Заняття отримують сім, змінних менше п'яти, сім для решти
Джеймс

8
"змінні максимум п'ять" (менше п'яти не є точними)
Jason S

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

10

У Java існує культура заохочення довгих імен, можливо, тому, що IDE мають хороший автозавершення.

На цьому сайті написано, що найдовша назва класу в JRE - InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedStateце 92 символи.

Що стосується найдовшого імені методу, я знайшов цей supportsDataDefinitionAndDataManipulationTransactions, який становить 52 символи.


20
Схоже, цей клас назвали люди, які називали людей, найнятих Департаментом надмірності, щоб назвати речі у відділі надмірності.
Майкл Мадсен

1
@MichaelMadsen: Це справді зайве чи описує кадр, вкладений у інший кадр?
ендоліт

PEP-8 хотів би слово з цією назвою класу.
Mateen Ulhaq

9

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

Я не думаю, що ваша теза про те, що "довжина назви методу пропорційна довжині методу" насправді не відповідає.

Візьмемо приклад, який ви даєте: "getNumberOfSkinCareEligibleItemsWithinTransaction". Мені це здається, що він робить лише одне: він підраховує кількість елементів транзакції, які потрапляють у певну категорію. Звичайно, я не можу судити, не побачивши фактичного коду методу, але це здається мені хорошим методом.

З іншого боку, я бачив безліч методів із дуже короткими та стислими іменами, які значно полегшують роботу, як-от "processSale" чи популярний "doStuff".

Я думаю, що було б важко дати жорстке правило про довжину імені методу, але мета повинна бути: достатньо довга, щоб передати те, що функція виконує, досить коротка, щоб бути читабельною. У цьому прикладі я думаю, що "getSkinCareCount", ймовірно, було б достатнім. Питання в тому, що вам потрібно відрізняти. Якщо у вас є одна функція, яка враховує придатні до догляду за шкірою елементи трансакцій, та інша, яка рахує предмети, які відповідають за доглядом за шкірою, у чомусь іншому, то "в межах трансакцій" додає значення. Але якщо говорити про такі предмети поза трансакцією, це нічого не означає, то не має сенсу захаращувати назву такою зайвою інформацією.

По-друге, я вважаю, що диво нереально припустити, що ім’я будь-якої керованої довжини точно скаже вам, що ця функція виконує у всіх, крім самих тривіальних випадках. Реалістичною метою є створення імені, яке дає читачеві підказку, і про це можна згадати пізніше. Мовляв, якщо я намагаюся знайти код, який обчислює, скільки антиматерії нам потрібно споживати, щоб досягти швидкості викривлення, якщо я переглянув назви функцій та побачив "calibrateTransporter", "firePhasers" та "calcAntimatterBurn", то цілком зрозуміло, що перші два - не це, але третя може бути. Якщо я перевірю і виявлю, що це дійсно те, що я шукаю, буде легко запам'ятати, що коли я повернусь завтра, щоб ще трохи попрацювати над цією проблемою. Це досить добре.

Три, довгі імена, схожі, більш заплутані, ніж короткі назви. Якщо у мене є дві функції, які називаються "calcSalesmanPay" і "calcGeekPay", я можу швидко здогадатися, що це таке, що швидко. Але якщо вони називаються "CalcuMonthlyCheckAmountForSalesmanForExportToAccountingSystemAndReconciliation" і "izračunaMonthlyCheckAmountForProgrammersForExportToAccountingSystemAndReconciliation", я повинен вивчити імена, щоб побачити, хто це. Додаткова інформація в назві, ймовірно, є контрпродуктивною в таких випадках. Це перетворює пів секунди на 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 відвезти вас туди, якщо ви хочете довгий опис того, для чого це потрібно.


Мені подобаються такі правила. Поки ви пам’ятаєте, що ви / ваша команда складали їх випадковим чином, все це добре. З іншого боку, я не можу підтримати це, тому що "показ досліджень" насправді потребує посилання на це дослідження чи щось про нього ...
Dan Rosenstark

5

Тривалість самого методу, напевно, є кращим показником того, чи робиться він занадто багато, і навіть це дає лише приблизне уявлення. Вам слід прагнути до лаконічності, але важливіша описовість. Якщо ви не можете передати одне і те ж значення в більш короткому імені, то, мабуть, саме ім’я добре.


3

Коли ви збираєтесь написати наступне ім'я методу, просто подумайте нижче

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

13
Добре, що він просто водорості, а не психолог
StingyJack

2

Назва методу, безумовно, занадто довга. Моя думка схильна блукати, коли я читаю такі великі назви методів. Це як читати речення без пробілів.

Особисто я віддаю перевагу якомога менше слів у методах. Вам допоможуть, якщо назва пакету та класу може передати значення. Якщо відповідальність класу дуже лаконічна , немає потреби в назві гігантського методу. Мені цікаво, чому там "InternalTransaction".

"getNumberOfSkinCareEligibleItemsWithinTransaction" може стати:

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

Тоді, коли використовується, метод може виглядати як "query.getNumEligibleItems ()"


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 або повинні підтримувати код, коли ви виходите. Просто запам'ятайте KISS (нехай це буде просто дурно)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.