Jak w starej bazie kodów jak szybko dowiedzieć się, co jest używane, a co nie?

21

Poproszono mnie o ocenę czegoś, co wydaje się być znaczną bazą kodu, jako wstęp do zawarcia umowy o utrzymanie tej bazy.

Nie po raz pierwszy byłem w tej sytuacji. W niniejszym przypadku kod jest przeznaczony dla dość głośnej i dość obciążonej strony z grami dla wielu graczy, obsługującej jednocześnie co najmniej kilka tysięcy graczy online. Jak wiele takich witryn, ta jest połączeniem technologii front-end i back-end.

Struktura strony widziana od wewnątrz jest bałaganem. Wszędzie są foldery z rozszerzeniem „_OLD” i „_DELETE”. Wiele folderów wydaje się służyć bez celu lub ma bardzo tajemnicze nazwy. Może znajdować się wiele starych, nieużywanych skryptów, nawet w odpowiednio wyglądających folderach. Nie tylko to, ale niewątpliwie istnieje wiele niedziałających sekcji kodu, nawet w skryptach działających w inny sposób (znacznie mniej paląca obawa).

Jest to przekazanie od dotychczasowych opiekunów, z powrotem do pierwotnych twórców / opiekunów strony. Jak to jest zrozumiałe typowe w tego rodzaju scenariuszach, operator zasiedziały nie chce mieć nic wspólnego z przekazaniem, poza tym, co jest wymagane przez prawo i prawo do przekazania go nowemu wybranemu opiekunowi. Zatem wyodrębnianie informacji o istniejącej strukturze witryny z zasiedziałego operatora jest po prostu wykluczone.

Jedyne podejście, które przychodzi na myśl, aby dostać się do bazy kodu, to zacząć od katalogu głównego witryny i powoli, ale pewnie poruszać się po połączonych skryptach ... i prawdopodobnie są w użyciu setki, a setki innych nie. Biorąc pod uwagę, że znaczna część strony znajduje się we Flashu, jest to nawet mniej proste, ponieważ, szczególnie w starszych aplikacjach Flash, linki do innych skryptów mogą być osadzone w plikach binarnych (.FLA), a nie w plikach tekstowych (.AS / ActionScript).

Zastanawiam się więc, czy ktoś ma lepsze sugestie, jak podejść do oceny bazy kodu jako całości pod kątem łatwości konserwacji. Byłoby wspaniale, gdyby istniał jakiś sposób spojrzenia na wykres częstotliwości dostępu do plików w systemie operacyjnym serwera WWW (do którego mam dostęp), ponieważ może to dać pewien wgląd w to, które pliki są najważniejsze, nawet jeśli nie być w stanie wyeliminować te pliki, które nigdy nie są używane (ponieważ niektóre pliki mogą być używane tylko raz w roku).

Inżynier
źródło
7
Nie wiem wystarczająco dużo o flashu, ale jeśli wystąpią błędy kompilacji, gdy nie ma kodu, możesz zmienić nazwę folderów, aby sprawdzić, czy są do nich odniesienia.
Oded
Złe rozwiązanie: Usuń je i poczekaj na raporty o błędach / błędach. (Tylko upewnij się, że można go odzyskać!)
Izkata
1
@Nick Czy możesz wyjaśnić, czy otrzymujesz wynagrodzenie za wycenę w ramach kolejnego etapu umowy, który nadal musisz licytować / uzyskać w inny sposób? Twoja odpowiedź nie zmieni pytania „czy istnieje narzędzie”, ale niektórzy z nas mogliby opracować odpowiedzi dotyczące: procesu, który byłby lepiej dopasowany do twojej sytuacji (np. Powstrzymanie cię przed popsuciem itp.).
jcmeloni
@ jcmeloni Nie, nie otrzymuję zapłaty za ocenę. Ale z mojego doświadczenia wynika , że z małych rzeczy, które kupiłem w ciągu ostatnich kilku dni, nie ma teraz nikogo przy stole. Mój zestaw umiejętności jest dość niezwykły, więc jestem jeszcze bardziej spokojny, że na podstawie cytatu nie ma nikogo, kto by o niego walczył. Rzeczywista wycena, o której mowa, pochodzi od mojego przyszłego klienta do jego klienta, który planuje ponownie udzielić im zamówienia. Naprawdę z mojej strony, mam im pomóc w zapewnieniu wspomnianego cytatu. HTH.
Inżynier
@Oded Rename jest zdecydowanie łatwiejsze niż usuwanie prób i błędów! Dobre myślenie tam. To jeszcze jedno narzędzie w pudełku.
Inżynier

