Kiedy nazwa metody Java jest za długa? [Zamknięte]

173

W ostatnich tygodniach widziałem, jak niektórzy faceci używali naprawdę długich nazw dla metody lub klasy (50 znaków), zwykle zakłada się, że poprawia to czytelność, moim zdaniem taka długa nazwa wskazuje, że jesteśmy próbując zrobić dużo lub za dużo w klasie metod, jeśli potrzebujemy tak długiej nazwy, ale chciałem wiedzieć, co o tym myślicie.

Przykład:

getNumberOfSkinCareEligibleItemsWithinTransaction
MexicanHacker
źródło
19
TAK, to „zapach kodu” ... c2.com/cgi/wiki?LongMethodSmell
Dan Rosenstark,
23
Kiedy ma ponad 666 znaków, wiesz, że masz problem.
Thomas Eding,
8
@yar w twoim przykładzie, przeciwieństwem „metody długiej” jest „metoda krótka”, która jest uważana za dobrą rzecz. Więc oczywiście nie odnosi się do nazwy metody; odnosi się do linii kodu (lub czegoś podobnego). na przykład f()jest to bardzo krótka funkcja, ale z pewnością nie jest to dobra praktyka ... i coś, co powinieneś powiedzieć niektórym matematykom programowania :)
sfussenegger
3
@sfussenegger, to prawda. Ale stawiam na korelację między długością nazwy metody a długością metody. f()może nie jest świetną funkcją, ale ten $()facet jest jak gwiazda rocka w świecie metody Javascript.
Dan Rosenstark
7
@yar, link, który podałeś, odnosił się do długości metody w wierszach, a nie długości nazwy metody .
Thorbjørn Ravn Andersen

Odpowiedzi:

398

Nazwa w Javie lub jakimkolwiek innym języku jest zbyt długa, gdy istnieje krótsza nazwa, która w równym stopniu przekazuje zachowanie metody.

JaredPar
źródło
65
Matematycznie elegancki.
Ricket
304
Na przykład boolean doesShorterNameExistThatEquallyConvaysTheBehaviorOfTheMethod(String s)należy refaktoryzować boolean isTooLong(String s).
z5h
6
Nie do końca się z tym zgadzam, ponieważ chcesz nie tylko przekazać zachowanie, ale także zachować konwencję projektu i języka. Tak więc w Pythonie możesz powiedzieć, eligible_items_cntale w Javie zwykle mówisz getEligibleItemsCount.
flybywire
17
@flybywire: Każda konwencja, która zmusza do pisania zbyt długich nazw, ma wątpliwe korzyści.
MAK
20
@MAK @ S.Lott what about getLength()vs. length()? Naprawdę uwielbiam patrzeć na autouzupełnienia po wpisaniu „pobierz” lub „ustaw” - w tym przypadku wolę konwersję niż zwięzłość.
sfussenegger
202

Niektóre techniki zmniejszania długości nazw metod:

  1. Jeśli cały Twój program, klasa lub moduł dotyczy „produktów do pielęgnacji skóry”, możesz zrezygnować z pielęgnacji skóry. Na przykład, jeśli zostanie wywołana Twoja klasa SkinCareUtils, spowoduje to przejście dogetNumberOfEligibleItemsWithinTransaction

  2. Można zmienić terminie do w ,getNumberOfEligibleItemsInTransaction

  3. Możesz zmienić Transakcję na Tx, co prowadzi do getNumberOfEligibleItemsInTx.

  4. Lub jeśli metoda akceptuje parametr typu Transaction, możesz całkowicie usunąć InTx:getNumberOfEligibleItems

  5. Zmieniasz numerOf według liczby: getEligibleItemsCount

To bardzo rozsądne. I jest o 60% krótszy.

Lecieć jak po sznurku
źródło
11
dodatkowo 5) umieszczą getEligibleItems()i getEligibleItemsCount()obok siebie na listach w kolejności alfabetycznej (np. autouzupełnianie lub javadoc)
sfussenegger
4
I jak zwykle jest prawdą, krótsza nazwa wpisuje się w zasadę haiku.
sal
2
@mercator Korzystanie ze standardowej konwencji, takiej jak getElitableItems, w porównaniu z countElitableItems, zmniejsza prawdopodobieństwo niejednoznaczności w instrukcji. Mniej niejednoznaczne, co metoda ma robić, zwiększa czytelność. Bez zagłębiania się w metodę metoda, która „liczy” jest mniej jasna niż to, co metoda, która „otrzymuje”, osiąga na dłuższą metę.
Bill
53
Nie lubię jak skrót Tx, Cnt, grph, i tak dalej ... (btw, Txto skrót od "Transmission" lub "nadajnik")
Meinersbur
14
Tak, zgadzałem się z tobą, dopóki nie zdecydowałeś się użyć „Tx”.
Ponkadoodle
183

