W którym momencie / zakresie plik kodu jest zbyt duży?

36

Znajduję dużo 2-3k plików liniowych i nie wydaje mi się, żeby były tak duże.

Jakie są dobre kryteria, aby obiektywnie nazwać plik kodu źródłowego „zbyt dużym”? Czy istnieje coś takiego jak maksymalna liczba linii, które powinien mieć plik kodu źródłowego?

dukeofgaming
źródło
Twój rówieśnik powie ci po przejrzeniu kodu. „Nie możesz tego ustalić sam, ponieważ wiesz więcej, jak mówi autor, niż sam kod. Komputer nie może ci powiedzieć, z tych samych powodów, dla których nie może stwierdzić, czy obraz jest sztuką, czy nie. Dlatego potrzebujesz innego człowieka zdolnego utrzymywania oprogramowania - aby spojrzeć na to, co napisałeś i wyrazić swoją opinię ... ”
gnat
Niektóre kompilatory miały dziwne ograniczenia rozmiaru kodu źródłowego: maksymalna długość linii lub maksymalna liczba linii. Gdy kompilator narzeka, jest to obiektywny wskaźnik, że kod jest zbyt duży (lub że nadszedł czas na aktualizację).
mouviciel
2
Podziel jak najwięcej, ale bez naruszania integralności plików. Każdy plik (lub para plików nagłówkowych / źródłowych) powinien zawsze być zaokrągloną całością, niezależną od wewnętrznej implementacji innych plików. Jeśli to oznacza, że ​​niektóre pliki będą duże, ponieważ implementują coś złożonego, niech tak będzie.
Ambroz Bizjak
Zauważ, że złożoność to nie tylko liczby, ale także struktura. Na przykład chciałbym powiedzieć, że python zen „mieszkanie jest lepsze niż zagnieżdżone”: płaska lista 100 przypadków jest prostsza niż hierarchia (nie pamiętasz wszystkich 100 przypadków, ale łatwo pamiętasz, że istnieje 100 alternatyw) . A „zwykła” hierarchia, w której gałęzie mają tę samą strukturę niż ich rodzeństwo, jest prostsza niż hierarchia z nieregularną podstrukturą.
Juh_
„Czy to kod źródłowy?” „Nie, to plik makefile. Kod źródłowy znajduje się w ciężarówkach za nimi”.
mckenzm

Odpowiedzi:

26

Jako model idealny wykorzystuję następujące kryteria (z podobnym uzasadnieniem, jak sugerował Martin Beckett, tj. Myślenie w kategoriach logicznej struktury, a nie w liniach kodu):

Zasada nr 1

Jedna klasa na plik (w C ++: jedna klasa -> jeden nagłówek i jeden plik implementacyjny).

Zasada 2

Siedem jest uważane za liczbę przedmiotów, które nasz mózg może obserwować w tym samym czasie bez pomieszania. Powyżej 7 trudno nam mieć przegląd tego, co widzimy. Dlatego: każda klasa nie powinna mieć więcej niż 7-10 metod. Klasa, która ma więcej niż 10 metod, jest prawdopodobnie zbyt złożona i powinieneś spróbować ją podzielić. Podział jest bardzo skuteczną metodą, ponieważ za każdym razem, gdy dzielisz klasę, zmniejszasz złożoność każdej z klas przynajmniej 2 razy.

Zasada 3

Ciało metody, które nie mieści się na jednym lub dwóch ekranach, jest zbyt duże (zakładam, że okno ekranu / edytora ma około 50 linii). Idealnie możesz zobaczyć całą metodę w jednym oknie. Jeśli tak nie jest, wystarczy przewinąć w górę i w dół, nie zapominając o części metody, która się ukrywa. Tak więc, jeśli musisz przewinąć więcej niż jeden ekran w górę lub w dół, aby przeczytać całą treść metody, Twoja metoda jest prawdopodobnie zbyt duża i łatwo możesz stracić ogólny przegląd.