Odpowiedzi:

32

Ponieważ jesteś proszony o podanie danych wejściowych, aby Twój klient napisał odpowiednią propozycję dla drugiego klienta (właściciela koszmaru) dla jakiejkolwiek pracy nad tym kodem, zamierzam wyjść kończynę i powiedz, że w tym momencie nie będziesz przeprowadzać dokładnych testów, refaktoryzacji ani nic podobnego. Prawdopodobnie masz bardzo krótki czas, aby uzyskać przybliżoną ocenę. Moja odpowiedź opiera się na moim doświadczeniu w tej samej sytuacji, więc jeśli moja interpretacja jest nieprawidłowa, po prostu zignoruj ​​wszystko, co następuje.

  • Użyj narzędzia pająka, aby zorientować się, które strony są dostępne i jakie są przychodzące. Nawet podstawowe narzędzie do sprawdzania linków - a nie konkretne narzędzie „pająka do celów kontrolnych” - będzie przydatne w tym względzie.
  • Wykonaj podstawowy arkusz kalkulacyjny audytu / zapasów. Może to być tak proste, jak lista plików i ich czas ostatniej modyfikacji, uporządkowane według katalogu. Pomoże ci to poczuć zakres, a kiedy dojdziesz do katalogów takich jak _OLD i _DELETE, możesz zauważyć, że a) twoja ocena opiera się na rzeczach nie znajdujących się w tych katalogach b) obecność tych katalogów i potencjał cruft / hidden koszmary świadczy o głębszych problemach, które należy w jakiś sposób uwzględnić w ofercie klienta . Nie musisz spędzać miliarda lat na wyliczaniu możliwych problemów w _OLD lub _DELETE; informacje zostaną dodane do ostatecznej oferty.
  • Biorąc pod uwagę, że przeglądasz coś, co brzmi jak aplikacja całkowicie internetowa, nawet standardowe narzędzia do analizowania dzienników będą Twoim przyjacielem. Będziesz mógł dodać do arkusza kalkulacyjnego trochę „to jest w pierwszej 10 dostępnych skryptów” lub coś takiego. Nawet jeśli skrypty są osadzone w plikach Flash, a zatem nie są pająkowate, istnieje duże prawdopodobieństwo, że są dostępne za pośrednictwem POST lub GET i będą widoczne w logach serwera. Jeśli wiesz, że masz 10 skryptów o wysokim dostępie, a nie 100 (lub odwrotnie), da ci to dobre wyobrażenie o tym, jak przebiegną prace konserwacyjne.

Nawet w skomplikowanej witrynie to, co opisałem powyżej, jest czymś, co można zrobić w ciągu dnia lub półtora dnia. Ponieważ odpowiedź masz zamiar dać swoim klientem jest coś takiego jak „to będzie to ogromny ból w tyłek, a oto kilka powodów, dla których to po prostu być wprowadzenie szminkę na świni, więc należy odpowiednio bid ”lub„ każda rozsądna osoba starałaby się nie utrzymywać, ale zacząć od nowa, więc powinieneś licytować odpowiednio ”lub nawet„ to nie jest takie złe, ale będzie to ciągły strumień pracy w dowolnym okresie, więc licytuj odpowiednio ” , chodzi o to, że będą licytować, a zatem nie musisz być tak precyzyjny, jak gdybyś był zatrudniony bezpośrednio w celu przeprowadzenia pełnego audytu treści i architektury.

jcmeloni
źródło
2
+1 To fantastyczna odpowiedź. Gdzie dotarł ten przycisk +5 ...
Inżynier
1
TL; DR: nie wysyłaj się do króliczej nory, dopóki nie będziesz musiał. :)
jcmeloni
4

Zdecydowanie polecam przeformułowanie istniejącego kodu źródłowego (w przeciwieństwie do przepisywania) przy użyciu wzorców zawartych w książce „ Efektywna praca ze starszym kodem ”.

Książka szczegółowo opisuje kilka mechanizmów efektywnego pokrycia starszego kodu w testach jednostkowych, abyś mógł zacząć bezpiecznie refaktoryzować kod. Książka jest podzielona na części, jedna opisuje filozofię stojącą za tym podejściem, a następnie kilka rozdziałów, które rozwiązują określone problemy, takie jak „Zmiana trwa wieczność”, „Nie mam dużo czasu i muszę ją zmienić” oraz „Nie mogę dostać tej klasy do uprzęży testowej”. Każdy z tych rozdziałów zawiera szczegółowe, sprawdzone techniki, które pomagają nauczyć się, jak stosować najlepsze praktyki testowania w rzeczywistych problemach.

