Jak naprawić projekt w zasadzie bez struktury?


25

Pracuję nad projektem oprogramowania głównie solo od ponad 5 lat. Na początku był bałagan (jestem trzecim lub czwartym programistą, który nad nim pracował) i chociaż teraz jest mniej bałaganu, jest nadal niesamowicie zdezorganizowany. Tempo postępu w opanowywaniu go jest lodowate i zaczynam odczuwać przygnębienie z powodu stanu, w którym się znajduje. Jak naprawdę mogę to naprawić?

Specyfika projektu: Jest to program sprzedaży napisany prawie całkowicie w języku Visual Basic Classic (VB6) z zapleczem MySQL i silnikiem raportowania napisanym w języku C #. Moduł raportowania C # jest przyjemnością w pracy, został napisany dopiero w ciągu ostatnich kilku lat, a wcześniej wszystkie raporty zostały wykonane w Crystal Reports 9 (tak, wciąż mamy kilka raportów, które na nim polegają).

Jednak sam program jest kompletną katastrofą. Nie ma w sumie 90 000 LOC i około 10 000 linii komentarzy (głównie nie dokumentacji, ale stary kod, który został skomentowany). 158 plików formularzy i 80 plików modułów. Nie mam pojęcia, ile z nich jest faktycznie używanych, ponieważ niektóre funkcje programu są po prostu przestarzałe i (hm, czasami) zanotowane jako takie bez usuwania powiązanego kodu z programu. Domyślam się, że tylko 50% kodu jest faktycznie wykorzystywane produktywnie.

Boję się dotknąć dużej części kodu tylko dlatego, że nie jestem pewien, czy niszczę coś, na czym opiera się jeden niejasny klient, zdarza się to częściej niż mogę to zliczyć. To tak, jakby w całym kodzie rozrzucone były miny lądowe.

Projekt nie ma tak naprawdę żadnej struktury. Nie jest zorientowany obiektowo, z wyjątkiem kilku miejsc, w których do tej pory miałem cierpliwość do reform. Jeśli potrzebujesz uzyskać dane w formularzu, tworzysz instancję obiektu bazy danych, deklarujesz zapytanie bezpośrednio w funkcji, wykonujesz go i robisz, co chcesz z zestawem danych.

Kiedy zacząłem pracować nad projektem, nie było żadnej kontroli źródła. Próbowałem zachęcić inne osoby, nad którymi pracowałem, do korzystania z niego, ale byłem nowym facetem i moje próby nakłonienia ludzi do korzystania z subwersji prawie nie powiodły się. Główny programista firmy w końcu złapał błąd rtęci w ciągu ostatnich kilku lat i upewnił się, że wszyscy programiści używają teraz kontroli źródła we wszystkich projektach, więc to przynajmniej pewien postęp.

Myślę, że gdybym mógł pracować nad reformą projektu w pełnym wymiarze godzin, byłbym w stanie osiągnąć przyzwoity postęp, a może nawet oszacować, ile czasu zajmie mi pełne przekształcenie projektu, ale jest on w użyciu i jestem ciągle proszony o gaszenie pożarów, naprawianie błędów, dodawanie funkcji itp. itp.

Jak więc zacząć naprawdę naprawiać ten projekt? Spróbuj użyć VB6 w innym języku? Czy próbuję przepisać program w wolnym czasie? Czy to jest całkowicie beznadziejne?

Aktualizacja

Po tym poście wróciłem do projektu z nową gorliwością, ale wróciłem do beznadziejności w ciągu kilku miesięcy po tak powolnym tempie postępu. Następnie powtórzyłem ten cykl jeszcze 2 lub 3 razy w ciągu następnego roku.

Od tego czasu przeszedłem do innej pracy. Chociaż po tylu latach vb6 i tylko peryferyjnym doświadczeniu z innymi technologiami wyszukiwanie było trudne i po drodze spotkałem się z wieloma odrzuceniami (około kilkunastu wywiadów w ciągu roku). Moja rada dla innych w tej sytuacji polega na rozważeniu pozostawienia tego czynnika w spokoju. Zastanów się, jakie szkody możesz wyrządzić swojej karierze, pozostając w ślepej uliczce, takiej jak ta.