Dla odmiany odpowiedź nie-subiektywna: 65536 znaków.

A.java:1: Reprezentacja UTF8 dla ciągu „xxxxxxxxxxxxxxxxxxxx ...” jest za długa dla puli stałej

;-)

Mark Byers
źródło
4
tak, jest za długo, kiedy JVM nie może sobie z tym poradzić :)
Anurag,
35
+1 dla THE odpowiedź dosłownym.
Sal
37
Technicznie rzecz biorąc, specyfikacja języka Java nie ma górnego limitu długości identyfikatora. To jest ograniczenie implementacji maszyny JVM. Twoje zdrowie!
uckelman
13
Kompilator Sun najwyraźniej nie jest zgodny ze specyfikacją. java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 mówi: „Identyfikator to sekwencja o nieograniczonej długości…”
Michael Myers
6
JVM Spec ma mieć górną granicę, jak podkreśla komunikat o błędzie. Reprezentacja stałej puli utf8 jest ograniczona do 2 ^ 16 bajtów określonych tutaj . Nazwy klas i nazwy metod muszą być przechowywane jako utf8 w stałej puli.
thejoshwolfe
42

Zgadzam się ze wszystkimi: nazwy metod nie powinny być zbyt długie. Chcę jednak dodać jeden wyjątek:

Nazwy metod testowych JUnit mogą być jednak długie i powinny przypominać zdania.

Czemu?

  • Ponieważ nie są wywoływane w innym kodzie.
  • Ponieważ są używane jako nazwy testów.
  • Ponieważ wtedy można je zapisać jako zdania opisujące wymagania. (Na przykład za pomocą AgileDox )

Przykład:

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

Aby uzyskać więcej informacji na temat tego pomysłu, zobacz „ Projektowanie oparte na zachowaniu ”.

Epaga
źródło
5
+1 Zgadzam się z tym i to też robię, chociaż metody JUnit 4 nie są już wymagane do startu test, otwiera to również możliwość użycia should: np dialogShouldCloseWhenTheRedButtonIsPressedTwice(). Czy można nazwać klasę testową DialogShould, a następnie metodę closeWhenTheRedButtonIsPressedTwice(), więc je czytać razem: DialogShould.closeWhenTheRedButtonIsPressedTwice().
Stivlo
Zgadzam się, ale sugeruję również, że zbyt długie zdanie może sugerować test, który robi za dużo!
Brian Agnew,
17

Kontekst „... WithinTransaction” powinien być oczywisty. Na tym właśnie polega orientacja obiektowa.

Metoda jest częścią klasy. Jeśli klasa nie oznacza „Transakcja” - i jeśli nie uchroni Cię przed koniecznością ciągłego powtarzania „W ramach transakcji”, masz problemy.

S.Lott
źródło
2
Może również przyjąć jakiś parametr transakcji
willcodejavaforfood
3
Jak widać z powyższej odpowiedzi, która uzyskała najwyższą liczbę punktów, wybierz prostotę outbacku zamiast porad z zakresu OO. +1
Dan Rosenstark
@yar Ludzie nigdy się nie mylą.
CurtainDog,
12

Zwykle używam reguły haiku do nazw:

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

Oto praktyczne zasady dotyczące maksymalnych nazw. Naruszam to tylko wtedy, gdy poprawia czytelność. Coś takiego jak recalculateMortgageInterest (currentRate, quoteSet ...) jest lepsze niż recalculateMortgageInterestRate lub recalculateMortgageInterestRateFromSet, ponieważ fakt, że obejmuje stawki i zestaw cytatów, powinien być całkiem jasny z osadzonych dokumentów, takich jak javadoc lub odpowiednik .NET.

UWAGA: To nie jest prawdziwe haiku, ponieważ jest 7-5-7 zamiast 5-7-5. Ale nadal wolę nazywać to haiku.

