Ile wierszy w klasie jest za dużo w Javie? [Zamknięte]

74

Z twojego doświadczenia, jaka jest użyteczna ogólna zasada dotycząca tego, ile wierszy kodu jest zbyt wiele dla jednej klasy w Javie?

Dla jasności wiem, że liczba wierszy nie jest nawet zbliżona do rzeczywistego standardu, który należy zastosować dla tego, co powinno być w danej klasie, a co nie. Zajęcia powinny być zaprojektowane zgodnie z odpowiednimi filozofiami OOP (enkapsulacja itp.). To powiedziawszy, ogólna zasada może stanowić przydatny punkt wyjścia do rozważań na temat refaktoryzacji (tj. „Hmmm, ta klasa ma> n linii kodu; prawdopodobnie jest nieczytelna i wykonuje kiepską pracę w enkapsulacji, więc może chciałbym sprawdzić, czy powinna w pewnym momencie zostanie refaktoryzowane ”).

Z drugiej strony, być może natknąłeś się na przykłady bardzo dużych klas, które nadal dobrze przestrzegały projektowania OOP i były czytelne i łatwe do utrzymania pomimo ich długości?

Oto pokrewne, niebędące duplikatem pytanie o wiersze na funkcję .

Michael McGowan
źródło
4
Widziałem zajęcia z ponad tysiącem wierszy, nie sądzę, że istnieje coś takiego jak „za dużo”.
Mahmoud Hossam,
5
Jest ich zbyt wiele, gdy już się nie skompiluje. Poważnie, to tylko za dużo, gdy klasa robi zbyt wiele różnych rzeczy.
Berin Loritsch,
20
Ogólna zasada zmienia się w maksimum, które zmienia się w politykę, która zamienia się w spór. Unikaj liczności. Liczenie i mierzenie nie są idealnym sposobem na ustalenie, czy obowiązki zostały właściwie przydzielone.
S.Lott,
7
Mniej więcej tyle, ile wynosi odpowiednia liczba cali dla kawałka sznurka.
Matt
6
Pytanie z 30 głosami, oglądane ~ 24 000 razy, 10 odpowiedzi z (łącznie) ~ 75 głosów. „zamknięte jako oparte głównie na opiniach” Witaj w wymianie stosów :) Coś musi się zmienić w kulturze SE ...
jb.

Odpowiedzi:

79

Kilka interesujących wskaźników:

            junit fitnesse testNG tam jdepend ant tomcat
            ----- -------- ------ --- ------- --- ------
maks. 500 498 1450 355 668 2168 5457
średnia 64,0 77,6 62,7 95,3 128,8 215,9 261,6
min 4 6 4 10 20 3 12
sigma 75 76 110 78 129 261 369
pliki 90 632 1152 69 55 954 1468
wszystkie linie 5756 49063 72273 6575 7085 206001 384026

Używam FitNesse jako punktu odniesienia, ponieważ miałem wiele wspólnego z jego pisaniem. W FitNesse średnia klasa ma 77 linii. Żadne nie są dłuższe niż 498 linii. Odchylenie standardowe wynosi 76 linii. Oznacza to, że zdecydowana większość klas ma mniej niż 150 linii. Nawet Tomcat, który ma jedną klasę przekraczającą 5000 linii, ma większość klas mniejszych niż 500 linii.

Biorąc to pod uwagę, możemy prawdopodobnie wykorzystać 200 linii jako dobrą wytyczną, aby pozostać poniżej.

Wujek Bob.
źródło
9
Jeśli klasa ma tylko jedną odpowiedzialność, szanse na przekroczenie 200-500 linii są niewielkie. Te, które zazwyczaj mają „klasy wewnętrzne” do obsługi innych powiązanych obowiązków. Na przykład klasa linii Tomcat 5000+ może naprawdę być 1 klasą główną z tuzinem klas wewnętrznych. Nie jest to niczym niezwykłym w Javie, gdzie masz moduły obsługi żądań i tym podobne.
Berin Loritsch,
4
jak w rzeczywistości są uzyskiwane te wskaźniki? chcę tylko wiedzieć
Sнаđошƒаӽ
1
Zwykle bardziej skłaniam się ku tej odpowiedzi na powiązane pytanie dotyczące funkcji: programmers.stackexchange.com/a/9452/100669 LOC jest trochę nieistotny, z wyjątkiem wyjątkowo ogólnej zasady, by po prostu zacząć zastanawiać się, czy możesz móc dalej wszystko rozkładać. I zgadzam się co do zagnieżdżonych klas. Niemniej jednak 500 jest prawdopodobnie bliżej ogólnego znaku ostrzegawczego.
Panzercrisis,
@ Sнаđошƒаӽ github.com/AlDanial/cloc
firephil
32

