Co zostało udowodnione jako dobra maksymalna długość funkcji? [Zamknięte]

44

Czy długość funkcji wpływa na produktywność programisty? Jeśli tak, jaka jest dobra maksymalna liczba linii, aby uniknąć utraty wydajności?

Ponieważ jest to wysoce opiniotwórczy temat, prosimy o uzupełnienie roszczenia niektórymi danymi.

Peter Mortensen
źródło
6
Długość nie powinna być mierzona w LOC, ale w czasie wymaganym do dokładnego zrozumienia, co robi. I ta długość powinna wynosić nie więcej niż minutę. Jeśli nie potrafię tego rozgryźć w ciągu kilku sekund, prawdopodobnie robi to za dużo ... po minucie, na pewno tak jest.
CaffGeek,
13
Maksymalna długość powinna wynosić 17.
ThomasX
1
Pomyśl o S w wersji SOLID.
Kris Krause
1
@CaffGeek A może funkcja polega po prostu na robieniu czegoś niebanalnego. Widziałem funkcje, których pełne zrozumienie zajęłoby mi kilka dni. Nawet funkcje, w których rozumiem wszystkie związane z nimi pojęcia, mogą zająć pół godziny na zapoznanie się ze szczegółami. Chociaż fajnie jest mieć trywialne funkcje, wiele problemów jest po prostu z natury trudnych.
CodesInChaos

Odpowiedzi:

46

Odkąd zacząłem szaloną rakietę w 1970 roku, widziałem dokładnie jeden moduł, który naprawdę musiał być więcej niż jedną wydrukowaną stroną (około 60 linii). Widziałem wiele modułów, które były dłuższe.

W tym przypadku napisałem moduły, które były dłuższe, ale zwykle były to duże maszyny stanów skończonych napisane jako duże instrukcje przełączające.

Problem polega na tym, że w dzisiejszych czasach programiści nie uczą się modularyzacji.

Problemem są również standardy kodowania, które maksymalizują marnotrawstwo przestrzeni pionowej. (Nie spotkałem jeszcze menedżera oprogramowania, który przeczytał „ Psychologię programowania komputerowegoGeralda Weinberga . Weinberg zauważa, że ​​wiele badań wykazało, że rozumienie programisty jest zasadniczo ograniczone do tego, co programista może zobaczyć w danym momencie. programista musi przewijać lub przewracać stronę, ich rozumienie znacznie spada: muszą pamiętać i streszczać.)

Jestem przekonany, że wiele dobrze udokumentowanych wzrostów wydajności programistów z FORTH wynikało z systemu blokowego kodu źródłowego FORTH: moduły były ograniczone do absolutnego maksimum 16 wierszy o długości 64 znaków. Możesz brać pod uwagę czynniki w nieskończoność, ale w żadnym wypadku nie możesz napisać 17-liniowej procedury.

John R. Strohm
źródło
3
Cała filozofia FORTH została zaprojektowana, aby zachęcić do tego ... Miałeś na celu zaprojektowanie własnego słownictwa, nieubłaganie dzieląc swój program na coraz mniejsze części, kończąc na mniejszym skrypcie i więcej słownika. Same limity długości tego nie robią - zobaczysz procedurę podzieloną na dowolne części, aby spełnić jakiś standard kodowania. Myślę, że masz całkowitą rację, podejrzewając, że programiści po prostu „nie uczą się modularyzacji”; to powinno być jednym z największych wygranych OOP, ale z różnych powodów to często de-podkreślić jako celu samym w sobie.
Shog9
1
@Pan. CRT: Ograniczenia długości w zorientowanych blokowo implementacjach FORTH MODUŁOWOŚĆ FORCED. Interaktywny charakter większości FORTH pomaga, zachęcając małe moduły i szybkie testowanie tych modułów. D85, FORTH oparty na plikach, nie wymusił modularyzacji i widziałem, jak faceci grający z D85 piszą z nim wiele modułów do śledzenia strumienia świadomości programistów. Stąd moje przekonanie. (Co do tego, co jest warte, Liz Rather nie zgadza się ze mną. Uważa, że ​​to głównie interaktywność daje FORTH wzrost wydajności.)
John R. Strohm,
2
+1, aby przedstawić mi świetną książkę „Psychologia programowania komputerowego” :)
Samuel
30

