Zazwyczaj dobrze jest to robić, gdy tylko jest to możliwe, ale lubię myśleć o tego rodzaju pracy nie jako o „krokach”, ale o podzadaniach .
Podzadanie jest określoną jednostką pracy, którą można wykonać: ma określoną odpowiedzialność oraz zdefiniowane dane wejściowe i dane wyjściowe (pomyśl o „S” w SOLID ). Podzadanie nie musi nadawać się do ponownego użycia: niektórzy ludzie myślą: „Nigdy nie będę musiał dzwonić do tego z niczego innego, więc po co pisać to jako funkcję?” ale to błąd.
Spróbuję również przedstawić korzyści i sposób, w jaki dotyczy to funkcji zagnieżdżonych (zamknięć) w porównaniu z inną funkcją w klasie. Ogólnie rzecz biorąc, zalecałbym, aby nie używać zamknięć, chyba że są one szczególnie potrzebne (istnieje wiele zastosowań, ale dzielenie kodu na logiczne części nie jest jednym z nich).
Czytelność.
Ponad 200 wierszy kodu proceduralnego (treści funkcji) jest trudnych do odczytania. 2-20 funkcji linii jest łatwych do odczytania. Kod jest dla ludzi.
Zagnieżdżone czy nie, przeważnie zyskujesz na czytelności, chyba że używasz wielu zmiennych z zakresu nadrzędnego, w którym to przypadku odczytanie może być równie trudne.
Ogranicz zakres zmiennej
Posiadanie innej funkcji zmusza cię do ograniczenia zakresu zmiennej, a konkretnie przekazania tego, czego potrzebujesz.
Często powoduje to również lepszą strukturę kodu, ponieważ jeśli potrzebujesz jakiejś zmiennej stanu z wcześniejszego „kroku”, może się okazać, że istnieje inna podzadanie, które powinno zostać napisane i wykonane jako pierwsze, aby uzyskać tę wartość. Innymi słowy, utrudnia to pisanie wysoce sprzężonych fragmentów kodu.
Posiadanie funkcji zagnieżdżonych umożliwia dostęp do zmiennych w zakresie nadrzędnym z wnętrza funkcji zagnieżdżonej (zamknięcie). Może to być bardzo przydatne, ale może również prowadzić do subtelnych, trudnych do znalezienia błędów, ponieważ wykonanie funkcji może nie nastąpić w sposób, w jaki został napisany. Jest tak nawet w przypadku, gdy modyfikujesz zmienne w zakresie nadrzędnym (ogólnie bardzo zły pomysł).
Testy jednostkowe
Każda podzadanie, zaimplementowana funkcja (lub nawet klasa) jest samodzielnym, testowalnym fragmentem kodu. Korzyści z testów jednostkowych i TDD są dobrze udokumentowane gdzie indziej.
Korzystanie z zagnieżdżonych funkcji / zamknięć nie pozwala na testowanie jednostkowe. Dla mnie jest to przełom i powód, dla którego powinieneś po prostu inną funkcję, chyba że istnieje szczególna potrzeba zamknięcia.
Praca w zespole / projekt z góry na dół
Podzadania mogą być pisane przez różne osoby, niezależnie, w razie potrzeby.
Nawet samemu przydaje się przy pisaniu kodu, aby po prostu wywołać podzadanie, które jeszcze nie istnieje, jednocześnie budując główną funkcjonalność, i martwić się o faktyczne wdrożenie podzadania tylko wtedy, gdy wiesz, że uzyska on potrzebne wyniki w znaczący sposób. Jest to również nazywane odgórnym projektowaniem / programowaniem.
Ponowne użycie kodu
Okej, więc pomimo tego, co powiedziałem wcześniej, czasem tak naprawdę jest powód do ponownego użycia podzadania do czegoś innego. W ogóle nie jestem zwolennikiem „architektury astronautów”, ale po prostu pisząc luźno powiązany kod, możesz później skorzystać z ponownego użycia.
Często ponowne użycie oznacza pewne refaktoryzowanie, co jest całkowicie oczekiwane, ale refaktoryzacja parametrów wejściowych do małej samodzielnej funkcji jest DUŻO łatwiejsza niż wyodrębnienie jej z ponad 200 funkcji liniowych kilka miesięcy po jej napisaniu, co jest naprawdę moim celem tutaj.
Jeśli użyjesz funkcji zagnieżdżonej, ponowne użycie jej jest generalnie kwestią refaktoryzacji do oddzielnej funkcji, co znowu jest powodem, dla którego twierdzę, że zagnieżdżenie nie jest właściwą drogą.