Kilka razy widziałem książkę Efektywna praca ze starszym kodem . Jakie są kluczowe punkty tej książki?
Czy jest coś więcej do czynienia ze starszym kodem niż dodawanie testów jednostkowych / integracyjnych, a następnie refaktoryzacja?
Kilka razy widziałem książkę Efektywna praca ze starszym kodem . Jakie są kluczowe punkty tej książki?
Czy jest coś więcej do czynienia ze starszym kodem niż dodawanie testów jednostkowych / integracyjnych, a następnie refaktoryzacja?
Odpowiedzi:
Kluczowym problemem związanym ze starszym kodem jest brak testów. Musisz więc dodać trochę (a potem więcej ...).
To samo w sobie wymagałoby dużo pracy, jak zauważył @mattnz. Jednak szczególny problem ze starszym kodem polega na tym, że nigdy nie został zaprojektowany do testowania . Tak więc zazwyczaj jest to skomplikowany bałagan kodu spaghetti, w którym izolowanie małych części do testowania jednostkowego jest bardzo trudne lub wręcz niemożliwe. Dlatego przed testowaniem jednostkowym należy zmodyfikować kod, aby był bardziej testowalny.
Jednak w celu bezpiecznego refaktoryzacji musisz mieć testy jednostkowe, aby sprawdzić, czy nic nie zepsułeś zmianami ... Jest to haczyk 22 starszego kodu.
Książka uczy, jak wyjść z tego haczyka, wprowadzając absolutnie minimalne, najbezpieczniejsze zmiany w kodzie, aby umożliwić pierwsze testy jednostkowe. Nie mają one na celu uczynienia projektu ładniejszym - tylko w celu umożliwienia testów jednostkowych. W rzeczywistości czasami sprawiają, że projekt jest brzydszy lub bardziej złożony. Umożliwiają one jednak pisanie testów - a po przeprowadzeniu testów jednostkowych możesz ulepszyć projekt.
Istnieje wiele sztuczek umożliwiających przetestowanie kodu - niektóre z nich są oczywiste, inne wcale. Są metody, o których nigdy bym nie pomyślał, bez przeczytania książki. Ale jeszcze ważniejsze jest to, że Feathers wyjaśnia, co dokładnie sprawia, że jednostka kodu jest testowalna. Musisz wyciąć zależności i wprowadzić bariery do kodu, ale z dwóch różnych powodów:
Bezpieczne obcięcie zależności może być trudne. Wprowadzenie interfejsów, kpiny i wstrzykiwania zależności jest czyste i przyjemne jako cel, ale niekoniecznie bezpieczne w tym momencie. Czasami więc musimy zastosować podklasę testowanej klasy, aby zastąpić jakąś metodę, która normalnie np. Uruchomiłaby bezpośrednie żądanie do bazy danych. Innym razem możemy nawet wymagać zastąpienia klasy zależności / słoika fałszywą w środowisku testowym ...
Dla mnie najważniejszą koncepcją wprowadzoną przez Feathers są szwy . Szew to miejsce w kodzie, w którym można zmienić zachowanie programu bez modyfikowania samego kodu . Budowanie szwy w kodzie umożliwia oddzielenie kawałek kodu w ramach testu, ale również pozwala wyczuć zachowanie kodu badanego nawet gdy jest to trudne lub niemożliwe do wykonania bezpośrednio (np ponieważ wywołanie wprowadza zmiany w innym obiekcie lub podsystemu , którego stanu nie można zapytać bezpośrednio z metody testowej).
Ta wiedza pozwala dostrzec ziarna testowalności w najokropniejszej kupie kodu i znaleźć minimalne, najmniej zakłócające, najbezpieczniejsze zmiany, aby się tam dostać. Innymi słowy, aby uniknąć dokonywania „oczywistych” refaktoryzacji, które mogą spowodować uszkodzenie kodu bez zauważenia - ponieważ nie masz jeszcze testów jednostkowych, aby to wykryć.
Szybkie sposoby uzyskania kluczowych punktów Efektywnej pracy ze starszym kodem
Pracuję na bazie kodu milionów linii kodu, niektóre z lat 80-tych. To tylko oprogramowanie, więc to tylko kwestia napisania kilku testów jednostkowych, abyś mógł go po prostu przebudować i uczynić o wiele lepszym.
Kluczowe słowo tutaj jest po prostu - to czteroliterowe słowo, które nie należy do słownika programisty, nie mówiąc już o tym, kto pracuje na starszych systemach.
Jak myślisz, ile czasu zajmuje napisanie testu jednostkowego, aby przetestować godzinny wysiłek rozwojowy? W celu omówienia, powiedzmy, kolejna godzina.
Ile czasu zainwestowano w ten milionowy, 20-letni system dziedzictwa? Powiedzmy, że 20 programistów przez 20 lat razy 2000 godzin rocznie (ciężko pracowali). Wybierzmy teraz liczbę - masz nowe komputery i nowe narzędzia i jesteś o wiele mądrzejszy niż faceci, którzy napisali ten kawałek $% ^^ - powiedzmy, że jesteś wart 10 z nich. Masz 40 lat, no cóż, czy ...?
Więc odpowiedź na twoje pytanie jest o wiele więcej. Na przykład ta rutyna, która ma 1000 linii (mam kilka, które mają ponad 5000), jest zbyt skomplikowana i jest kawałkiem spaghetti. Ponowne uwzględnienie go w kilku 100 liniowych procedurach i kilku kolejnych 20 liniowych pomocnikach zajmie tylko (jeszcze jedno czteroliterowe słowo), prawda? ŹLE. W tych 1000 wierszach ukrytych jest 100 poprawek błędów, z których każda stanowi nieudokumentowane wymaganie użytkownika lub niejasny przypadek krawędzi. To 1000 linii, ponieważ oryginalna procedura 100-liniowa nie wykonała zadania.
Musisz pracować z zestawem umysłów „ jeśli się nie zepsuje, nie naprawiaj go ”. Kiedy się zepsuje, musisz być bardzo ostrożny, gdy go naprawiasz - ponieważ poprawiasz go, aby przypadkowo nie zmienić niczego innego. Pamiętaj, że „zepsuty” może zawierać kod, którego nie da się utrzymać, ale działa poprawnie, zależnie od systemu i jego użycia. Zapytaj „co się stanie, jeśli to spieprzę i pogorszę”, bo pewnego dnia to zrobisz i będziesz musiał powiedzieć szefowi szefów, dlaczego to zrobiłeś.
Systemy te zawsze można ulepszyć. Będziesz miał budżet do pracy, harmonogram, cokolwiek. Jeśli nie - idź i zrób jeden. Przestań poprawiać, gdy skończy się czas / pieniądze. Dodaj funkcję, daj sobie czas na jej ulepszenie. Napraw błąd - ponownie poświęć trochę czasu i popraw go. Nigdy nie dostarczaj gorzej niż było na początku.
Książkę należy zabrać z dwóch kluczowych punktów.
Jak zauważyli inni respondenci, próba wyprzedzającej aktualizacji istniejącego starszego kodu jest głupcem . Zamiast tego, ilekroć musisz zmienić stary kod (w celu wprowadzenia nowej funkcji lub poprawki błędu), poświęć czas na usunięcie jego starszego kodu.