sal
źródło
13
Klasy mają siedem, zmienne mniej niż pięć, siedem dla pozostałych
James,
8
„zmienne najwyżej pięć” (mniej niż pięć jest niedokładnych)
Jason S
Mniejsze nazwy mogą prowadzić do mniejszej czytelności kodu.
Deniss M.
10

Java ma kulturę zachęcania do długich nazw, być może dlatego, że IDE mają dobre autouzupełnianie.

Ta witryna mówi, że najdłuższa nazwa klasy w środowisku JRE InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedStatema 92 znaki.

Jeśli chodzi o najdłuższą nazwę metody, to znalazłem tę supportsDataDefinitionAndDataManipulationTransactions, która ma 52 znaki.

Lecieć jak po sznurku
źródło
20
Wygląda na to, że ta klasa została nazwana przez osoby zatrudnione przez Departament Zwolnień w celu nazwania rzeczy w Departamencie Zwolnień.
Michael Madsen
1
@MichaelMadsen: Czy jest to naprawdę zbędne, czy też opisuje ramkę zagnieżdżoną w innej ramce?
endolith
PEP-8 chciałby mieć słowo o tej nazwie klasy.
Mateen Ulhaq,
9

Nigdy nie używaj długiego słowa, jeśli wystarczy zdrobnienie.

Nie wydaje mi się, żeby twoja teza o „długości nazwy metody jest proporcjonalna do długości metody” naprawdę ma sens.

Weź podany przykład: „getNumberOfSkinCareElitableItemsWithinTransaction”. Wydaje mi się, że to robi tylko jedną rzecz: liczy liczbę pozycji w transakcji, które należą do określonej kategorii. Oczywiście nie mogę oceniać, nie widząc właściwego kodu metody, ale wydaje mi się to dobrą metodą.

Z drugiej strony widziałem wiele metod o bardzo krótkich i zwięzłych nazwach, które wykonują dużo pracy, na przykład „processSale” lub zawsze popularny „doStuff”.

Myślę, że trudno byłoby podać sztywną regułę dotyczącą długości nazwy metody, ale cel powinien być: wystarczająco długi, aby przekazać, co robi funkcja, wystarczająco krótki, aby był czytelny. W tym przykładzie myślę, że „getSkinCareCount” prawdopodobnie byłoby wystarczające. Pytanie brzmi, co musisz odróżnić. Jeśli masz jedną funkcję, która zlicza w transakcjach przedmioty kwalifikujące się do pielęgnacji skóry, a drugą, która liczy pozycje kwalifikujące się do pielęgnacji skóry w czymś innym, wówczas funkcja „withinTransactions” dodaje wartości. Ale jeśli mówienie o takich przedmiotach poza transakcją nie ma żadnego znaczenia, to nie ma sensu zaśmiecać nazwy tak zbędnymi informacjami.

Po drugie, myślę, że jest szalenie nierealistyczne przypuszczenie, że nazwa o dowolnej możliwej do zarządzania długości powie ci dokładnie, co robi funkcja we wszystkich, z wyjątkiem najbardziej trywialnych przypadków. Realistycznym celem jest stworzenie nazwy, która daje czytelnikowi wskazówkę, którą można później zapamiętać. Na przykład, jeśli próbuję znaleźć kod, który oblicza, ile antymaterii potrzebujemy, aby osiągnąć prędkość warp, jeśli spojrzę na nazwy funkcji i zobaczę „calibrateTransporter”, „firePhasers” i „calcAntimatterBurn”, jest całkiem jasne, że pierwsze dwa to nie to, ale trzeci może być. Jeśli sprawdzę i stwierdzę, że to jest właśnie ten, którego szukam, łatwo będzie mi to zapamiętać, kiedy jutro wrócę, aby popracować nad tym problemem. To wystarczy.

Trzy długie imiona, które są podobne, są bardziej zagmatwane niż nazwy krótkie. Jeśli mam dwie funkcje o nazwie „calcSalesmanPay” i „calcGeekPay”, mogę szybko zgadnąć, która z nich jest tym, do czego. Ale jeśli nazywane są one „calculatorMonthlyCheckAmountForSalesmanForExportToAccountingSystemAndReconciliation” i „calculatorMonthlyCheckAmountForProgrammersForExportToAccountingSystemAndReconciliation”, muszę przestudiować nazwy, aby zobaczyć, która jest która. Dodatkowe informacje w nazwie prawdopodobnie przyniosą skutki odwrotne do zamierzonych w takich przypadkach. Zmienia myślenie trwające pół sekundy w myślenie trwające 30 sekund.