Jaki naprawdę jest odpowiedni rozmiar?

Zależy od używanego języka, ale ogólnie (i według mojego osobistego gustu):

  • Idealnie mniej niż 25 linii.
  • Dopuszczalnie mniej niż 35 linii.

Jeśli to więcej, to muszę do tego wrócić i przerobić.

Ale realistycznie , każdy rozmiar musi być, gdy trzeba coś dostarczyć, i że bardziej sensowne jest w tej chwili wyplenienie ich w ten sposób, sprawia, że ​​czasami jeszcze łatwiej jest komuś sprawdzić przed wysyłką. (ale nadal wracam do tego później).

(Niedawno mój zespół uruchomił program w naszej bazie kodu: znaleźliśmy klasę z 197 metodami, a drugą tylko z 3 metodami, ale jedna z nich miała 600 linii. Urocza gra: co jest gorsze z 2 zła?)


Teraz, aby uzyskać bardziej zenową odpowiedź ... Ogólnie rzecz biorąc, dobrą praktyką (TM) jest cytowanie jednego lub dwóch wielkich ludzi, więc oto:

Wszystko powinno być tak proste, jak to możliwe, ale nie prostsze. - A. Einstein

Doskonałość zostaje ostatecznie osiągnięta nie wtedy, gdy nie ma już nic do dodania, ale kiedy nie ma już nic do zabrania. - A. de Saint Exupéry


Dodatek do stylów komentarzy

Jako uzupełnienie tego, twoje funkcje powinny mieć jasne nazwy wyjaśniające ich zamiary. Jeśli chodzi o komentarze, zwykle nie komentuję wewnątrz funkcji:

  • komentarze mówią „dlaczego?” ,
  • kod mówi „jak?” .

Wystarczy blok komentarza u góry każdej funkcji (który wymaga wyjaśnienia). Jeśli twoja funkcja jest mała, a nazwy funkcji są wystarczająco wyraźne, powinieneś po prostu powiedzieć, co chcesz osiągnąć i dlaczego. Używam wbudowanych komentarzy tylko dla pól w niektórych językach lub na początku bloku dla funkcji, które łamią reguły 25-35 linii, jeśli zamiar jest niejasny. Używam komentarza blokowego wewnątrz kodu, gdy występują wyjątkowe sytuacje (blok przechwytujący, w którym nie potrzebujesz lub nie chcesz nic robić, powinien mieć komentarz wyjaśniający, na przykład, dlaczego).

Aby uzyskać więcej informacji, przeczytaj moją odpowiedź na temat stylu i zalecenia dotyczące komentowania kodu

przyłbica
źródło
@haylem Myślę, że to jest wersja dla programistów Freddy vs.Jason :-)
Gaurav
Zgadzam się, ale chciałbym dodać, że powinna mieć rozmiar jednej strony ekranu. jeśli masz 72 linie na jednej stronie ekranu, funkcja nie powinna przekraczać 72 linii.
Nazwa wyświetlana
@ Należy upewnić się, że jedna funkcja zachowa się również na stronie ekranu, aby się nie przewijać, ale zwykle nie jest to moim głównym zmartwieniem. Obawiam się, ile czasu zajmuje przetworzenie informacji podczas czytania funkcji, i jest to prawie natychmiastowe, jeśli jest to wyraźnie napisane w 25 liniach. Staje się to kwestią śledzenia wywołań funkcji. 72 jest dla mnie zdecydowanie za duża (a co, jeśli masz podzielone ekrany? I to zależy od czcionki. Ale zgadzam się z historyczną wartością rekomendacji)
haylem
1
Oczywiście czasami masz funkcje, w których po prostu kopiujesz 70 różnych pól do 70 różnych miejsc. Najczęściej używam ttdo ich generowania, ale czasami utkniesz w funkcji długiego tyłka (lub funkcji długiego tyłka), która tak naprawdę nie robi nic interesującego, więc nie jest to prawdziwy problem.
konfigurator
1
Kiedy funkcja jest np Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3);. Jest całkiem jasne, że wszystko jest takie samo. (Uwaga: to tylko przykład; tego rodzaju funkcja pojawia się od czasu do czasu)
konfigurator
12

Moim zdaniem każda funkcja powinna być jak najmniejsza. Każda funkcja powinna robić tylko jedną rzecz i robić to dobrze. To tak naprawdę nie odpowiada na pytanie o maksymalną długość, ale bardziej odczuwam długość funkcji.