Czytanie książki sprawiło, że poczułem, że „nie jesteśmy sami”… wielu z nas, a może wszyscy, pracujemy ze złożonymi bazami kodu, które stały się trudne do zarządzania. Techniki wymienione w książce dały mi wiele nadziei i osobiście byłem w stanie zastosować je niemal natychmiast.

Wpis na blogu Joela Spolsky'ego świetnie wyjaśnia, dlaczego najlepiej zachować istniejącą, działającą bazę kodu, a nie zaczynać od zera. Wybrałem cytat z artykułu, który go podsumowuje, ale jest to fantastyczna lektura.

„Istnieje subtelny powód, dla którego programiści zawsze chcą wyrzucić kod i zacząć od nowa. Powodem jest to, że myślą, że stary kod to bałagan. A oto ciekawa obserwacja: prawdopodobnie się mylą. Powód, dla którego uważają, że stary kod to bałagan z powodu kardynalnego, podstawowego prawa programowania:

Trudniej jest odczytać kod niż go napisać. ”- http://www.joelonsoftware.com/articles/fog0000000069.html

Kyle Hodgson
źródło
4
+1. W odpowiedzi na komentarz Joela: „Cholernie dobrze nie powinno być”. Ponieważ nie widzę problemu jako nieodłącznego. Widzę to częściowo dlatego, że wiele osób pisze tandetny kod i nie obchodzi go to, podczas gdy wielu innych pisze dość dobry kod, ale żyje zgodnie z koncepcją „kodu samodokumentującego” ... co jest po prostu BS: Ktoś może pochlebiać własny styl kodowania, wszystko, czego się chce w prywatności, ale jeśli chodzi o publiczne bazy kodu, po prostu pojawiają się komentarze, jakby nie było jutra. Nie boli I wreszcie są ludzie, którzy muszą sprawić, by wszystko działało w starszych kodeksach, przy ograniczonym budżecie czasu.
Inżynier
2

W typowej bazie kodu Java rozważę użycie narzędzi takich jak PMD, FindBugs lub Sonar, a następnie spróbuję zrozumieć raportowanie narzędzi (martwy kod, nieudokumentowany kod, powielony kod itp.)

Na podstawie raportów postaram się znaleźć różne warstwy aplikacji / witryny (warstwa biznesowa, DB, SQL itp.)

Jeśli warstwy są połączone (html w serwletie, sql w kodzie java) Zacznę od odsprzęgnięcia każdego z tych kroków należy uznać za odizolowane i możesz zatwierdzić na końcu każdego z nich (uruchamiając gałąź, a następnie scalić) .

Abderrazak BOUADMA
źródło
1
Dzięki. Chociaż twoja odpowiedź jest nieco specyficzna dla Javy, ciekawe jest twoje warstwowe podejście ... obieranie cebuli, że tak powiem. Coś do przemyślenia.
Inżynier
1

Z twojego opisu wydaje się, że ten kod osiągnął stan niemożliwy do utrzymania, co oznacza, że ​​najlepszym podejściem jest prawdopodobnie całkowite przepisanie. Deweloperzy mieliby znacznie mniejsze wypłaty, gdyby istniały narzędzia wysokiej jakości, które działałyby w celu utrzymania nieuporządkowanej bazy kodu. Możliwe jest przejrzenie i usunięcie starego niepotrzebnego kodu z folderów, ale jest to ręczne zadanie i prawdopodobnie nie dostaniesz wszystkiego bez nieuzasadnionej ilości czasu. Zgaduję tutaj, ale założę się, że sam działający kod jest tak samo bałaganem, jak struktura plików, co oznacza, że ​​nawet jeśli uda się przyciąć bazę kodu do aktywnie działającego kodu, nadal będzie to koszmar zaktualizować lub naprawić cokolwiek.

Chciałbym podkreślić, że wysiłek wymagany do utrzymania istniejącego kodu w stanie umożliwiającym utrzymanie byłby równy lub większy niż wysiłek, aby zacząć od nowa od przepisania. częścią utrzymywania czegokolwiek jest wiedza, kiedy „wziąć to za szopę i zastrzelić”.