Sójka
źródło
+1 za tę kiepską odpowiedź, która ucierpiała.
Dan Rosenstark
7

Zaprojektuj interfejs tak, jak chcesz, i dostosuj implementację.

Na przykład może napisałbym to jako

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

lub ze strumieniami Java 8:

getTransaction().getItems().stream()
    .filter(item -> item.getType() == SKIN_CARE)
    .filter(item -> item.isEligible())
    .count();
Christoffer Hammarström
źródło
6

Moja zasada jest następująca: jeśli nazwa jest tak długa, że ​​musi pojawić się w osobnym wierszu, to jest za długa. (W praktyce oznacza to, że rzadko mam ponad 20 znaków).

Opiera się to na badaniach wykazujących, że liczba widocznych pionowych linii kodu jest dodatnio skorelowana z szybkością / skutecznością kodowania. Jeśli nazwy klas / metod zaczną to znacząco boleć, są za długie.

Dodaj komentarz, w którym metoda / klasa jest zadeklarowana i pozwól IDE Cię tam zabrać, jeśli chcesz mieć długi opis tego, do czego służy.

Rex Kerr
źródło
Lubię takie zasady. O ile pamiętasz, że Ty / Twój zespół tworzyliście je losowo, wszystko jest w porządku. Z drugiej strony nie mogę tego zagłosować, ponieważ „pokazujące badania” faktycznie wymagałyby linku do tych badań lub czegoś o nich ...
Dan Rosenstark,
5

Długość samej metody jest prawdopodobnie lepszym wskaźnikiem tego, czy robi ona za dużo, a nawet to daje tylko ogólne pojęcie. Należy dążyć do zwięzłości, ale ważniejsza jest opisowość. Jeśli nie możesz przekazać tego samego znaczenia w krótszej nazwie, prawdopodobnie sama nazwa jest w porządku.

Bill the Lizard
źródło
3

Kiedy następnym razem będziesz pisać nazwę metody, pomyśl o poniższym cytacie

"The man who is going to maintain your code is a phyco who knows where you stay"
Sreejesh
źródło
13
Dobrze, że to tylko wodorosty, a nie „psychol”
StingyJack,
2

Ta nazwa metody jest zdecydowanie za długa. Mój umysł ma tendencję do błądzenia, kiedy czytam nazwy metod o takich rozmiarach. To jak czytanie zdania bez spacji.

Osobiście wolę jak najmniej słów w metodach. Otrzymasz pomoc, jeśli nazwa pakietu i klasy może przekazać znaczenie. Jeśli odpowiedzialność klasy jest bardzo zwięzła , nie ma potrzeby nadawania olbrzymiej nazwy metody. Ciekaw jestem, dlaczego jest tam „WithinTransaction”.

„getNumberOfSkinCareEliciousItemsWithinTransaction” może stać się:

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

Wtedy w użyciu metoda mogłaby wyglądać jak „query.getNumElitableItems ()”

Jesse
źródło
2

Nazwa zmiennej jest zbyt długa, gdy krótsza nazwa pozwoli na lepszą czytelność kodu w całym programie lub w ważnych częściach programu.

Jeśli dłuższa nazwa pozwala przekazać więcej informacji o wartości. Jeśli jednak nazwa jest zbyt długa, zaśmieci to kod i ograniczy możliwość zrozumienia reszty kodu. Dzieje się tak zazwyczaj przez zawijanie wierszy i wypychanie innych wierszy kodu ze strony.

Sztuczka polega na określeniu, które zapewni lepszą czytelność. Jeśli zmienna jest używana często lub kilka razy w niewielkiej ilości miejsca, lepiej nadać jej krótką nazwę i użyć komentarza. Czytelnik może łatwo odnieść się do komentarza. Jeśli zmienna jest często używana w całym programie, często jako parametr lub w innych skomplikowanych operacjach, najlepiej jest skrócić nazwę lub użyć akronimów jako przypomnienia dla czytelnika. Zawsze mogą odwołać się do komentarza za pomocą deklaracji zmiennej, jeśli zapomną o znaczeniu.