Aby użyć słów wuja Boba: „Wyodrębniaj, dopóki nie będziesz mógł już więcej wyodrębnić. Wyodrębniaj, aż upuścisz”.

Jason
źródło
2
Co rozumiesz przez tak mały, jak to możliwe? Czy nie byłoby tak małe, jak to możliwe, aby każda funkcja zawierała tylko dwie linie: jedną do wykonania pojedynczej operacji, a drugą do wywołania funkcji, która wykona resztę?
Kelmikra
Wujek Bob ponownie. Myśl za siebie. Nie słuchaj wujków. Doprowadzają cię na manowce.
gnasher729
10

Jaka powinna być maksymalna wysokość budynku? Zależy od tego, gdzie jest kompilacja lub jaka ma być wysokość.
Możesz uzyskać różne odpowiedzi od różnych osób pochodzących z innego miasta.
Niektóre funkcje skryptów i procedury obsługi przerwań jądra są bardzo długie.

Huang F. Lei
źródło
Całkowicie się z tobą zgadzam. Lubię metafory. :) Budynek o trzech kondygnacjach mógł zostać zbudowany przez głupiego architekta, który nie wie, gdzie umieścić prawidłowe wyjście bezpieczeństwa, a inny budynek może mieć dziesięć pięter i być idealnym projektem architektonicznym. Zawsze powinniśmy pamiętać, że czytelność i łatwość konserwacji powinny być głównym powodem zmiany metody na zmniejszenie jego rozmiaru, a nie samego rozmiaru. Nie można zbudować miasta z 90% wieżowca, z wyjątkiem filmów science fiction. :)
Samuel
10

Metodą, która działa dla mnie jest: czy mogę mieć część dłuższej funkcji, nadać nazwę, która ma sens. Myślę, że długość metody nie jest tak ważna jak dobre nazewnictwo. Metoda powinna robić to, co mówi nazwa, nie więcej i nie mniej. I powinieneś być w stanie podać dobre imię. Jeśli nie możesz nazwać swojej metody dobrą, kod prawdopodobnie nie jest dobry razem.

Memento
źródło
I twoja metoda powinna robić tylko jedną rzecz, aby mieć dobre imię ... nie „I”, „Lub” ani nic innego, co powoduje, że nazwa metody ma 50 znaków.
Samuel
10

Tak długo, jak trzeba to robić, co trzeba, ale już nie.

Paul Nathan
źródło
jak mówią w punkcie „Nie ma problemu w punkcie c, którego nie można rozwiązać, dodając kolejny wskaźnik do tego wskaźnika”. zawsze można było dodać inną funkcję pod nim, jego pytanie dotyczyłoby waszego objawienia „gdzie to się kończy?”
Nazwa wyświetlana
1
Odwróciłbym to i powiedziałbym „tak krótko, jak to musi być, ale nie krócej”, ale dostajesz moją +1 za bycie wystarczająco blisko :)
Ben Hughes
6

Myślę, że jest kompromis. Jeśli masz wiele krótkich metod, często trudniej jest je debugować niż jedną długą. Jeśli będziesz musiał skakać po edytorze 20 lub 30 razy, aby prześledzić jedno wywołanie metody, trudno będzie zachować to wszystko w głowie. Tymczasem, jeśli istnieje jedna dobrze napisana jasna metoda, nawet jeśli jest to 100 linii, często łatwiej jest zachować ją w głowie.

Prawdziwe pytanie brzmi: dlaczego elementy powinny być w różnych metodach, a odpowiedź, jak podano powyżej, to ponowne użycie kodu. Jeśli nie używasz ponownie kodu (lub nie wiesz), warto pozostawić go w jednej gigantycznej, łatwej do naśladowania metodzie, a następnie, gdy trzeba go ponownie użyć, podziel części, które wymagają ponownego przy użyciu mniejszych metod.

W rzeczywistości częścią dobrego projektowania metod jest tworzenie funkcjonalnie spójnych metod (w zasadzie robią jedną rzecz). Długość metod nie ma znaczenia. Jeśli funkcja wykonuje jedną dobrze zdefiniowaną rzecz i ma 1000 wierszy, jest to dobra metoda. Jeśli funkcja wykonuje 3 lub 4 rzeczy i ma tylko 15 linii, jest to zła metoda ...