Ryathal
źródło
Zwykle byłbym w 100% z tobą przy podejściu polegającym na rzucaniu i przepisywaniu. Ale w tym przypadku (a przynajmniej na razie) mam płacić tylko za pracę nad utrzymaniem strony, a nie za bardziej rozbudowany przegląd, który potrwa kilka tygodni. Ponadto, nawet gdybym chciał to teraz zrobić, nie mogłem nadążyć za robieniem tego i utrzymywaniem innych umów, które mam w ruchu, ponieważ moja tygodniowa dostępność jest wyraźnie ograniczona - moja podstawowa umowa musi być spełniona 40 godzin tygodniowo minimum.
Inżynier
1
Nie zgadzaj się z podrzucaniem i przepisuj! From joelonsoftware.com/articles/fog0000000069.html ... „Istnieje subtelny powód, dla którego programiści zawsze chcą wyrzucić kod i zacząć od nowa. Powodem jest to, że uważają, że stary kod to bałagan. A oto ciekawa obserwacja : prawdopodobnie są w błędzie. Powodem, dla którego uważają, że stary kod jest bałaganem, jest kardynalne podstawowe prawo programowania: Trudniej jest odczytać kod niż napisać ”. Zamiast tego zdecydowanie polecam refaktoryzację: amazon.ca/Working-Effectively-Legacy-Michael-Feathers/dp/…
Kyle Hodgson
1
@KyleHodgson czasami kod jest naprawdę bałaganem, a gdy jesteś w punkcie, w którym znalezienie kodu przed odczytaniem jest bałaganem, czas zacząć od nowa.
Ryathal
Tak, nie sądzę, żeby było to tak jednoznaczne, chociaż ta książka wydaje się warta przeczytania. Zależy to bardzo od wielkości / złożoności bazy kodu i ciepłych ciał dostępnych do wykonania pracy.
Inżynier
1

Robot indeksujący może pomóc Ci ustalić, które adresy URL są dostępne. Zwłaszcza jeśli jest wystarczająco inteligentny, aby wyodrębnić linki z Flasha lub JavaScript. Po utworzeniu listy stron internetowych przejrzyj je i wyświetl listę plików, do których się odnoszą. Wszystko, co pozostało po tym procesie, należy uznać za martwy kod.

Mike Baranczak
źródło
1
Zdecydowanie nie zgadzam się z twoim ostatnim zdaniem. Robot indeksujący może dowiedzieć się tylko, które strony są połączone ze sobą w postaci ukierunkowanego wykresu z jednym lub wieloma punktami początkowymi. Ale kiedy mówimy o witrynie internetowej, istnieją również tak zwane „strony docelowe”, które prowadzą do innych stron, ale nie ma linków do nich wskazujących. Ponadto mogą istnieć stare części interfejsu administracyjnego, które są również odłączone od innych stron. Obecnie mam projekt tego typu.
scriptin
0

Uwaga: Zwracam uwagę na wykorzystanie bazy danych, podczas gdy ty pytasz o wykorzystanie samego kodu. Odpowiedź nadal dotyczy obu przypadków w każdym punkcie, o którym wspomniałem.

Po części odpowiedziałeś już na własne pytanie w ostatnim akapicie: sprawdź, do czego można uzyskać dostęp podczas działania aplikacji.

  1. Możesz profilować bazę danych i poprosić profilera o rejestrowanie wszystkich zapytań na jeden dzień. Daje przegląd najczęściej używanych obiektów bazy danych, ale nie powie, które z nich nigdy nie są używane. Ponadto musisz nadal uważać na wyniki: na przykład tabela może być używana wyłącznie za pomocą procedur przechowywanych, ale gdy spojrzysz na zapytania z profilera, wyglądałoby to tak, jakby tabela w ogóle nie była używana.

  2. Przeglądanie kodu źródłowego, wyszukiwanie zapytań jest bardziej pomocne, a po zebraniu wszystkich zapytań możesz dobrze zrozumieć wykorzystanie bazy danych, nie pod względem częstotliwości (w tym przypadku przydatny jest profiler), ale pod względem używanego / nie używane tabele. Niestety, w przypadku źle napisanej / nieobsługiwanej przez lata bazy kodu może być ona wyjątkowo trudna i podatna na błędy , szczególnie jeśli zapytania są konstruowane dynamicznie (wyobraź sobie metodę, która w selectparametrze a używa parametru jako nazwy tabeli; jak możesz być może wiesz, jakie są możliwe wartości parametru, po prostu patrząc na kod źródłowy?).

  3. Analiza statyczna i niektóre kompilatory mogą również ujawniać martwy kod, ale nadal nie dają odpowiedzi, której potrzebujesz.

  4. Analiza samych danych lub metadanych bazy danych może ujawnić kilka interesujących informacji. Na przykład, łatwo byłoby twierdzić, że tabela LogonAudit(uniqueidentifier LogonAuditId, datetime LogonEvent, ...)nie jest używany dłużej, jeśli zawiera 10 000 rekordów dziennie na lata 2006 do 2009, a nie zapisy od września, 18 th , 2009. W tym samym nie jest prawdą dla A tabela zawierająca dane, które mają być w większości przeznaczone tylko do odczytu.

