Niedawno rozpocząłem nową pracę, w której pracuję nad bardzo dużą aplikacją (15M loc). W mojej poprzedniej pracy mieliśmy podobnie dużą aplikację, ale (na lepsze lub gorsze) korzystaliśmy z OSGi, co oznaczało, że aplikacja została podzielona na wiele mikrousług, które można niezależnie zmieniać, kompilować i wdrażać. Nowa aplikacja to tylko jedna duża baza kodu, może z kilkoma bibliotekami .dll.
Muszę więc zmienić interfejs tej klasy, ponieważ o to poprosił mój szef. Początkowo napisali to z pewnymi założeniami, które nie uogólniły się zbyt dobrze, i przez pewien czas unikali problemu refaktoryzacji, ponieważ jest tak ściśle powiązany. Zmieniłem interfejs i teraz jest ponad 25 000 błędów. Niektóre błędy występują w klasach z ważnymi brzmiącymi nazwami, takimi jak „XYZPriceCalculator”, które w rzeczywistościnie powinien się złamać. Ale nie mogę uruchomić aplikacji, aby sprawdzić, czy działa, dopóki wszystkie błędy nie zostaną usunięte. I wiele testów jednostkowych albo bezpośrednio odwołuje się do tego interfejsu, albo jest sprzężonych z klasami bazowymi, które odwołują się do tego interfejsu, więc samo ich naprawienie jest bardzo dużym zadaniem. Poza tym tak naprawdę nie wiem, jak te wszystkie elementy pasują do siebie, więc nawet gdybym mógł to zacząć, tak naprawdę nie wiem, jak by to wyglądało, gdyby coś się zepsuło.
Nigdy tak naprawdę nie spotkałem się z takim problemem podczas mojej ostatniej pracy. Co ja robię?
źródło
Odpowiedzi:
25000 błędów w zasadzie oznacza „nie dotykaj tego”. Zmień to z powrotem. Utwórz nową klasę z pożądanym interfejsem i powoli przenieś konsumentów tej klasy do nowej. W zależności od języka możesz oznaczyć starą klasę jako przestarzałą, co może powodować różnego rodzaju ostrzeżenia kompilatora, ale w rzeczywistości nie spowoduje uszkodzenia kompilacji.
Niestety takie rzeczy zdarzają się w starszych bazach kodu. Niewiele można na to poradzić, z wyjątkiem powolnego ulepszania. Kiedy tworzysz nowe klasy, upewnij się, że odpowiednio je testujesz i tworzysz je zgodnie z zasadami SOLID, aby łatwiej było je zmienić w przyszłości.
źródło
Dziel i podbijaj za pomocą refaktoryzacji
Często podzielenie zmiany, którą musisz zrobić, na mniejsze kroki może pomóc, ponieważ możesz wtedy wykonać większość mniejszych kroków w sposób, który wcale nie psuje oprogramowania. Narzędzia do refaktoryzacji bardzo pomagają w takich zadaniach.
Podzielić
Najpierw zidentyfikuj najmniejsze możliwe zmiany (pod względem zmian logicznych, a nie pod względem zmienionego LoC), które sumują się do zmiany, którą chcesz osiągnąć. Szczególnie staraj się wyodrębnić etapy, które są czystymi refaktoryzacjami i mogą być wykonane za pomocą narzędzi.
Podbić
W przypadku skomplikowanych przypadków, takich jak Twoja, sensowne może być wykonanie jednego małego refaktoryzacji na raz, a następnie pozostawienie problemu na odpoczynek, aby wszystkie systemy ciągłej integracji mogły zweryfikować zmianę, a być może zespół testowy również to obejrzał. To potwierdza wykonane kroki.
Aby przeprowadzić konkretną refaktoryzację, absolutnie potrzebujesz wsparcia narzędziowego w przypadku, gdy masz 25 000 stron wywoławczych metody, którą chcesz zmienić. Być może działa również funkcja wyszukiwania i zamiany, ale w tak krytycznym przypadku byłbym wystraszony.
Przykład
Na przykład w języku C # można użyć Resharper do zmiany podpisu metody. Jeśli zmiana jest wystarczająco prosta, np. Dodanie nowego parametru, możesz określić, która wartość powinna być używana w witrynach wywoławczych, które w przeciwnym razie miałyby błąd kompilacji.
Jesteś wtedy bezbłędnie w bazie kodu i możesz uruchomić wszystkie testy jednostkowe, które przejdą, ponieważ była to tylko refaktoryzacja.
Gdy podpis metody będzie wyglądał dobrze, możesz przejść i zastąpić wartości dodane przez Resharper jako argumenty do nowo wprowadzonego parametru. Nie jest to już refaktoryzacja , ale masz bazę kodu wolną od błędów i możesz uruchamiać testy po każdej zmianie wiersza.
Czasami to nie działa
Jest to bardzo przydatne podejście w przypadkach takich jak Twoja, w których jest wiele witryn z połączeniami telefonicznymi. I masz już działające oprogramowanie, więc może być możliwe wykonanie małych kroków refaktoryzacyjnych, aby nieco zmienić sygnaturę, a następnie zrobić kolejny.
Niestety nie zadziała, jeśli zmiana podpisu jest zbyt złożona i nie można jej podzielić na mniejsze zmiany. Ale to rzadkie; podział problemu na mniejsze problemy zwykle pokazuje, że jest to możliwe.
źródło
Wyjaśnij swoje zadanie swojemu szefowi, aby pomóc mu zrozumieć problem i twoje potrzeby jako profesjonalnego programisty.
Jeśli należysz do zespołu, poszukaj głównego programisty i poproś go o radę.
Powodzenia.
źródło
Nie dotykaj tego. Nic nie popełniaj.
Zamiast tego usiądź na krześle i wykrzycz „Heeeeelp !!!!!” tak głośno, jak tylko możesz.
Cóż, niezupełnie tak, ale poproś o radę któregokolwiek z twoich starszych kolegów. Jeśli masz 25 000 błędów, nie naprawiasz błędów, naprawiasz to, co je spowodowało. Starszy kolega powinien być w stanie doradzić, jak wprowadzić zmiany, których chce szef bez 25 000 błędów. Można to zrobić na różne sposoby, ale dobry sposób zależy od konkretnej sytuacji.
I może to być szef powiedział twoim starszym kolegom, aby dokonali tej samej zmiany, a oni powiedzieli „nie”. Ponieważ wiedzieli, co się stanie. Właśnie dlatego dostałeś pracę.
źródło
Osadzonych interfejsów API nie można po prostu zmienić. Jeśli naprawdę chcesz je zmienić, zrób anotację i / lub udokumentuj jako przestarzałe (bez względu na to, na co pozwala język) i udokumentuj, którego interfejsu API należy użyć zamiast tego. Stare API można następnie stopniowo wycofywać ... być może bardzo powoli, w zależności od budżetu czasu na refaktoryzację.
źródło
Oceniać
Oceń, czy ta zmiana jest konieczna, czy możesz dodać nową metodę, a drugą zastąpić.
Naprzód
Jeśli zmiana jest konieczna; konieczny jest plan migracji.
Pierwszym krokiem jest wprowadzenie nowej metody, a stara metoda masuje argumenty, aby mogła wywołać nową. Może to wymagać zakodowania kilku rzeczy; w porządku.
To jest punkt zatwierdzenia: sprawdź, czy wszystkie testy przeszły, zatwierdzają, wypychają.
Migrować
Zajęta praca polega na migracji wszystkich rozmówców starej metody do nowej. Na szczęście można to zrobić stopniowo dzięki spedytorowi.
Więc śmiało; nie wahaj się korzystać z narzędzi do pomocy (
sed
są najbardziej podstawowe, są inne).Oznacz starą metodę jako przestarzałą (z nutą przejścia na nową metodę); pomoże ci dostrzec, czy o czymś zapomniałeś i pomoże, jeśli współpracownik wprowadzi wezwanie do starej metody podczas pracy nad tym.
Jest to punkt zatwierdzenia (a może kilka punktów zatwierdzenia): sprawdź, czy wszystkie testy przeszły, zatwierdzają, wypychają.
Usunąć
Po upływie pewnego czasu (może zaledwie jednego dnia) po prostu usuń starą metodę.
źródło
sed
jest prawdopodobnie złym pomysłem ... Lepiej jest coś, co faktycznie „rozumie” język i nie wprowadza niezamierzonych drastycznych zmian..c_str()
na przykład wywołania ) i wprowadzenia nowych argumentów.sed
trochę działa, kompilator łapie później swoje problemy.sed
(lubed
) może być odpowiednie do tego rodzaju rzeczy - o ile poprawnie przejrzysz różnicę przed zatwierdzeniem.Jeśli zmiana w sygnaturze metody jest jedynie zmianą nazwy, prostym rozwiązaniem jest użycie narzędzi do zautomatyzowania zmiany w 25 000 klas, które odwołują się do danej metody.
Zakładam, że po prostu edytowałeś kod ręcznie, co spowodowało wszystkie błędy. Zakładam również, że znasz Javę (patrz odniesienie do OSGi), więc na przykład w Eclipse (nie wiem, jakiego środowiska programistycznego używasz, ale inne środowiska mają podobne narzędzia do refaktoryzacji) możesz użyć opcji „Refaktoryzacja -> Zmień nazwę” zaktualizować wszystkie odwołania do metody, co powinno pozostawiać bez błędów.
Jeśli dokonujesz innych zmian w podpisie metody niż zmiana nazwy (zmiana liczby lub typów parametrów), możesz użyć opcji „Refaktoryzacja -> Zmień podpis metody”. Jednak są szanse, że będziesz musiał być bardziej ostrożny, jak sugerują inne odpowiedzi. Ponadto, niezależnie od rodzaju zmiany, może to być całkiem niezłe zadanie, dokonując wszystkich zmian w bazie kodu zajętego.
źródło
Oto mój wkład.
Prawdopodobnie nie znasz projektu i jego „funkcji”. Przed wpisaniem jednego wiersza kodu ważne jest, aby zapoznać się z projektem. Więc wycofaj zmiany i zacznij od analizy kodu . (Przynajmniej dotknięty)
Zrozumienie istniejącego rozwiązania daje lepszą perspektywę na to, gdzie się pakujesz. Kontekstualizuj rozwiązanie i jego znaczenie.
Jak wskazał @Greg, powinieneś być w stanie przetestować istniejący kod, aby mieć prawidłowe odwołanie do porównania (testy regresji). Twoje rozwiązanie powinno być w stanie generować takie same wyniki jak istniejące. Na tym etapie nie przejmujesz się, czy wyniki są prawidłowe, czy nie . Pierwszym celem jest refaktoryzacja, a nie naprawianie błędów. Jeśli istniejące rozwiązanie mówi „2 + 2 = 42”, Twoje rozwiązanie również powinno. Jeśli nie rzuca wyjątków, twój też nie powinien. Jeśli zwróci wartości zerowe, twoje również powinny zwrócić wartości zerowe. I tak dalej. W przeciwnym razie naruszysz 25 000 wierszy kodu.
Ma to na celu zapewnienie zgodności retro.
Dlaczego? Ponieważ w tej chwili jest to Twoja wyjątkowa gwarancja udanego refaktora.
Pilnie potrzebny jest sposób, aby zagwarantować kompatybilność retro. Oto Twoje pierwsze wyzwanie. Wyizoluj komponent do testów jednostkowych.
Należy pamiętać, że te 25 tys. Linii kodu zostało stworzonych przy założeniu możliwych wyników istniejącego kodu. Jeśli nie złamiesz tej części umowy, jesteś w połowie drogi do ostatecznego rozwiązania. Jeśli tak, to dobrze: niech siła będzie z tobą
Po zaprojektowaniu i wdrożeniu nowego „kontraktu” zastąp go starym. Przestarzałe lub wyjmij.
Zasugerowałem pozostawienie błędów w spokoju, ponieważ refaktoryzacja i naprawianie błędów to różne zadania. Jeśli spróbujesz je posunąć naprzód, możesz zawieść na obu. Możesz myśleć, że znalazłeś błędy, mogą to być jednak „funkcje”. Więc zostaw je w spokoju (na minutę).
Wydaje mi się, że 25 000 linii kodu wystarcza do tego, aby skupić się tylko na jednym zadaniu.
Po wykonaniu pierwszego zadania. Ujawnij te błędy / funkcje swojemu szefowi.
Wreszcie, jak powiedział @Stephen:
źródło
Sprawdź to.
Wszyscy inni zalecają sposób refaktoryzacji, aby miał niewielki wpływ. Ale przy tak wielu błędach, nawet jeśli uda Ci się zrefaktoryzować przy użyciu zaledwie 10 linii kodu (prawdopodobnie możesz), to wpłynąłeś na 25 000 przepływów kodu , nawet jeśli nie musiałeś ich przepisywać.
Następną rzeczą do zrobienia jest sprawdzenie, czy zestaw testów regresji przeszedł w żywych kolorach. A jeśli nie masz, zrób taki, który będzie. Dodanie kompleksowego zestawu testów regresji do monolitycznego projektu wydaje się nudne, ale jest dobrym sposobem na zwiększenie zaufania do kandydatów do wydania, a także ich zwolnienie szybciej, jeśli pakiet jest dobrze zautomatyzowany.
źródło