Cervo
źródło
Lubię krótkie metody.
Marcie,
Podoba mi się to, co powiedziałeś, ponieważ stwierdzenie, że metoda nie powinna zawierać więcej niż 10 linii, jest moim zdaniem utopią. Ok, to dobra zasada, o której należy pamiętać za każdym razem, gdy piszesz metodę, ale nie powinna to być zasada matematyczna, taka jak 1 + 1 = 2. Jeśli przestrzegasz zasad takich jak KISS, DRY, YAGNI itp., A twoje metody są nie pełne komentarze wyjaśniające niektóre szczegóły, ponieważ są one zbyt długie, metody mogą zawierać 100 wierszy kodu i mogą być całkowicie czyste do zrozumienia i utrzymania. Jednak powinien to być raczej wyjątek niż nawyk. Myślę, że przypadek przełączania w metodzie fabrycznej jest dobrym przykładem wyjątku.
Samuel
5

Łatwiej jest mi śledzić, co robię, jeśli mogę zobaczyć całą funkcję naraz. Oto jak wolę pisać funkcje:

  1. Wystarczająco krótki, aby zmieścił się na moim monitorze z rozsądną czcionką.
  2. Jeśli musi być dłuższy niż nr 1, wystarczy go wydrukować na kawałku papieru rozsądną czcionką.
  3. Jeśli musi być dłuższy niż nr 2, wystarczy na tyle krótko, aby wydrukować 2 strony na kartce papieru.

Rzadko piszę funkcje dłuższe niż to. Większość z nich to gigantyczne instrukcje przełączników C / C ++.

Bob Murphy
źródło
Wystarczająco krótki, aby zmieścił się na monitorze, jest fajny, ale określa typ i rozmiar czcionki. Moim zdaniem papier nie powinien być regułą, ponieważ mamy rok 2013 i kto nadal drukuje kod na papierze, kto wydrukuje, aby sprawdzić, czy pasuje do rozmiaru papieru? Dzięki takim narzędziom, jak Visual Studio i intellisense, nie ma już powodu, aby analizować kod za pomocą papieru.
Samuel
5

Dla mnie funkcja jest dowolną długością, jaką musi być. W większości przypadków dzielę go na moment, kiedy ponownie użyję kodu.

Zasadniczo pozostanę przy głównej „wysokiej kohezji, niskim sprzężeniu” i nie ma ograniczeń co do długości.

Ross
źródło
5

Pytanie powinno brzmieć, ile funkcji powinna wykonać funkcja. I zwykle zdarza się, że potrzebujesz 100 linii, aby zrobić „jedną” rzecz. Znowu zależy to od poziomu, z którego patrzysz na kod: czy hashowanie to jedno? A może mieszanie i zapisywanie hasła to jedno?

Powiedziałbym, że zacznij od zapisania hasła jako jednej funkcji. Kiedy wydaje Ci się, że skrót jest inny, zmienisz kod. W żadnym wypadku nie jestem ekspertem od programowania, ale IMHO, cała idea funkcji zaczyna się od małych, że im bardziej atomowe są twoje funkcje, tym większa szansa na ponowne użycie kodu, nigdy nie zmuszając się do zmiany w więcej niż jednym miejscu itd.

Widziałem procedury składowane SQL , które działają ponad 1000 linii. Czy liczba wierszy procedur przechowywanych również jest mniejsza niż 50? Nie wiem, ale to sprawia, że ​​czytanie kodu jest piekłem. Nie tylko musisz ciągle przewijać w górę i w dół, musisz nadać kilku wierszom kodu nazwę „to robi sprawdzanie poprawności1”, „to aktualizacje w bazie danych” itp. - praca, którą programista powinien był wykonać.

Narayana
źródło
+1 tylko dla pierwszego akapitu. wszystko inne dotyczy sprawy, nad którą pracujesz.
Nazwa wyświetlana
Jak pomaga podział na 50 funkcji? Kiedy funkcje muszą się komunikować, więc nie skończysz z 500 liniami, a tysiącem?
gnasher729
5

Ze złożoności cyklicznej (Wikipedia):