Dla mnie wiersze kodu nie mają znaczenia w tym kontekście. Chodzi o liczbę różnych powodów, dla których chciałbym to zmienić.

Gdybym przyszedł na tę klasę, gdy chcę zmienić zasady sprawdzania poprawności Osoby, nie chcę przychodzić na tę samą klasę, aby zmienić zasady potwierdzania Zamówienia, ani nie chcę tu przychodzić, aby zmienić miejsce utrzymywać osobę.

To powiedziawszy, jeśli dążysz do tego, rzadko znajdziesz zajęcia zawierające więcej niż 200 linii. Zdarzą się, z ważnych powodów, ale będą rzadkie. Więc jeśli szukasz wskaźników z czerwoną flagą, nie jest to złe miejsce na rozpoczęcie; ale uczyń to wytyczną, a nie regułą.

pdr
źródło
200 wydaje się słuszne jako bardzo szorstkie przypuszczenie. Tak jak mówisz, nie jest to jednak kwestia, o którą najpierw się martwisz.
Steve,
Inną rzeczą w Javie jest to, że licząc LOCs, zignorowałbym programy pobierające / ustawiające.
MrFox,
1
@MrFox: Nie zgadzam się. Jeśli twoja klasa ma wystarczającą liczbę pobierających i ustawiających, aby wypaczać dane LOC, liczy się to w przypadku „czy ta klasa robi zbyt wiele?” pytanie. Jednakże, jako kompromis, chciałbym uzyskać getter / settery NetBean przy mniej niż 1 linii / linii z powodu nadmiernej płyty kotłowej, jaką mają takie metody.
Brian
23

Przepraszam, ale jestem bardzo zaskoczony, że wiele odpowiedzi mówi, że „to naprawdę nie ma znaczenia”. Bardzo WIELKIE znaczenie ma liczba linii w klasie. Dlaczego? Rozważ te zasady, pisząc dobry kod Java ...

  • Testowalność
  • Spójność
  • Sprzęganie
  • Wyrozumiałość

Klasy z wieloma liniami najprawdopodobniej naruszą wszystkie te zasady.

Dla tych, którzy stwierdzili, że „to naprawdę nie ma znaczenia” ... ile zabawy sprawiło, że próbujesz zrozumieć klasę zawierającą ponad 5000 linii? Lub zmodyfikować? Jeśli powiesz, że to zabawne, masz dziwne zamiłowanie do bólu ...

Powiedziałbym, że każda klasa, która ma więcej niż 1000 linii, powinna przynajmniej zostać zapytana, w jaki sposób mogą one naruszać powyższe zasady i być może podzielone na kilka klas „poza sesją”.

Moje komentarze opierają się na czytaniu i studiowaniu takich autorów, jak Martin Fowler, Joshua Bloch i Misko Hevery. Są to doskonałe zasoby do konsultacji przy pisaniu dobrego kodu Java.

Zrób następnej osobie (którą możesz być za kilka lat) przysługę i staraj się pisać klasy, które zawierają mniej niż więcej wierszy.

Zack Macomber
źródło
Myślę, że wszyscy zgadzają się, że 5000+ nie jest ogólnie dobrym znakiem (nie licząc klas zagnieżdżonych), ale wydaje im się, że to raczej efekt uboczny lub coś więcej niż faktyczny problem. Oczywiście, niektórzy ludzie są nadmiernie gadatliwi i używają nadmiernej liczby wierszy tylko do deklarowania i inicjowania zmiennych i tym podobnych - i muszą temu zapobiec. Który ma uczynić go mniej czytelny. Ale jeśli odnosi się to do struktury klas, problemem nie jest sam LOC; to fakt, że ktoś po prostu nie rozbija wszystkiego na dobre, a LOC jest tego efektem ubocznym.
Panzercrisis,
2
Chodzi o to, że klasa powinna mieć wysoką spójność i wyraźną odpowiedzialność, co oznacza, że ​​klasy zwykle nie rosną tak duże. Ale JEŻELI klasa jest dobrze zaprojektowana, ale nadal ma ponad 5000 linii kodu, to nie pomaga nikomu podzielić jej na wiele mniejszych ściśle ze sobą powiązanych klas.
JacquesB,
12