4
Brzmi nieźle. Na początek należy zapisać kopię bieżącego kodu i usunąć stary kod, który został zakomentowany (to tylko szum). Kiedy pracowałem nad starszym systemem, zwykle umieszczałem datę na górze kodu, którą komentowałem. Następnie wypisz komentarz, który miał 6 miesięcy lub więcej.
programista

4
Zacznę od Jamisona i zejdę z półki. . .
Wyatt Barnett,

1
Czy kiedykolwiek próbowałeś przejąć projekt C # napisany przez programistę VB?
שינתיא אבישגנת

Odpowiedzi:


28

Teraz, gdy jest pod kontrolą źródła, możesz pozbyć się skomentowanego kodu.

Zacząłem tutaj w podobnej sytuacji (aplikacja 80KLOC VB6 bez kontroli źródła, bez prawdziwej struktury, prawie wszystko zrobione w programach obsługi zdarzeń).

W ciągu około 2 lat z przerwami przekonałem się o ponad połowę konwersji na C # (zwykle, gdy wymagane są znaczące nowe funkcje). Cały nowy kod C # ma zasięg testu jednostkowego. Jednak zdecydowanie zajmuje dużo więcej czasu na konwersję do C #. Jeśli nie dodajesz nowych znaczących modułów, nie poszedłbym tą drogą.

Jedną z rzeczy, które zrobiłem, było stworzenie podstawowej warstwy dostępu do danych, która generowała się automatycznie z bazy danych. To przynajmniej wychwyciło problemy, gdy zmieniła się nazwa kolumny tabeli i nie znalazłem wszystkich miejsc w kodzie. Powoli przeniosłem logikę biznesową do modułów poza moduły obsługi zdarzeń formularza.

Miałem jednak tę zaletę, że aplikacja była tylko wewnętrzna. Ponieważ miałem tylko jedną witrynę do wdrożenia, mogłem podjąć większe ryzyko niż ty. Jeśli popełniłem błąd, to zazwyczaj nie było problemu. Wygląda na to, że nie masz tego luksusu.

Naprawdę uważam, że najlepszym rozwiązaniem jest przyjęcie następującego podejścia:

  1. Dowiedz się wszystkiego z niesamowitymi szczegółami. To sprawia, że ​​jest mniej prawdopodobne, że coś przypadkowo złamiesz.
  2. Refaktoryzuj bezlitośnie, aby poprawić separację i strukturę, ale nie próbuj wprowadzać nowej metodologii, takiej jak programowanie zorientowane obiektowo, ponieważ VB6 jest po prostu do bani.
  3. Traktuj to jako doświadczenie edukacyjne. Skąd wiesz, że inny sposób jest lepszy, jeśli nigdy nie widziałeś gorszego sposobu?
  4. Nie przejmuj się przepisywaniem w nowym języku / frameworku / platformie, chyba że masz duży moduł do napisania. Nawet wtedy zastanów się dokładnie.

Pamiętaj, że celem tego programu jest bycie produktem, który zarabia na Twojej firmie. Nie musi to być bezbłędne dzieło sztuki (a ja jestem perfekcjonistą, więc naprawdę trudno mi to przyznać). Czasami lepiej jest przyjąć pragmatyzm.

Istnieje prawdopodobnie wielu programistów COBOL, którzy utrzymują ogromne ilości starszego kodu. Wątpię, żeby wszyscy szaleńczo pracowali nad przepisaniem go w jakimś nowym języku. :)


3
+1 Świetna odpowiedź: Wszystko, co mogę dodać, to upewnić się, że nie stawiasz przed sobą zbyt wielkich oczekiwań. Utrzymanie kodu jest powolne w porównaniu z nowym rozwojem, starszym kodem, nawet wolniejszym i nieudokumentowanym, nieustrukturyzowanym kodem, jak opisałeś ... W ciągu ostatnich 5 lat pracowałem nad różnymi bazami kodu z lat 80. i działaniami w milionach SLOC ... Znam twój ból ...
Mattnz

+1, ale jedna funkcja OO VB6 działa OK na to Interfejsy. Jeśli kilka razy widzisz podobne zakodowane kopiowane i wklejane, możesz być w stanie refaktoryzować interfejs, jeśli nie pełną klasę.
Mark Hurd

3