Nie jest to łatwa kompromis, ponieważ musisz wziąć pod uwagę, co czytelnik kodu prawdopodobnie będzie próbował zrozumieć, a także wziąć pod uwagę, jak kod będzie się zmieniał i rozwijał w czasie. Dlatego nazwanie rzeczy jest trudne.

Czytelność jest powodem, dla którego dopuszczalne jest użycie i jako licznika pętli zamiast DescriptiveLoopCounterName. Ponieważ jest to najczęstsze zastosowanie zmiennej, możesz poświęcić najmniej miejsca na wyjaśnienie, dlaczego ona istnieje. Dłuższa nazwa tylko straci czas, utrudniając zrozumienie, w jaki sposób testujesz warunek pętli lub indeksujesz tablicę.

Z drugiej strony, jeśli funkcja lub zmienna jest używana rzadko, jak w złożonej operacji, takiej jak przekazywanie do wywołania funkcji wieloparametrowej, możesz pozwolić sobie na nadanie jej nazbyt opisowej nazwy.

Ben Gartner
źródło
1

Jak w każdym innym języku: kiedy nie opisuje już pojedynczej czynności wykonywanej przez funkcję.

Kaz Dragon
źródło
1

Powiedziałbym, że użyj kombinacji dobrych odpowiedzi i bądź rozsądny.

Całkowicie, jasno i czytelnie opisz, co robi ta metoda.

Jeśli nazwa metody wydaje się zbyt długa - refaktoryzuj metodę, aby robiła mniej.

Bill K.
źródło
1

Jest za długa, gdy nazwa metody zawija się w inną linię, a wywołanie metody jest jedyną rzeczą w linii i zaczyna się bardzo blisko marginesu. Musisz wziąć pod uwagę średni rozmiar ekranu osób, które będą z niego korzystać.

Ale! Jeśli nazwa wydaje się zbyt długa, prawdopodobnie jest za długa. Sposobem na obejście tego problemu jest napisanie kodu w taki sposób, że znajdujesz się w kontekście, a nazwa jest krótka, ale powielana w innych kontekstach. To tak, jakbyś mógł powiedzieć „ona” lub „on” po angielsku zamiast czyjegoś pełnego imienia i nazwiska.

Brian T Hannan
źródło
1

Jest za długi, jeśli zbyt werbalnie wyjaśnia, o co chodzi.

Na przykład te nazwy są funkcjonalnie równoważne.

w Javie: java.sql.SQLIntegrityConstraintViolationException

w Pythonie / Django: django.db.IntegrityError

Zadaj sobie pytanie, w pakiecie SQL / db, o ile więcej typów błędów integralności możesz wymyślić? ;) Stąd db.IntegrityErrorwystarczy.

vdboor
źródło
Zawsze można było dyskutować na odwrót. Kiedy werbalnie wyjaśnia, o co chodzi, jest oczywiście jasne, co robi metoda, w przeciwnym razie może to spowodować zamieszanie i sprowokować niewłaściwe użycie metody.
Jonas Geiregat
0

Nazwa identyfikatora jest zbyt długa, jeśli przekracza długość obsługiwaną przez kompilator języka Java.

uckelman
źródło
3
Co?! Nie rozumiem, dlaczego zostałem za to odrzucony. Pytanie nie dotyczyło warunku koniecznego, tylko wystarczającego!
uckelman
0

Istnieją dwa sposoby lub punkty widzenia: po pierwsze, nie ma znaczenia, jak długa jest nazwa metody, pod warunkiem, że opis jej działania jest możliwie jak najbardziej opisowy (podstawowa zasada najlepszych praktyk Java). Z drugiej strony zgadzam się z postem flybywire. Powinniśmy użyć naszej inteligencji, aby spróbować maksymalnie zredukować nazwę metody, ale bez zmniejszania jej opisowości. Ważniejsza jest opisowość :)

HackerGil
źródło
0

Nazwa jest za długa, jeśli:

  • Odczytanie zajmuje ponad 1 sekundę
  • Zajmuje więcej pamięci RAM niż przydzielisz dla maszyny JVM
  • To coś absurdalnie nazwanego
  • Jeśli krótsza nazwa ma sens
  • Jeśli zawija się w twoim IDE

Szczerze mówiąc, nazwa musi tylko przekazać swój cel programistom, którzy wykorzystają ją jako metodę publicznego interfejsu API lub będą musieli zachować kod, gdy odejdziesz. Po prostu pamiętaj KISS (zachowaj głupotę)

Paul Gregoire
źródło