To zależy od złożoności, a nie liczby linii. Napisałem wielkie, głupie procedury, które były łatwe do zrozumienia i które zrobiły dokładnie jedną rzecz i zrobiły to dobrze, ale ciągnęły się przez setki linii. Napisałem dość krótkie funkcje, które były trudne do zrozumienia (i debugowania).

Inną rzeczą, na którą możesz spojrzeć, jest liczba funkcji publicznych w klasie. To może być również znak ostrzegawczy.

Nie mam dobrych wyników, ale sugeruję przyjrzeć się porządnemu kodowi, który robi użyteczne rzeczy w twoim sklepie, i oprzeć go na tym. Na pewno powinieneś spojrzeć na najdłuższe klasy i największe API.

David Thornley
źródło
7
+1: Nie mierz głupich rzeczy, takich jak linie. Cyklomatyczna złożoność i liczenie cech (liczba metod) mają większy sens.
S.Lott,
2
tak i nie. Nadmierna liczba linii jest często objawem złego projektu, a tym samym czerwoną flagą, że klasa prawdopodobnie potrzebuje refaktoryzacji.
jwenting
1
@jwenting Tak, o to mi chodziło. Wiem, że wiele wierszy!
Michael McGowan
5

Jest zbyt wiele wierszy kodu, jeśli klasa robi zbyt wiele różnych rzeczy. Zasadniczo, jeśli przestrzegasz zasady pojedynczej odpowiedzialności za klasy, istnieje limit wzrostu tej klasy.

Jeśli chodzi o ograniczenia fizyczne, które możesz mieć (źródło: format pliku Class Java5 ):

  • 65 536 stałych, zastosowanych interfejsów, pól, metod i atrybutów - każdy. UWAGA: zabraknie ci stałej przestrzeni, zanim zabraknie któregokolwiek z pozostałych przedmiotów. UWAGA 2: atrybuty są konstrukcjami plików klas - nie należy ich mylić ze znacznikami „@Attribute” (tzn. Informacje debugowania i kod bajtowy są przechowywane jako osobne atrybuty dla metody).
  • Każda metoda może mieć 4 GB (32 bity) wygenerowanego kodu bajtowego. UWAGA: wersje Java wcześniejsze niż 1.5 mogły mieć tylko 64 KB (16 bitów) wygenerowanego kodu bajtowego dla każdej metody.

Krótko mówiąc, plik klasy może być znacznie większy, niż ktokolwiek uznałby za użyteczny. Jeśli będziesz przestrzegać zasady pojedynczej odpowiedzialności, twoje pliki klas będą miały odpowiedni rozmiar.

Berin Loritsch
źródło
1
+1 za pojedynczą odpowiedzialność :) @Berin, czy wdrażasz to ściśle w swoim oprogramowaniu?
Aditya P
Tak. Sztuką jest podział obowiązków w sposób, który ma sens.
Berin Loritsch
ah, stara dobra granica 64 KB. Niezły test lithmus, aby sprawdzić, czy strony JSP są zbyt złożone, ponieważ są one tłumaczone na jedną metodę z dużą ilością instrukcji println dla wszystkich statycznych
plików
Od wersji Java 5 zwiększono ją do 4 GB. Nie martw się teraz.
Berin Loritsch,
5

Prawidłowa odpowiedź to 42. Tylko żartuję.
W rzeczywistości maksymalna zalecana liczba linii na klasę wynosi 2000 linii.

„Konwencje kodu Java” od 1999 roku stwierdzają to w ten sposób:
Pliki dłuższe niż 2000 linii są uciążliwe i należy ich unikać.

Postępując zgodnie z konwencjami kodowania Sun / Oracle od czasu wynalezienia Javy, uznałem tę zasadę dotyczącą wierszy według klas za rozsądną. 99% twojego kodu Java powinno być zgodne ... A jeśli przekroczy 2000, po prostu umieść TODO na górze, mówiąc, że klasa potrzebuje pracy.

Najgorszą rzeczą jest odwrotny przypadek, gdy programiści tworzą zbyt wiele małych, małych klas prawie bez żadnej rzeczywistej funkcjonalności w każdej klasie. Ignorując radę „Preferuj kompozycję”, programiści tworzą setki dziedziczących klas, które tworzą skomplikowane modele obiektowe, które są znacznie gorsze niż problem dużych klas (które przynajmniej zwykle zachowują funkcjonalność z odpowiednią nazwą klasy).