Cyklomatyczna złożoność sekcji kodu źródłowego to liczba liniowo niezależnych ścieżek w kodzie źródłowym.

  • Zalecam, aby utrzymać tę liczbę poniżej 10 w jednej metodzie. Jeśli dojdzie do 10, nadszedł czas na ponowne uwzględnienie.

  • Istnieją narzędzia, które mogą ocenić kod i dać cykliczną liczbę złożoności.

  • Powinieneś starać się zintegrować te narzędzia ze swoim rurociągiem kompilacji.

  • Nie dosłownie ścigaj rozmiaru metody, ale spróbuj spojrzeć na jej złożoność i obowiązki. Jeśli ma więcej niż jedną odpowiedzialność, prawdopodobnie dobrym pomysłem jest ponowne uwzględnienie. Jeśli jego cykliczna złożoność wzrasta, prawdopodobnie nadszedł czas na ponowne uwzględnienie.

  • Jestem całkiem pewien, że istnieją inne narzędzia, które dają podobne opinie, ale nie miałem jeszcze okazji się temu przyjrzeć.

CodeART
źródło
Wykazano, że cykliczna złożoność, na prawdziwym kodzie z jednego z dużych publicznych repozytoriów, nieskomplikowanych przykładów, jest bardzo silnie skorelowana z surowym SLOC. To sprawia, że ​​jest on w zasadzie bezwartościowy, ponieważ znacznie łatwiej jest liczyć zwroty karetki. (Tak, można grać w SLOC. Bądźmy szczerzy tutaj: jak długo ktoś, kto grał w wskaźniki SLOC u twojego pracodawcy, mógł kontynuować wypłatę?)
John R. Strohm
4

Zazwyczaj staram się zachować moje metody / funkcje zgodnie z tym, co mieści się na ekranie monitora 1680x1050. Jeśli to nie pasuje, użyj metod / funkcji pomocniczych, aby wykonać zadanie.

Pomaga czytelność na ekranie i papierze.

Jason
źródło
Robię to samo, ale warto określić, jakiego rodzaju czcionki i rozmiaru używasz. Dla siebie wolę „konsole” o rozmiarze 14, jak sugeruje Scott Hanselman. hanselman.com/blog/… Trudno jest po raz pierwszy pracować z tak dużą czcionką, ale najlepszym rozwiązaniem jest zawsze pamiętać, że twoja metoda powinna być jak najmniejsza.
Samuel
4

Nie stawiam na nic sztywnego ograniczenia, ponieważ niektóre funkcje implementują algorytmy, które są z natury złożone, a każda próba skrócenia ich spowodowałaby, że interakcje między nowymi, krótszymi funkcjami byłyby tak skomplikowane, że wynik netto nie byłby redukcją prostoty. Nie wierzę również, że idea, że ​​funkcja powinna wykonywać tylko „jedną rzecz”, jest dobrym przewodnikiem, ponieważ „jedna rzecz” na wysokim poziomie abstrakcji może być „wieloma rzeczami” na niższym poziomie.

Dla mnie funkcja jest zdecydowanie za długa, jeśli jej długość powoduje obecnie subtelne naruszenia OSUSZANIA, a wyodrębnienie części funkcji do nowej funkcji lub klasy mogłoby to rozwiązać. Funkcja może być zbyt długa, jeśli tak nie jest, ale można łatwo wyodrębnić funkcję lub klasę, które uczynią kod bardziej modułowym w sposób, który może być przydatny w obliczu przewidywalnej zmiany w przyszłości.

dsimcha
źródło
Funkcje wykonują „jedną rzecz” na określonym poziomie abstrakcji, a ty martwisz się tylko o ten jeden poziom abstrakcji. To o to chodzi. Jeśli nie możesz tego pojąć, nie sądzę, że rozumiesz abstrakcję.
Zoran Pavlovic
4

Wystarczająco krótki, aby można go było poprawnie zoptymalizować

Metody powinny być tak krótkie, aby zrobić dokładnie jedną rzecz. Powód tego jest prosty: aby Twój kod mógł zostać odpowiednio zoptymalizowany.

W języku JIT, takim jak Java lub C #, ważne jest, aby metody były proste, aby kompilator JIT mógł szybko tworzyć kod. Dłuższe, bardziej skomplikowane metody naturalnie wymagają więcej czasu JIT. Ponadto kompilatory JIT oferują tylko kilka optymalizacji i korzystają z tego tylko najprostsze metody. Fakt ten został nawet przywołany w Effective C # Billa Wagnera .