To, co musisz zrobić, to refaktoryzacja. Refaktoryzacja jest prawie niemożliwa w takiej sytuacji bez testu jednostkowego, który daje pewność, że niczego nie złamałeś. Dlatego zacznij od utworzenia testów jednostkowych. Udokumentuj zachowanie kodu - ale nie (tylko na papierze), ale w większej ilości kodu - testy jednostkowe. Po zakończeniu testów możesz rozpocząć restrukturyzację kodu.


11
Byłem w tej sytuacji. Po pierwsze, VB6 ma żałosne zestawy testów jednostkowych. Po drugie, testy jednostkowe prawie zawsze wymagają DI, co jest bardzo trudne w VB6 ze względu na jego straszne wsparcie dla programowania obiektowego. Jeszcze nie słyszałem od nikogo, kto wziął udział w projekcie VB6, napisał kilka testów jednostkowych i zaczął się zastanawiać nad refaktoryzacją, nawet jeśli jest to podstawowa odpowiedź, którą zawsze usłyszysz na takie pytanie na Programmers.SE. Czy wiesz, jak bolesne jest pisanie testów jednostkowych dla logiki osadzonej wszędzie w modułach obsługi zdarzeń Form? Musisz napisać refaktor przed napisaniem testu!
Scott Whitlock,

Chciałbym dodać testy jednostkowe do naszego kodu, ale brakuje mi początku. Przeprowadziłem testy jednostkowe w .net i innych językach, ale tylko od podstaw, nigdy nie dodając testów do istniejącego projektu. Żadne z przeprowadzonych przeze mnie testów jednostkowych nie dotyczyło programów wykorzystujących GUI, szczególnie GUI z dużą ilością baz danych i logiki biznesowej zmiatanych w modułach obsługi zdarzeń!
Dylan Nissley,

1
Jeśli kod nie został napisany jako testowalny, wystarczy napisać testy jednostkowe, które obejmują proste i oczywiste przypadki, i pominąć przypadki skrajne, które powodują 90% wad. Byłem tam, zrobiłem to, zmarnowałem dużo czasu i wysiłku (czytaj Pieniądze). Najlepszym rozwiązaniem jest upewnienie się, że zmieniany kod jest łatwy do przetestowania - co zawsze oznacza to w twoim otoczeniu, co nie brzmi jak testy jednostkowe.
mattnz

3

Przypomina mi się jedna zasada z „ Debugowania ” Davida Agana : przestań myśleć i patrz. Zdarza się, że masz do dyspozycji maszynę zdolną do przetwarzania ogromnych ilości tekstu. Użyj go, aby dokładnie dowiedzieć się, który kod nie jest już używany i usuń go bez litości. Jeśli popełnisz błąd, po to jest kontrola źródła.

To najłatwiejsza część. Co musisz teraz przemyśleć, to jak jesz słonia? Jeden kęs na raz. Podnieś „ Refaktoryzację ” Martina Fowlera i przyjmij funkcję według funkcji, plik po pliku. Nie skrobaj czegoś całkowicie i nie przepisuj tego od wymagań, które według ciebie są. Pracuj jak alpinista, nigdy nie usuwając poprzedniego bezpieczeństwa, dopóki nie znajdzie się następny.

Masz już dość metafor? Chodzi o to, że jeśli powolny i stały, z wieloma ulepszeniami tak prostymi, jak zmiana nazwy lub podział funkcji, możesz poprawić złe części kodu bez niszczenia dobrych części, które powstały przez lata debugowania i żądań funkcji . Chcesz, aby kod cały czas był wysyłany. Jeśli jest to możliwe podczas przenoszenia do bardziej nowoczesnego języka, skorzystaj z niego.


O ile nie zostanie to zrobione poprawnie, „Przeniesienie do nowoczesnego języka” da „program VB w składni C #” - Obecnie pracuje nad aplikacją C przeniesioną do aplikacji Java, która tak naprawdę jest „Cava”, a nie Java - jest to najgorsze z obu i najlepsze z obu ........ Prawidłowe portowanie to tak naprawdę przepisanie w przeciąganie, a jak to ujął Joel - to wysoko na liście „rzeczy do zrobienia”.
mattnz