http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-141855.html#3043

użytkownik1865223
źródło
Właściwie większość z nich to komentarze @LluisMartinez
Xtreme Biker
Zdecydowanie nie zgadzam się z 2000 r . Klasa nie może być dłuższa niż 200 linii z wyłączeniem komentarzy.
Nikolas
4

Wyczyść kod:

Klasy powinny być małe!

Pierwszą zasadą klas jest to, że powinny one być małe. Drugą zasadą klas jest to, że powinny one być mniejsze. Nie, nie powtórzymy dokładnie tego samego tekstu z rozdziału Funkcje. Ale podobnie jak w przypadku funkcji, mniejsza jest podstawową zasadą, jeśli chodzi o projektowanie klas. Podobnie jak w przypadku funkcji, naszym bezpośrednim pytaniem jest zawsze „Jak mały?”

** W przypadku funkcji mierzyliśmy rozmiar, licząc fizyczne linie. W przypadku klas używamy innej miary. Liczymy obowiązki. **

Nazwa klasy powinna opisywać, jakie obowiązki wypełnia. W rzeczywistości nazewnictwo jest prawdopodobnie pierwszym sposobem na określenie wielkości klasy. Jeśli nie możemy uzyskać zwięzłej nazwy dla klasy, prawdopodobnie jest ona zbyt duża. Im bardziej niejednoznaczna jest nazwa klasy, tym bardziej prawdopodobne jest, że ma zbyt wiele obowiązków. Na przykład nazwy klas, w tym słowa łasicy, takie jak Processor lub Manager lub Super, często wskazują na niefortunne agregowanie obowiązków.

Następnie:

  • Tylko upewnij się, że twoje metody robią tylko jedną rzecz.
  • Następnie upewnij się, że klasa nie ma zbyt wielu obowiązków.

Skończysz z klasą rozsądnego rozmiaru.

Tulains Córdova
źródło
jeśli Clean Codena dodatek twoja odpowiedź odnosi się do książki Roberta C. Martina (co robi!), to muszę powiedzieć, że ty i ja mam to wspólne; ta książka doprowadziła mnie do tego pytania. Myślę, że ta odpowiedź mówi wszystko
Sна Sошƒаӽ
2

Liczba linii jest dość słabym wskaźnikiem jakości klasy. Dla mnie lubię patrzeć (jak wspomnieli inni) na publiczne metody, a także na wszelkie publicznie ujawnione właściwości (chyba publiczne gettery / settery w Javie). Gdybym musiał wyciągnąć z powietrza liczbę, która mogłaby zwrócić moją uwagę, powiedziałbym, że jest ich więcej niż 10. Naprawdę, jeśli jest to więcej niż około 5 właściwości lub metod, przyjrzę się i często znajdę sposoby na refaktoryzację, ale wszystko powyżej 10 jest zwykle znakiem ostrzegawczym, że coś jest raczej narażone na słabą ekspozycję.

To kolejna rozmowa całkowicie, ale prywatne metody i pola są dla mnie mniej nieprzyjemne, więc jeśli mają duży wpływ na liczbę linii, to chyba nie martwię się. Przynajmniej pokazuje, że prawdopodobnie nie ma jakiegoś boskiego kontrolera, który mnoży obiekt z daleka, co jest dość problematycznym problemem projektowym.

Morgan Herlocker
źródło
2

Spróbuj użyć lepszych danych.

Jednym z przykładów jest ABC Metric . Jest to bardziej miara tego, ile pracy wykonuje kod, niż ile jest kodu.

sylvanaar
źródło
1

Każda linia, która wchodzi w zakres problemowej klasy napisanej poza klasą, jest o jedną linię za mało i o jedną za dużo w klasie, w której mieszka. Pomyśl o klasie jako o temacie. Musisz to zakryć. Idealnie zwięźle jest to idealne, ale jeśli zajmie 500 linii, zajmie 500 linii. Jeśli 100 z tych wierszy dotyczy innego tematu, należą one gdzie indziej. Podział na mniejsze subdomeny wewnątrz klasy jako klasy wewnętrzne ma sens, ale zdefiniowałbym te poza klasą, gdyby miały zastosowanie gdzie indziej.

Erik Reppen
źródło