Jakie są kluczowe punkty efektywnej pracy ze starszym kodem? [Zamknięte]

133

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?

Armand
źródło
10
Krótka recenzja
napisana
2
Oczywiście chodzi o dodanie testów, a następnie refaktoryzację. Książka w dużej mierze opowiada o tym , jak udaje ci się uzyskać niemożliwie zawiły kodowany test, a na ten temat jest wiele otwartych oczu. Powiedzmy, że Pióra nie biorą żadnych więźniów!
Kilian Foth
9
Być może powinieneś po prostu przeczytać książkę
HLGEM
Ładna recenzja tutaj: andreaangella.com/2014/03/…
rohancragg

Odpowiedzi:

157

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:

  • wykrywanie - w celu sprawdzenia i weryfikacji efektów wykonania fragmentu kodu, oraz
  • separacja - przede wszystkim w celu umieszczenia określonego fragmentu kodu w wiązce testowej.

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ć.

Péter Török
źródło
5
Uwaga: gdy powyższa odpowiedź mówi „testy jednostkowe” , w rzeczywistości oznacza „testy automatyczne” . W przypadku starszych aplikacji duża część początkowo przydatnych automatycznych testów będzie w rzeczywistości testami integracyjnymi (w których logika testów wykonuje większą płytę całego kodu i może powodować awarie z powodu wad w wielu różnych miejscach), a nie prawdziwą jednostkę testy (które mają na celu analizę tylko jednego modułu i wykonanie o wiele mniejszych części kodu).
Lutz Prechelt
99

Szybkie sposoby uzyskania kluczowych punktów Efektywnej pracy ze starszym kodem

MarkJ
źródło
3
Link MP3 na tej stronie Hanselminutes jest uszkodzony, ale ten na hanselminutes.com/165/... nie jest - s3.amazonaws.com/hanselminutes/hanselminutes_0165.mp3 .
Peter Mortensen
Dzięki Rosston za naprawienie łącza PDF. Wygląda na to, że objectmentor.com zniknął - może „wujek Bob” przestał działać?
MarkJ
Nie jestem pewien, co stało się z mentorem obiektów, ale obecnie wujek Bob pracuje dla 7th Light.
Jules
40

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.

mattnz
źródło
2
dzięki za wskazówki! Czy to twoje, czy z książki?
Armand
3
Prawdopodobnie trochę z obu - przeczytałem książkę po kilku latach pracy i prawdopodobnie powinienem przeczytać ją raz po raz. Jak każda dobra książka, sprawi, że podejmiesz wyzwanie tego, co obecnie robisz, wzmocnisz większość tego, co robisz, ale nie ma wszystkich odpowiedzi na określone problemy.
mattnz
7
„Jest to 1000 linii, ponieważ oryginalna procedura 100 linii nie wykonała zadania”. Tak bardzo rzadko wydaje się, że tak jest. Najczęściej jest to 1000 linii po prostu dlatego, że pierwotny programista podwinął rękawy i zaczął kodować, zanim poświęcił choćby chwilę na planowanie lub projektowanie.
Stephen Touset
3
Nie. Mówię, że w większości przypadków (które osobiście spotkałem), 1000 procedur liniowych jest wyraźnymi wskazówkami, że ludzie zaczęli pisać kod, zanim zastanawiali się, jak napisać odpowiednią abstrakcję. Tysiące linii procedur jest z definicji zbyt skomplikowanych - czy mówisz, że tysiąc-liniowa procedura z setkami ukrytych, nieskomunikowanych poprawek błędów jest cechą odpowiedzialnego programisty?
Stephen Touset
16
Jeśli wierzysz w każdy post na tej stronie, każdy ma do czynienia z 1000-wierszowym kodem spaghetti, ale nikt go nigdy nie napisał. Z mojego doświadczenia wynika, że ​​1000 (i 10000) procedur liniowych jest znakiem firmowym deweloperów, którzy robią, co mogą, z tym, co mają, aby dostarczyć to, czego wymaga od nich szef, który wypłaca wynagrodzenie. Uważam to za obraźliwe i aroganckie, ponieważ wielu programistów może swobodnie komentować z boku bez wiedzy o okolicznościach, a jednocześnie nie musi narażać swojej pracy na krytykę.
mattnz
19

Książkę należy zabrać z dwóch kluczowych punktów.

  1. Starszy kod to dowolny kod, który nie jest objęty testem.
  2. Ilekroć musisz zmienić starszy kod, upewnij się, że ma on zasięg.

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.

Michael Brown
źródło
6
+1 Znakomity punkt: „Za każdym razem, gdy trzeba wprowadzić zmiany w starszym kodzie, poświęć czas na usunięcie jego starszego kodu”.
Jan
3
Usuwam status Dziedzictwa, zdobądź mój głos :)
Rachel
7

W pigułce to prawda - dodawanie testów i refaktoryzacja jest tym, o co w tym wszystkim chodzi.

Książka zawiera jednak wiele różnych technik umożliwiających wykonanie tego kodu, który jest bardzo trudny do przetestowania i bezpiecznego refaktoryzacji.

Oded
źródło