Potrafię wymyślić co najmniej dwa argumenty przemawiające za długimi funkcjami:
Oznacza to, że masz dużo kontekstu wokół każdej linii. Sposób sformalizowania tego: narysuj wykres przepływu kontroli swojego kodu. Na wierzchołku (~ = linia) między wejściem funkcji a wyjściem funkcji znasz wszystkie przychodzące krawędzie. Im dłuższa funkcja, tym więcej takich wierzchołków jest.
Wiele małych funkcji oznacza, że istnieje większy i bardziej złożony wykres połączeń. Wybierz losową linię w funkcji losowej i odpowiedz na pytanie „w jakim kontekście jest wykonywana ta linia?” Jest to tym trudniejsze, im większy i bardziej złożony jest wykres połączeń, ponieważ musisz spojrzeć na więcej wierzchołków na tym wykresie.
Istnieją również argumenty przeciwko długim funkcjom - przychodzi na myśl testowanie jednostkowe. Skorzystaj z własnego doświadczenia, wybierając między jednym a drugim.
Uwaga: Nie mówię, że twój szef ma rację, tylko że jego perspektywa nie może być całkowicie pozbawiona wartości.
Myślę, że moim zdaniem dobrym parametrem optymalizacji nie jest długość funkcji. Uważam, że desiderata bardziej przydatna do myślenia jest następująca: jeśli wszystko inne jest równe, lepiej jest móc odczytać z kodu ogólny opis zarówno logiki biznesowej, jak i implementacji. (Szczegóły implementacji niskiego poziomu zawsze można odczytać, jeśli znajdziesz odpowiedni fragment kodu).
Komentując odpowiedź Davida Arno :
Pisanie małych funkcji jest uciążliwe, ponieważ zmusza cię do przejścia do każdej małej funkcji, aby zobaczyć, co robi kod.
Jeśli funkcja ma dobrą nazwę, tak nie jest. isApplicationInProduction jest oczywiste i nie powinno być konieczne sprawdzanie kodu, aby zobaczyć, co robi. W rzeczywistości jest odwrotnie: sprawdzenie kodu ujawnia mniej intencji niż nazwa funkcji (dlatego szef musi uciekać się do komentarzy).
Nazwa pokazuje , co oznacza wartość zwracana , ale nie mówi nic o skutkach wykonania kodu (= co robi kod ). Nazwy (tylko) przekazują informacje o intencji , kod przekazuje informacje o zachowaniu (z których części intencji można czasem wywnioskować).
Czasami chcesz jednego, a czasem drugiego, więc ta obserwacja nie tworzy jednostronnie uniwersalnej reguły decyzyjnej.
Umieść wszystko w głównej dużej pętli, nawet jeśli główna pętla ma więcej niż 300 linii, jest szybszy do odczytania
Skanowanie może być szybsze, ale aby naprawdę „odczytać” kod, musisz być w stanie skutecznie wykonać go w swojej głowie. Jest to łatwe z małymi funkcjami i jest naprawdę bardzo trudne z metodami o długości 100 linii.
Zgadzam się, że musisz to zrobić w swojej głowie. Jeśli masz 500 linii funkcji w jednej dużej funkcji w porównaniu do wielu małych funkcji, nie jest dla mnie jasne, dlaczego jest to łatwiejsze.
Załóżmy, że jest to skrajny przypadek 500 wierszy kodu o wysokim skutku ubocznym, a chcesz wiedzieć, czy efekt A wystąpi przed efektem B. Numery linii. W przypadku wielu małych funkcji musisz pamiętać, gdzie w drzewie wywołań występują efekty, a jeśli zapomniałeś, musisz spędzić niebanalną ilość czasu na odkryciu struktury tego drzewa.
Przechodząc przez drzewo wywołań funkcji pomocniczych, stajesz również przed wyzwaniem ustalenia, kiedy przeszedłeś z logiki biznesowej do szczegółów implementacji. Twierdzę bez dowodów *, że im prostszy wykres połączeń, tym łatwiej jest dokonać takiego rozróżnienia.
(*) Przynajmniej jestem co do tego szczery ;-)
Po raz kolejny myślę, że oba podejścia mają mocne i słabe strony.
Napisz tylko małe funkcje, jeśli musisz powielić kod
Nie zgadzam się. Jak pokazuje twój przykład kodu, małe, dobrze nazwane funkcje poprawiają czytelność kodu i powinny być używane, gdy [np.] Nie jesteś zainteresowany „jak”, tylko „co” z części funkcjonalności.
Niezależnie od tego, czy interesuje Cię „jak” lub „co” jest funkcją celu, dla którego czytasz kod (np. Uzyskanie ogólnego pomysłu a wyśledzenie błędu). Cel, do którego czytasz kod, nie jest dostępny podczas pisania programu i najprawdopodobniej przeczytasz kod do różnych celów; różne decyzje zostaną zoptymalizowane do różnych celów.
To powiedziawszy, jest to część poglądu szefa, z którą prawdopodobnie najbardziej się nie zgadzam.
Nie pisz funkcji o nazwie komentarza, umieść złożony wiersz kodu (3-4 wiersze) z komentarzem powyżej. W ten sposób możesz bezpośrednio zmodyfikować uszkodzony kod
Naprawdę nie rozumiem uzasadnienia tego, zakładając, że to naprawdę poważne. [...] Komentarze mają fundamentalną wadę: nie są kompilowane / interpretowane, więc nie mogą być testowane jednostkowo. Kod zostaje zmodyfikowany, a komentarz zostaje sam, a ty nie wiesz, co jest poprawne.
Kompilatory porównują tylko nazwy dla równości, nigdy nie dają Ci błędu wprowadzającego w błąd. Ponadto, ponieważ kilka witryn wywołujących może wywoływać daną funkcję według nazwy, czasami zmiana nazwy jest bardziej uciążliwa i podatna na błędy. Komentarze nie mają tego problemu. Jest to jednak nieco spekulacyjne; aby naprawdę to rozwiązać, prawdopodobnie potrzebowalibyśmy danych o tym, czy programiści częściej aktualizują wprowadzające w błąd komentarze w porównaniu do wprowadzających w błąd nazw, a ja tego nie mam.