Słuszna uwaga. Dlatego powiedziałem „jeśli to możliwe”. Jeśli nie możesz tego zrobić krok po kroku, a także idiomatycznie napisać przeniesiony kod, nie powinieneś próbować.
Karl Bielefeldt,

3

Nienawidzę tego mówić, ale wybrałbym „całkowicie beznadziejny” poza kontynuowaniem niekończącego się cyklu łatania / ulepszania i mam nadzieję, że nic się nie złamie. Widziałem o wiele za dużo projektów VB6, takich jak ten, który opisujesz i próbuje przefakturować / przepisać / przerobić je do C # / .NET strasznie zawodzi, często z ludźmi odpowiedzialnymi za próbę zwolnienia.

Chodzi o to, że prędzej czy później konieczne będzie całkowite przepisanie od podstaw. Wersje VB6 i Windows, które dobrze go obsługują, są coraz mniej popularne. Znalezienie programistów, którzy znają dziwactwa VB6 i którzy są gotowi pracować nad takimi programami, jest coraz rzadsze. Wewnętrzne limity VB6 zostaną uderzone w takie ogromne programy, powodując dziwne błędy.

Jeśli w tym momencie istnieje dobry konsensus i zobowiązanie do całkowitego, gruntownego, przeprojektowania i przepisania, rozpocznij prace nad nim i przekaż bieżącą obsługę komuś innemu (kontrahentom, młodszym programistom, cokolwiek dla ciebie działa). Jeśli ludzie nie są jeszcze wystarczająco przekonani, aby zacząć, zaczekaj, aż ból stanie się wystarczająco silny lub przejdź na zielone pastwiska.


+1 Masz rację co do utraty wsparcia przez VB6 w nowoczesnych wersjach Windows. Wcześniej czy później (prawdopodobnie wcześniej) Twoja aplikacja po prostu przestanie działać tam, gdzie powinna.
Bernard,

1

Kilka dobrych odpowiedzi tutaj, chciałbym dodać jedną rzecz. Zamiast próbować przepisać wszystko, być może będziesz mieć możliwość przeniesienia przynajmniej niektórych z tych modułów, głównie 1: 1, do VB.NET (oczywiście musisz być bardzo ostrożny, robiąc to)? Z mojego doświadczenia wynika, że ​​takie przenoszenie można wykonać przy ~ 5-10 razy mniejszym wysiłku niż próba odbudowania wszystkich istniejących funkcji od podstaw. I po tym jak przeniósł go, po czym można rozpocząć byłaby - ze wszystkich tych narzędzi dostępnych w świecie .NET, jak dobre narzędzia do testowania jednostkowego, automatycznych narzędzi refaktoryzacji, real OOP etc.

Byłem w podobnej sytuacji, kiedy musieliśmy migrować stary 16-bitowy program C ++ (150k LOC) do 32-bitowego świata, w którym oryginalna używana platforma GUI nie była już dostępna. Trochę czasu zajęło nam zrozumienie, że przepisywanie nie było realistyczne, ale po tym, jak postanowiliśmy przenieść tę rzecz do świata .NET, używając C ++, C ++ / CLI i C #, potrzebowaliśmy tylko około 9 miesięcy, aby to się stało (przy około 1 dev praca na pełnym etacie nad tym projektem). Nie mieliśmy dostępnych testów jednostkowych części GUI, wszystkie testy tych części wykonaliśmy ręcznie.


0

Chociaż kładzie duży nacisk na testowanie jednostkowe aplikacji, co, choć jest bardzo ważną rzeczą do zrobienia, jest bardzo trudne w VB6, Steven McConnell napisał doskonałą książkę o tym, jak poradzić sobie z takim projektem.

Spójrz na to:

Steven C. MCCONNELL: Skutecznie współpracuje ze starszym kodem, wydanie drugie. Microsoft Press, czerwiec 2004.

Zasadniczo jego celem jest powolne, krok po kroku. Zaleca również, aby zacząć od zastosowania technik refaktoryzacji, które prawdopodobnie nie będą w stanie niczego uszkodzić, co czasem czyni go nieco gorszym w perspektywie krótkoterminowej, i zacząć używać bardziej zaawansowanych technik, ponieważ kod staje się bardziej przejrzysty i ma testy jednostkowe na jego poparcie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.