W języku niższego poziomu, takim jak C lub C ++, posiadanie krótkich metod (może kilkunastu wierszy) jest również ważne, ponieważ w ten sposób minimalizujesz potrzebę przechowywania zmiennych lokalnych w pamięci RAM, a nie w rejestrze. (Aka „Register Spilling”.) Należy jednak pamiętać, że w tym niezarządzanym przypadku względny koszt każdego wywołania funkcji może być dość wysoki.

Nawet w dynamicznym języku, takim jak Ruby lub Python, posiadanie krótkich metod pomaga również w optymalizacji kompilatora. W języku dynamicznym im bardziej „dynamiczna” jest funkcja, tym trudniej ją zoptymalizować. Na przykład długa metoda, która przyjmuje X i może zwrócić Int, Float lub String, będzie prawdopodobnie działać znacznie wolniej niż trzy osobne metody, z których każda zwraca tylko jeden typ. Wynika to z faktu, że jeśli kompilator wie dokładnie, jaki typ funkcja zwróci, może również zoptymalizować witrynę wywołań funkcji. (Np. Nie sprawdzanie konwersji typu).

Chris Smith
źródło
Około 99,999% aplikacji ma znacznie więcej rzeczy, które spowalniają szybkość programów, takich jak dostęp do bazy danych, dostęp do plików lub opóźnienie sieci. Myślenie o szybkości podczas projektowania metod może być ważnym powodem do grania, aplikacji w czasie rzeczywistym lub raportowania z mnóstwem danych, ale nie w innych przypadkach. Jest to jednak dobra uwaga, ale tak mały jak programista, rzadko muszę przeprowadzać tego typu optymalizację w swoich aplikacjach.
Samuel
Robisz coś takiego, gdy mierzysz szybkość swojego kodu i odkrywasz, że jest on zbyt wolny, jeśli wiesz, co robisz (nie jest to tak proste, jak myślisz), a jeśli zmierzysz go później, a prędkość się poprawi .
gnasher729
3

To bardzo zależy od tego, co jest w kodzie.

Widziałem rutynową linię, z którą nie miałem problemu. To była wielka instrukcja przełączania, żadna opcja nie przekraczała kilkunastu linii, a jedyną strukturą kontrolną w każdej opcji była pojedyncza pętla. W dzisiejszych czasach byłoby napisane obiektami, ale wtedy nie było takiej opcji.

Patrzę też na 120 linii w przełączniku przede mną. Żadna skrzynka nie przekracza 3 linii - strażnika, zadania i przerwy. To parsowanie pliku tekstowego, obiekty nie są możliwe. Każda alternatywa byłaby trudniejsza do odczytania.

Loren Pechtel
źródło
2

Większość kompilatorów nie ma nic przeciwko długości funkcji. Funkcja powinna być funkcjonalna, ale jednocześnie łatwa do zrozumienia, zmiany i ponownego wykorzystania przez ludzi. Wybierz długość, która najbardziej Ci odpowiada.

LennyProgrammers
źródło
1

Moją ogólną zasadą jest, że funkcja powinna pasować do ekranu. Znalazłem tylko trzy przypadki, które naruszają to:

1) Funkcje wysyłki. W dawnych czasach były one powszechne, ale większość z nich jest obecnie zastępowana dziedziczeniem obiektów. Obiekty działają jednak tylko w twoim programie, dlatego od czasu do czasu zobaczysz sporadyczne funkcje wysyłania w przypadku danych przychodzących z innych źródeł.

2) Funkcje, które wykonują całą masę kroków, aby osiągnąć cel i gdzie kroki nie mają dobrego podziału. W efekcie powstaje funkcja, która po prostu wywołuje długą listę innych funkcji w kolejności.

3) Jak nr 2, ale gdzie poszczególne kroki są tak małe, że są po prostu wstawiane, a nie wywoływane osobno.

Loren Pechtel
źródło
1

Może długość funkcji nie jest tak dobrym miernikiem. Staramy się wykorzystywać złożoność cykliczną także w metodach, a jedna z przyszłych metod kontroli źródła kontroli regułuje, że złożoność cykliczna w klasach i metodach musi być mniejsza niż X.

W przypadku metod X jest ustawione na 30, a to dość ciasne.

Peter Mortensen
źródło