Kiedy mam do czynienia z projektem, który ma wiele różnych plików, zawsze wydaje mi się, że nie rozumiem, w jaki sposób części współdziałają ze sobą. Nigdy tak naprawdę nie miałem większego problemu ze zrozumieniem mniejszych komponentów w izolacji, ale wraz ze wzrostem złożoności projektu, nie jestem w stanie mentalnie zrozumieć, co się dzieje. Zauważam to szczególnie w przypadku projektów OOP, ponieważ rośnie liczba metod i plików źródłowych.
Moje pochodzenie: Jestem samoukiem, programistą internetowym. Zajmowałem się głównie pythonem do szybkich i brudnych skryptów, ale wykonałem też kilka podstawowych projektów django . Lubię frameworki takie jak flask , ponieważ w prostocie układu jednego pliku mogę łatwo śledzić (głównie) to, co się dzieje.
Znajduję się teraz w sytuacji, w której muszę wchodzić w interakcje z dużym projektem PHP Zend Framework, który opracował ktoś inny, i jestem przytłoczony próbą zrozumienia kodu rozłożonego na wiele plików.
Jakie techniki i procesy okazały się przydatne do zrozumienia dużej bazy kodu opracowanej przez kogoś innego? Czy jest jakiś konkretny schemat, który pomaga zrozumieć większy obraz?
Odpowiedzi:
Sztuczka w zrozumieniu dużej bazy kodu polega na tym, aby nie próbować zrozumieć wszystkiego. Po pewnym rozmiarze nie możesz utrzymać modelu mentalnego w głowie całej rzeczy. Zaczynasz od punktu kontrolnego, który ma sens dla każdego zadania, nad którym najpierw musisz popracować, a następnie rozgałęziasz się od niego, ucząc się tylko potrzebnych części i ufając, że reszta działa zgodnie z reklamą. To tak jak zrozumienie rekurencji. Jeśli spróbujesz utrzymać cały stos w głowie, twój mózg eksploduje.
Grep, debuggery i intellisense są tutaj twoimi przyjaciółmi. Jeśli nie wiesz, jak wywoływana jest funkcja, ustaw na niej punkt przerwania i zejdź ścieżką stosu.
Inną rzeczą wartą uwagi jest to, że duże bazy kodu nie wyskakują znikąd. Im większy, tym więcej programistów ma doświadczenie w tym, więc zapytaj ich, od czego zacząć, ale bądź konkretny. Zadaj pytania typu: „Muszę dodać nowego dostawcę płatności. Gdzie powinienem szukać kodu?” Skoncentruj się tylko na tym zadaniu, zamiast próbować zrozumieć całą bazę kodu, a kawałek po kawałku Twoja znajomość wzrośnie.
źródło
Nie ma skrótu. Musisz przez to cierpieć.
Aby odpowiedzieć na pytanie dotyczące uzyskiwania diagramów, doxygen jest tym, czego chcesz. AFAIK działa z PHP.
Mówiąc bardziej ogólnie, spotykam się z mniej więcej następującymi etapami, gdy napotykam nową bazę kodów:
Zrozum, co robi z punktu widzenia użytkownika. Możliwość samodzielnego korzystania z aplikacji jak zaawansowany użytkownik. Dowiedz się, jak pracują z nim prawdziwi użytkownicy końcowi. Może to wymagać siedzenia z nimi, dopóki nie zrozumiesz dokładnie, co robią.
Jeśli to możliwe, komunikuj się z oryginalnymi programistami. Na początku będziesz mieć pytania architektoniczne stymulowane doświadczeniem użytkownika końcowego. Później będziesz mieć pytania dotyczące implementacji dotyczące przypadków skrajnych i szczegółów. Możliwość uzyskania odpowiedzi od programistów pomoże znacznie bardziej niż jakiekolwiek komentarze lub dokumentacja (która w najlepszym razie jest niekompletna i często myląca lub całkowicie nieobecna).
Dowiedz się o dowolnym używanym frameworku. Przynajmniej powinieneś być w stanie stworzyć „hello world” lub inną prostą aplikację z tym frameworkiem przed zanurzeniem się w aplikacji produkcyjnej.
Zapoznaj się z całym procesem wdrażania (najlepiej zrobić, gdy oryginalni programiści trzymają cię za rękę). Jeśli nie możesz pobrać bieżącej bazy kodu, zbudować go i wdrożyć za pomocą środowiska testowego / sprawdzania poprawności / prod, toast. Nawet najmniejsza zmiana będzie wymagała przeskoczenia przez wszystkie obręcze rozmieszczenia, więc dlaczego nie zabrać tej części od razu? W ten sposób zapoznasz się ze wszystkimi uroczymi serwerami, bazami danych, usługami i skryptami używanymi przez aplikację - będziesz wiedział, „gdzie to mieszka”.
Sprawdź testy funkcjonalne (jeśli istnieją). Skąd wiesz, czy to działa poprawnie? Co ludzie robią, aby dbać o aplikację i karmić ją?
Zrozum dzienniki aplikacji. Chociaż nigdy nie pracowałem z PHP, zgadnę i powiem, że każda poważna aplikacja PHP będzie miała jakiś rodzaj logowania. Jeśli zrozumiesz dzienniki, będziesz mieć dobry punkt wyjścia, gdy nadejdzie czas debugowania problemów.
---- Zauważ, że do tej pory nie wspominałem nawet o uważnym przyjrzeniu się bazie kodu. Jest DUŻO, którego możesz dowiedzieć się o dużym projekcie, nawet nie patrząc na kod. W pewnym momencie oczywiście musisz zaznajomić się z kodem. Oto, co pomaga mi:
Do diagramów, doxygen jest doskonałym narzędziem, które wygeneruje dla ciebie wykresy połączeń i inne relacje. Zdarza się, że ma możliwości PHP! Jeśli nie próbowałeś doxygen, absolutnie musisz spróbować. Chociaż nie mogę zagwarantować, jak zrozumiały będzie kod wewnątrz frameworka, ale może to pomóc. Oryginalni programiści są często zszokowani tym, co widzą, gdy są prezentowane w dokumentach generowanych doxygen. Dobrą wiadomością jest to, że naprawdę pomaga pobudzić ich pamięć i pomóc ci lepiej.
Jeśli masz zestaw testów jednostkowych, ich dokładne przyjrzenie się powinno zapewnić okno do wewnętrznych funkcji aplikacji. Będzie to również pierwsze miejsce, w którym można znaleźć błędy, które mógłbyś wprowadzić podczas wprowadzania zmian.
Zakładki IDE są nieocenione do oznaczania hot-spotów w bazie kodu. Możliwość szybkiego ich przełączania sprzyja zrozumieniu.
Czytanie ostatnich raportów o błędach i ich rozdzielczości są również cenne dla zrozumienia gorących punktów i pomogą ci nabierać prędkości w najbardziej odpowiednich częściach bazy kodu.
źródło
Zgodnie z prośbą, oto mój komentarz jako odpowiedź.
Pracując z kodem innych osób, mam tendencję do tworzenia lub, jeśli to możliwe, generowania diagramów klas UML, aby dać mi przegląd struktury statycznej. Schemat wizualny pomaga mi szczególnie, gdy muszę wrócić później i już zapomniałem o kontekście klasy. Czasami robię to również dla zachowania dynamicznego, aby wyrównać interakcje między współpracownikami, ale nie robię tego często.
Jeśli baza kodów zawiera testy (integracyjne lub jednostkowe), czasem warto je również sprawdzić.
źródło
Zacznę to robić w ciągu tego tygodnia, gdy nowy klient potrzebuje ulepszeń dla produktu pozostawionego przez innego programistę. Poniżej znajdują się kroki, które należy wykonać:
a) Zidentyfikuj używaną platformę programistyczną, która pomaga poznać przepływ aplikacji.
b) Zidentyfikuj wspólne usługi - rejestrowanie, obsługę wyjątków, MVC, połączenie z bazą danych, audyt, przeglądanie (generowanie strony), ponieważ są to części, z których będziemy najczęściej korzystać.
c) Przeprowadź wspólne przepływy użytkowników (w aplikacji), a następnie spróbuj dopasować je do układu kodu
d) Postaraj się wprowadzić pewne zmiany i zobacz, jak się pojawią. To największy krok, ponieważ dopóki nie zaczniesz wprowadzać zmian, kod nadal jest czarną skrzynką ...
Dam ci znać, jakie inne pomysły mam w ciągu najbliższych dwóch tygodni
źródło
Myślę, że powinieneś przeczytać dokumentację. Wiem, że hakerzy uwielbiają mówić „kod to dokumentacja” i używają tego jako wymówki, aby nie pisać żadnej dokumentacji, ale są w błędzie. Spójrz na jądro Linuksa, olbrzymi projekt programowy składający się z wielu milionów linii kodu: nie sądzę, aby ktokolwiek mógł naprawdę wejść na świeżo bez przeczytania książki i po prostu jej odebrania. Jeśli kod, z którym pracujesz, nie jest udokumentowany (lub dobrze skomentowany, jeśli mniejszy projekt), prawdopodobnie nie jest to dobry kod.
źródło
Jeśli pracujesz z czymś naprawdę dużym przy zerowej dokumentacji (ja też tam byłem, jest szorstki!), To, co znalazłem, pomaga znaleźć próbę wyizolowania części, nad którą pracujesz. W tej części kodu dowiedz się, w jaki sposób dane / zdarzenia / wiadomości / interakcje przechodzą i wychodzą z tej jednostki. Innymi słowy, dokonaj inżynierii wstecznej interfejsu. Zapisz to. Następnym razem, gdy będziesz pracować na innej jednostce (premia, jeśli mówi ona do tej, nad którą pracowałeś wcześniej), zrób to samo. Zachowaj całą swoją dokumentację. Po kilku miesiącach będziesz miał ładny obraz tego, jak rzecz płynie.
Wymyśl interfejs jednego małego urządzenia, nad którym pracujesz, i zapisz go do późniejszego wykorzystania. Z czasem zszyjesz większość tego, jak to działa. Znajdź, co robi Twój program, i prześledź przepływ tej wiadomości. Na przykład, jeśli twój system odbiera wejściowy komunikat sieciowy i wysyła komunikat wyjściowy, prześledź, jak ten komunikat przepływa przez system, nie martwiąc się o wszystkie szczegóły - po prostu zobacz, dokąd idzie.
źródło
To, co robię, to stworzenie jednego modelu UML ze wszystkich plików, które zostały odwrócone z Java do UML. Podejście to oznacza, że model nie jest już tylko abstrakcyjnym widokiem projektu, ale sam projekt jest całkowicie odwzorowany na MOF, a zatem na UML.
To, co otrzymuję, to duży pojedynczy model złożony z wielu podmodeli, z których każdy składa się z pakietów składających się z klasyfikatorów itp. Praca na poziomie wielu projektów pozwala mi również śledzić wszystkie klasyfikatory i wywołania metod na poziomach wielu projektów. Mam na myśli, że ta sama metoda może wywoływać jeden klasyfikator w projekcie A i inny klasyfikator w projekcie B. Jedynym sposobem, aby zobaczyć pełną strukturę projektu, jest odwrócenie obu z nich jednocześnie. Nie mam czasu na tworzenie diagramów komponentów, a informacje nie są naprawdę dokładne. Wolę poprosić komputer o odwrócenie pełnego projektu. Robię odwrotność przy każdej iteracji z zespołem, a wszystkie moje diagramy są natychmiast aktualizowane. Inżynieria odwrotna jest inkrementalna i wykorzystuje mapowanie identyfikatorów Java na UML. Chodzi mi o to, że każdy element Java jest mapowany do pojedynczego i unikalnego elementu MOF, który pozostaje taki sam przez cały okres życia projektu, nawet jeśli zostanie ponownie przetworzony. Takie postępowanie nie ogranicza już modelowania UML i pozwala na modelowanie bardzo dużych i złożonych projektów. Dla twojej informacji pracuję z projektem mającym ponad 5 000 000 linii kodu OOP. Wszystkie moje projekty są poprawnie odwrócone i możliwa jest graficzna nawigacja
Używam tylko diagramów klas, ponieważ z mojego modelu UML mogę utworzyć tyle widoków, ile potrzeba, które są zawsze aktualne. Potrafię również modelować bardzo złożone projekty.
źródło