Ponownie, dzielenie metod za pomocą prywatnych metod pomocy może bardzo szybko zmniejszyć złożoność metod (przy każdym podziale złożoność jest co najmniej o połowę). Jeśli wprowadzisz zbyt wiele metod pomocy prywatnej, możesz rozważyć utworzenie oddzielnej klasy do ich gromadzenia (jeśli masz więcej metod prywatnych niż publicznych, może druga klasa ukrywa się w twojej klasie głównej).

Łącząc te bardzo przybliżone szacunki:

  • Maksymalnie jedna klasa na plik źródłowy.
  • Maksymalnie 10 metod publicznych na klasę.
  • Maksymalnie 10 metod prywatnych na klasę.
  • Maksymalnie 100 linii na metodę.

Plik źródłowy zawierający ponad 2000 wierszy jest prawdopodobnie zbyt duży i zaczyna być zbyt nieuporządkowany.

To jest naprawdę bardzo przybliżony szacunek i nie przestrzegam tych kryteriów systematycznie (zwłaszcza, że ​​nie zawsze jest wystarczająco dużo czasu na właściwe refaktoryzowanie). Ponadto, jak zasugerował Martin Beckett, są sytuacje, w których klasa jest dużym zbiorem metod i nie ma sensu rozdzielać ich w sztuczny sposób, aby zmniejszyć klasę.

Tak czy inaczej, z mojego doświadczenia wynika, że ​​plik zaczyna być nieczytelny, gdy jeden z powyższych parametrów nie jest przestrzegany (np. Treść metody 300 linii, która obejmuje sześć ekranów, lub plik źródłowy zawierający 5000 linii kodu).

Giorgio
źródło
1
Chciałbym również dążyć do metod nie więcej niż 10 linii ... pomaga w czytaniu / zrozumieniu, co robi metoda i zmniejsza złożoność, która może się łatwo zdarzyć w dużych metodach ...
Zack Macomber
4
Zasada 2 jest absurdalna, jeśli będziesz ją przestrzegać. Nie powinieneś mieć więcej niż 7 plików w katalogu, więc musisz utrzymywać duże pliki, aby nie pomylić dziesiątek lub setek plików w swoim projekcie. Podobnie głęboko zagnieżdżona struktura katalogów jest zbyt myląca, dlatego lepiej jest przechowywać kilka dużych plików w jednym katalogu niż rozrzucać wszystko dookoła.
hasen
1
Przykro mi, że ta odpowiedź opiera się na całkowicie arbitralnych danych. „7 przedmiotów” to oczywiste bzdury, w przeciwnym razie alfabet nie byłby możliwy. Rozmiar obiektu powinien opierać się na rozdzieleniu problemów, odpowiedzialności pojedynczej, sprzężeniu o wysokiej spójności i podobnych zasadach, a nie na liczbach arbitralnych.
JacquesB
1
@JacquesB 7 pozycji zwykle wskazuje na 7 niepowiązanych informacji. Jeśli twój mózg może kojarzyć lub grupować informacje, w prawdziwym sensie jest to 1 informacja, która może prowadzić do większej liczby, jeśli spróbujesz przypomnieć sobie (w rzeczywistości „alfabet” jest symbolem, a nie wszystkimi 26 literami). Lepszym przykładem może być próba zapamiętania 7-cyfrowego numeru przekazanego ci przez telefon, bez długopisu i papieru. Metody najwyraźniej nie są liczbami arbitralnymi, ale jeśli metody te odnoszą się do tego, co kodujesz, możesz spodziewać się po 7, musisz poszukać go, zanim będziesz mógł poprawnie przywołać.
Neil,
3
@ Neil: Jeśli metody w klasie są przypadkowymi niepowiązanymi ze sobą informacjami, wtedy masz większe problemy z projektowaniem klasy niż liczba metod.
JacquesB
33

Nie - nie w zakresie linii kodu. Sterownik powinien być logicznym grupowaniem. Na przykład z pewnością nie powinno być wielu klas w jednym dużym pliku

Jeśli posiadasz klasę, która zgodnie z prawem ma kilkaset metod (co nie jest niemożliwe w powiedzmy modelowaniu 3D), byłoby znacznie mniej wygodnie podzielić ją na dowolne pliki. Kiedyś musieliśmy to robić, gdy pamięć była coraz rzadsza, a procesory wolniejsze - i było to bolesne, ciągle szukając definicji funkcji.