Te cztery punkty razem dają listę używanych tabel. Pozostałe są albo używane, albo nie. Możesz robić twierdzenia i je testować, ale bez dobrego pokrycia testami jednostkowymi nie byłoby to łatwe. Każdy „łatwy” sposób również zawiódłby. Na przykład, jeśli masz products_delme_not_usedtabelę, możesz stwierdzić, że w ogóle nie jest ona używana, i sprawdzić, czy w kodzie znajduje się „products_delme_not_used”. Jest to optymistyczne: nie jest niczym niezwykłym znalezienie takiego kandydata DailyWTF w starej bazie kodu:

// Warning: WTF code below. Read with caution, never reuse it, and don't trust
// the comments.

private IEnumerable<Product> GetProducts()
{
    // Get all the products.
    return this.GetEntities<Product>("PRODUCT");
}

private IEnumerable<T> GetEntities<T>(string tableName)
{
    // Everyone knows that SQL is case sensitive.
    tableName = tableName.ToLower();

    if (tableName == "user" || tableName == "product")
    {
        // Those tables were renamed recently in the database. Don't have time
        // to refactor the code to change the names everywhere.
        // TODO: refactor the code and remove this `if` block.
        tableName += "s";
    }

    if (this.IsDelme(tableName))
    {
        // We have some tables which are marked for deletion but are still
        // used, so we adjust their name.
        tableName = this.Delme(tableName);
    }

    return this.DoSelectQuery<T>("select top 200 * from " + tableName);
}

private bool IsDelme(string name)
{
    // Find if the table is among candidates for removal.
    List<string> names = this.Query<string>("select Names from DelmeTables");
    return names.Contains(name);
}

private string Delme(string name)
{
    // Return the new name for a table renamed for deletion.
    return string.Join("_", new [] { name, "delme", "not", "used" });
}

Czy możesz dowiedzieć się, że ten kod faktycznie używa products_delme_not_usedtabeli?

Gdybym był na twoim miejscu to bym:

  1. Trzymaj wszystkie obiekty bazy danych na miejscu,
  2. Refaktoryzuj całą aplikację (jeśli jest tego warta),
  3. Dokumentuj (podczas refaktoryzacji) aplikację, a konkretnie użycie bazy danych.

Po zakończeniu dwóch ostatnich kroków prawdopodobnie lepiej zrozumiesz użycie bazy danych, co pomoże wymyślić nazwy tabel, które nie są już używane, i może mniej lub bardziej bezpiecznie je usunąć.

Arseni Mourzenko
źródło
0

Wydaje mi się, że musisz uzyskać wystarczającą ilość informacji, aby stworzyć ofertę, więc skoncentruję się na tym wysiłku.

Spróbuję ustalić, ile przypadków użycia dotyczy tej witryny. Zwykle daje to wyobrażenie o tym, jak duża i skomplikowana jest strona oraz ile czasu zajmie jej ponowne utworzenie lub utrzymanie.

Tak, to prawda, że ​​czasami kod nie jest już używany i sprawi, że aplikacja będzie wyglądać na nieco większą niż w rzeczywistości, ale nie sądzę, że wpłynie to na liczby o więcej niż 20% , więc nie martwiłbym się tą częścią.

Patrząc na kod źródłowy, strony internetowe i tabele bazy danych powinny pomóc Ci to odkryć.

Możesz także rozważyć ograniczenie liczby godzin miesięcznie, które poświęcisz na ten projekt, na z góry ustaloną opłatę, aby się zabezpieczyć.

Jeśli chodzi o odkrycie, co jest używane, a co nie jest używane, tak naprawdę nie ma łatwego sposobu. Narzędzia do analizy kodu mogą pomóc, ale ponieważ masz do czynienia z tak mieszanym złem, nie sądzę, aby istniało jakiekolwiek narzędzie, które mogłoby pomóc. Dla każdego konkretnego obszaru prawdopodobnie znajdziesz narzędzie do analizy kodu, które może pomóc.

Sarel Botha
źródło