Martin Beckett
źródło
2
Czy klasa z setkami metod nie byłaby przejawem zazdrości klasowej, braku spójności, złego projektu, naruszenia zasady pojedynczej odpowiedzialności itp.?
Tulains Córdova
2
@ user1598390: zwykle, ale nie zawsze.
whatsisname
4
@ user1598390 - często mówi się, że modelowanie gis / 3d ma wiele operacji, które można wykonać, a następnie ma przeciążenie dla sygnałów 2d, 3d, 4d, 3d +, a następnie float / double / integer itp. - szablony pomagają trochę, ale dla wydajności wiele operacji jest często lepszych niż dziedziczna klasa klasowa
Martin Beckett
2
@ tp1 - a używasz małej czcionki, aby nie zajmowały tyle miejsca?
Martin Beckett,
2
@ tp1 Stary, przepraszam, naprawdę nie mam na myśli braku szacunku, ale współczuję temu, kto z wami pracuje. Jeśli masz 1200 klas, skorzystaj z konwencji katalogów, jeśli masz zbyt wiele katalogów, podziel je na niezależne moduły / biblioteki.
dukeofgaming,
8

Gdy kod w nim staje się niemożliwy do utrzymania. tzn .: nie możesz po prostu obserwować kodu, czy metoda / klasa / funkcja, której szukasz (i musisz edytować / debugować), jest tam, czy nie, a jeśli tak, to gdzie ona jest.

Jednak wybór IDE / edytora i funkcje będą miały wpływ na rzeczywistą kwantyfikację tego górnego limitu. Kod składany , funkcja / metoda wystawianie i wyszukiwanie będzie odłożyć W chwili obecnej opracowywanie scenariuszy prezenty.

Ale kiedy to nastąpi, czas to rozdzielić.

ZJR
źródło
2

Oto alternatywny widok: pytasz o sposób ograniczenia rozmiaru pliku. Moim zdaniem jest wiele czynników, które sprawiają, że duże pliki kodu są bardzo problematyczne. Czasami plik kodu jest ogromny, ale jego zawartość jest dobrze zgrupowana i wyjątkowo czysta, dzięki czemu rozmiar nie powoduje znaczących problemów. Widziałem wiele plików, które są bardzo czytelne pomimo wysokiego LOC.

Zamiast korzystać z danych LOC, wolę pomyśleć o użyciu danych historycznych, aby zrozumieć, jak często kod ulega uszkodzeniu w tych dużych plikach. Zwykle powodem tego jest to, że programiści nie mają czasu na cierpliwość, aby sprawdzić odpowiednie inne miejsca w tym samym pliku i dokonać zmiany z mentalnością „szybkiej poprawki” bez wystarczającego zrozumienia.

Większe niebezpieczeństwo stanowi obecność kodu kopiuj-wklej. Kodowanie kopiuj-wklej naturalnie przyspiesza także wzrost LOC. Myślę, że wyeliminowanie kopiowania i wklejania jest jeszcze ważniejsze niż utrzymywanie LOC poniżej jakiejś magicznej liczby. Oprócz czystego kopiowania i wklejania istnieje również drugie niebezpieczeństwo w dużych plikach: nakładanie się funkcji. Im większy plik, tym bardziej prawdopodobne jest, że ponownie wdrożysz fragment kodu, który znajduje się już w innej sekcji tego samego pliku.

Tak więc, dopóki współczynnik naprawiania błędów (stosunek zatwierdzeń napraw błędów do wszystkich zatwierdzeń) jest niski dla większych plików, sytuacja jest do przyjęcia. Spróbuj git logi przejrzyj, ile zatwierdzeń związanych jest z błędami. Lub użyj narzędzia, które może automatycznie je analizować i wizualizować, np . Softagram .

Ville Laitila
źródło
-1

Zastanów się nad tym Metaphor. Jeśli chodzi o długość kodu, myślę, że powinniśmy rozważyć następujące kwestie:

The Cat in The Hat (50 pp.)

i

Lord of The Rings (1,178 pp.)

Nie ma w tym nic złego Lord of the Rings. To fantastyczna książka. The Cat in the Hatto także świetna książka. Oba mogą być zrozumiane przez 5-latków, ale tylko jeden jest bardziej odpowiedni ze względu na treść.

Moim zdaniem pisanie kodu powinno mieć sens dla 5-latka, kiedy tylko możemy. Cyclomatic Complexityto ważna koncepcja, którą programiści powinni rozważyć podczas generowania kodu. Wykorzystywanie i tworzenie bibliotek w celu maksymalnego zwiększenia funkcjonalności i ponownego wykorzystania kodu. W ten sposób nasz kod może mówić więcej woluminów niż napisane.

Większość z nas nie pisze kodu asemblera . Ale rdzeniem naszego kodu jest asembler. Przeszukiwanie zestawu 10000 linii jest trudniejsze niż 10000 linii Pythona, jeśli jest wykonane poprawnie.

Ale niektóre prace wymagają napisania 500 do 1000 wierszy. Naszym celem z kodem powinno być napisanie 300 linii czystego kodu.

Jako programiści chcemy napisać „Władca pierścieni”. Dopóki nie dostaniemy błędu i nie chcielibyśmy pisać „Cat in the Hat”. Nie rób kodowania miarą ego. Po prostu spraw, aby wszystko działało w prosty sposób.

Programiści nie chcą dokumentować kodu (uwielbiam kodować osobiście, nie jestem samolubny). Nie pisz więc kodu, który tylko Ty możesz zrozumieć / odczytać. Napisz Cat in the Hatkod.

Wszyscy wiemy, że jesteś JRR Tolken (w twojej głowie). Pamiętaj, że nie będziesz miał nic do udowodnienia za pomocą kodu wolnego od błędów.

Kolejny powód metafory.

Nie przesadzaj, czytelnik rozprowadza bogactwo. Jeśli pracujesz z grupą ludzi i wszyscy będą musieli zmienić ten sam duży plik, prawdopodobnie doprowadzisz się do gitpiekła.

Wszyscy uwielbiają opierać się.

-> Nikt nigdy nie powiedział!

TL; DR Nacisk na czytelność. Rozłóż swój kod i pomocnika w wielu wierszach i plikach tak bardzo, jak to możliwe. Nie wyrzucaj 8 lub 9 klas w jednym pliku, to sprawia, że ​​kod jest trudny do odczytania i trudniejszy do utrzymania. Jeśli masz duży kod warunku lub pętlę, rozważ zmianę go na Lambdas, jeśli język go obsługuje. Funkcje narzędzi powinny być uważane za doskonałą drogę do zwiększenia czytelności kodu. Unikaj intensywnego zagnieżdżania.

GetBackerZ
źródło
Nie jest to downvoter, ale twoja analogia jest dla mnie trochę zagubiona. Czy mówisz, że lepiej jest rozłożyć kod na wiele wierszy i mieć mniej słów w każdym wierszu?
Fodder
Rozłóż kod i pomocnika w wielu wierszach i plikach tak bardzo, jak to możliwe. Nacisk na czytelność. Nie rzucaj 8 lub 9 klas w jednym pliku. To sprawia, że ​​kod jest trudny do odczytania i trudniejszy w utrzymaniu. Jeśli masz duży kod stanu lub pętle. Zamień je w narzędzia. Unikaj intensywnego zagnieżdżania. Daj mi znać, jeśli to pomoże to wyjaśnić.
GetBackerZ
Być może powinieneś to zmienić w swojej odpowiedzi, ponieważ dzięki temu wyjaśnisz, co masz na myśli.
Fodder
Użyłem skryptu dla Jackie Brown jako miernika dla modułowych programów COBOL z / OS. Wiesz, na pogawędkę na przyjęciu ...
mckenzm
„ma sens dla pięciolatka, kiedy tylko możemy”. - w przypadku rzeczywistych problemów, które płacą rachunki, jest to rzadko możliwe i ma na celu coś złego
whatsisname