Kiedy BIG przepisze odpowiedź?

278

Wystarczy przeczytać pytanie dotyczące Wielkich Przepisów i przypomniałem sobie pytanie, na które sam chciałem odpowiedzieć.

Przekazano mi okropny projekt, napisany w starej Javie, przy użyciu Struts 1.0, tabele z niespójnymi relacjami lub w ogóle żadnych relacji, a nawet tabele bez kluczy podstawowych lub pól, które mają być kluczami podstawowymi, ale wcale nie są wyjątkowe. Jakoś większość aplikacji „po prostu działa”. Większość stron jest ponownie wykorzystywana (kopiuj wklejony kod) i zapisana na stałe. Każdy, kto kiedykolwiek pracował nad projektem, przeklął go w takiej czy innej formie.

Teraz od dawna zastanawiałem się nad zaproponowaniem wyższej kadrze kierowniczej całkowitego przepisania tej przerażającej aplikacji. Powoli staram się robić to w czasie osobistym, ale naprawdę czuję, że zasługuje na to, aby to osiągnąć. Po przeczytaniu artykułów o dużych przepisaniach mam inne przemyślenia. I to nie jest dobre, gdy chcę przekonać moich przełożonych, aby poparli moje przepisywanie. (Pracuję w dość małej firmie, więc propozycja może zostać zatwierdzona)

TL; DR Kiedy duży przepisujesz odpowiedź i jakich argumentów możesz użyć do jej wsparcia?

Jonn
źródło
1
Również powiązane: programmers.stackexchange.com/questions/20246/…
IAbstract
6
Jest stary, ale klasyczny - Joel's „Rzeczy, których nigdy nie powinieneś robić, część I” joelonsoftware.com/articles/fog0000000069.html
Mawg
To świetne pytanie. Bardzo istotne, taka sytuacja często występuje w inżynierii oprogramowania.
Brad Thomas

Odpowiedzi:

325

Przykro nam, to potrwa długo, ale opiera się na osobistym doświadczeniu zarówno architekta, jak i programisty przy wielu projektach przepisywania.

Poniższe warunki powinny spowodować rozważenie przepisania. Porozmawiam o tym, jak zdecydować, który z nich zrobić później.

  • Czas uruchamiania deweloperów jest bardzo długi. Jeśli uruchomienie nowego programisty zajmuje dłużej niż poniżej (według poziomu doświadczenia), system musi zostać przeprojektowany. Przez czas rozruchu mam na myśli ilość czasu, zanim nowy programista jest gotowy do pierwszego zatwierdzenia (w przypadku małej funkcji)
    • Świeżo po studiach - 1,5 miesiąca
    • Wciąż zielony, ale wcześniej pracowałem nad innymi projektami - 1 miesiąc
    • Średni poziom - 2 tygodnie
    • Doświadczony - 1 tydzień
    • Poziom Senior - 1 dzień
  • Wdrożenie nie może być zautomatyzowane ze względu na złożoność istniejącej architektury
  • Nawet proste poprawki błędów trwają zbyt długo ze względu na złożoność istniejącego kodu
  • Nowe funkcje trwają zbyt długo i kosztują zbyt wiele z powodu współzależności bazy kodu (nowych funkcji nie można wydzielić, a zatem wpływają na istniejące funkcje)
  • Formalny cykl testowania trwa zbyt długo z powodu współzależności istniejącej bazy kodu.
  • Zbyt wiele przypadków użycia jest wykonywanych na zbyt małej liczbie ekranów. Powoduje to problemy szkoleniowe dla użytkowników i programistów.
  • Wymaga tego technologia obecnego systemu
    • Programiści jakości z doświadczeniem w technologii są zbyt trudni do znalezienia
    • Jest przestarzałe (nie można go zaktualizować do obsługi nowszych platform / funkcji)
    • Dostępna jest po prostu znacznie bardziej wyrazista technologia wyższego poziomu
    • Koszt utrzymania infrastruktury starszej technologii jest zbyt wysoki

Te rzeczy są dość oczywiste. Kiedy decydować o całkowitym przepisaniu w porównaniu z przyrostową przebudową, jest bardziej subiektywna, a zatem bardziej polityczna. Z przekonaniem mogę powiedzieć, że kategoryczne stwierdzenie, że nigdy nie jest dobrym pomysłem, jest błędne.

Jeśli system może być stopniowo przeprojektowywany, a ty masz pełne wsparcie sponsoringowe projektu dla takiej rzeczy, powinieneś to zrobić. Oto problem. Wiele systemów nie może być stopniowo przeprojektowywanych. Oto niektóre z powodów, które napotkałem, które temu zapobiegają (zarówno techniczne, jak i polityczne).

  • Techniczny
    • Sprzężenie komponentów jest tak duże, że zmian w jednym elemencie nie można odizolować od innych komponentów. Przeprojektowanie pojedynczego komponentu powoduje kaskadę zmian nie tylko w sąsiadujących komponentach, ale pośrednio do wszystkich komponentów.
    • Stos technologii jest tak skomplikowany, że projekt przyszłego stanu wymaga wielu zmian infrastruktury. Byłoby to konieczne również przy całkowitym przepisaniu, ale jeśli jest to wymagane przy stopniowym przeprojektowywaniu, tracisz tę przewagę.
    • Przeprojektowanie komponentu i tak powoduje jego całkowite przepisanie, ponieważ istniejący projekt jest tak fubarowany, że nie warto nic oszczędzać. Ponownie tracisz przewagę, jeśli tak jest.
  • Polityczny
    • Nie można zmusić sponsorów do zrozumienia, że ​​stopniowe przeprojektowanie wymaga długoterminowego zaangażowania w projekt. Nieuchronnie większość organizacji traci apetyt na ciągłe zmniejszanie budżetu, które powoduje stopniowe przeprojektowywanie. Ta utrata apetytu jest nieunikniona również przy przepisywaniu, ale sponsorzy będą bardziej skłonni do kontynuowania, ponieważ nie chcą być podzieleni między częściowo kompletny nowy system i częściowo przestarzały stary system.
    • Użytkownicy systemu są zbyt przywiązani do swoich „aktualnych ekranów”. W takim przypadku nie będziesz mieć licencji na ulepszenie istotnej części systemu (interfejsu użytkownika). Przeprojektowanie pozwala obejść ten problem, ponieważ zaczynają się od czegoś nowego. Nadal będą nalegać na uzyskanie „tych samych ekranów”, ale masz trochę więcej amunicji, aby się wycofać.

Należy pamiętać, że całkowity koszt stopniowego przeprojektowywania jest zawsze wyższy niż całkowite przepisanie, ale wpływ na organizację jest zwykle mniejszy. Moim zdaniem, jeśli możesz uzasadnić przepisanie, a masz programistów superstar, zrób to.

Rób to tylko wtedy, gdy masz pewność, że istnieje wola polityczna, aby doprowadzić ją do końca. Oznacza to zarówno wpisowe dla kierownictwa, jak i dla użytkowników końcowych. Bez tego zawiedziesz. Zakładam, że właśnie dlatego Joel twierdzi, że to zły pomysł. Dla wielu architektów wpisowe dla użytkowników wykonawczych i użytkowników końcowych wygląda jak dwugłowy jednorożec. Musisz go agresywnie sprzedać i nieustannie prowadzić kampanię, aby go kontynuować. To trudne, a ty mówisz o tym, aby postawić swoją reputację na czymś, czego niektórzy nie będą chcieli zobaczyć.

Niektóre strategie sukcesu:

  • Jeśli jednak to zrobisz, nie próbuj konwertować istniejącego kodu. Zaprojektuj system od podstaw. W przeciwnym razie marnujesz swój czas. Nigdy nie widziałem ani nie słyszałem o projekcie „konwersji”, który nie zakończył się nieszczęśliwie.
  • Migruj użytkowników do nowego systemu pojedynczo. Zidentyfikuj zespoły, które odczuwają najwięcej bólu w istniejącym systemie i migruj je najpierw. Niech głoszą dobrą nowinę ustnie. W ten sposób Twój nowy system będzie sprzedawany od wewnątrz.
  • Zaprojektuj swoją architekturę tak, jak potrzebujesz. Nie zaczynaj od jakiegoś szkieletu, który spędziłem 6 miesięcy, który nigdy nie widział prawdziwego kodu.
  • Utrzymuj swój stos technologiczny tak mały, jak to możliwe. Nie przepełniaj projektu. W razie potrzeby możesz dodawać technologie, ale ich usunięcie jest trudne. Dodatkowo, im więcej masz warstw, tym więcej pracy wykonują programiści. Nie utrudniaj od samego początku.
  • Zaangażuj użytkowników bezpośrednio w proces projektowania, ale nie pozwól im dyktować, jak to zrobić. Zdobądź ich zaufanie, pokazując im, że możesz im dać to, czego chcą lepiej, jeśli postępujesz zgodnie z zasadami dobrego projektowania.
Michael Meadows
źródło
25
Myślę, że Joel ma na myśli to, że robiąc przeróbkę, tracisz wiedzę zgromadzoną w starym kodzie.
quant_dev
14
@ quant_dev częściowo tak, ale kiedy przepisujesz czasami zdajesz sobie sprawę, że wiele błędów w starym systemie było spowodowanych działaniem starego systemu, a nie ścisłą logiką związaną z tym, jak powinien działać idealny system.
Tjaart
13
Joel mówi, że to się nie powiedzie, ponieważ podczas przepisywania nie dodajesz żadnych nowych funkcji do swojej aplikacji. Jedynym celem przepisania jest wyeliminowanie części lub całości długu technicznego. To prawda, nie jest to drobiazg, ale ryzykowne jest, jeśli twoi konkurenci dodają nowe funkcje i funkcje do swojego oprogramowania, gdy tylko pozbywasz się długu technicznego w swoim.
Robert Harvey
25
Pracowałem z bazą kodu, która spełnia wszystkie te kryteria +, a mimo to Big Rewrite wciąż zawiodło i pod pewnymi względami pogorszyło sytuację, dając nam do połowy zaimplementowany kod „nowej umowy” do obsługi, który był bardzo różny od starego chaosu, ale nie o wiele łatwiejsze do zarządzania. IMO, tylko jeśli refaktoryzacja staje się całkowicie niemożliwa, należy usunąć wszelkie skupienie na dodawaniu funkcji i naprawianiu błędów, które kosztują dziś klientów. Jeśli nie mówisz naprawdę nieczytelnego kodu, zespół, który nie jest w stanie wyciągnąć modułowych bitów w celu łatwiejszego ponownego wykorzystania w trakcie podróży, prawdopodobnie nie może zreorganizować wystarczająco dobrze dla dużego RW.
Erik Reppen
11
To przydatna odpowiedź, ale daleka od bycia fantastyczną, ponieważ w niektórych kwestiach robi złe wrażenie. Na przykład: „Należy pamiętać, że całkowity koszt ponownego zaprojektowania przyrostowego jest zawsze wyższy niż całkowite przepisanie” - słowo „zawsze” w tym zdaniu jest błędne, ponieważ „ponowne zaprojektowanie przyrostowe” daje możliwość ponownego użycia co najmniej niektórych części istniejącego projektu, podczas gdy „całkowite przepisanie” tego nie oferuje. Wiem to na pewno, ponieważ tak naprawdę byłem w takiej sytuacji, w której przepisaliśmy aplikację LOC> 100 000 częściowo w całości, a częściowo nie.
Doc Brown,
109

Brałem udział w dwóch dużych przepisywaniach. Pierwszy był małym projektem. Drugi był głównym produktem firmy programistycznej.

Istnieje kilka pułapek:

  • przepisywanie zawsze trwa dłużej niż oczekiwano.
  • przepisywanie nie ma bezpośrednich efektów / korzyści dla klienta.
  • pojemność przeznaczona na przepisywanie nie jest wykorzystywana do wspierania klienta.
  • utracisz funkcjonalność po przepisaniu, chyba że masz 100% dokumentację.

Przepisywanie rzadko jest prawdziwą odpowiedzią. Możesz refaktoryzować większość kodu bez utraty niczego i bez większego ryzyka.

Przepisania mogą być odpowiedzią, jeśli:

  • zmieniasz język lub platformę.
  • przełączasz frameworki / komponenty zewnętrzne.
  • istniejąca baza kodów nie jest już możliwa do utrzymania.

Ale zdecydowanie zalecam powolne podejście z wykorzystaniem refaktoryzacji. Jest to mniej ryzykowne i zapewniasz swoim klientom zadowolenie.

Toon Krijthe
źródło
11
+1 za podejście do refaktora. Wiele razy brakuje czasu lub roboczogodzin, aby przepisać ORAZ utrzymać istniejący system.
Ryan Hayes,
Jest to obecnie używane w aplikacji demonstracyjnej (żaden klient nie kupił jej ostatnio i uznałem, że teraz jest najlepszy czas na jej odtworzenie).
Jonn
4
@John: Jako dyrektor wykonawczy bardzo trudno mi byłoby napisać na nowo przepisanie aplikacji, dla której mój zespół sprzedaży nie ma jeszcze klienta. Szczerze mówiąc, poświęcę mu trochę czasu, a potem zdecyduję, co robić. Jeśli nie ma zainteresowania, wyrzucę to wszystko i wybiorę coś innego.
NotMe
4
Niedawno przepisałem aplikację Visual Basic w Javie. Dzięki temu można go było uruchomić jako usługę w systemie Windows (bez graficznego interfejsu użytkownika Java) - korzyść dla klienta.
4
„przepisywanie nie ma bezpośrednich efektów / korzyści dla klienta” - to często mit, ponieważ nowsze ramy zapewniają „wbudowane” wiele ulepszeń wydajności, których wdrożenie lub wdrożenie jest zbyt drogie. Jeden przykład: aktualizacja aplikacji vb6 do aplikacji .net pozwala użytkownikom otwierać większe pliki (ze względu na architekturę 64-bitową), co oznacza, że ​​użytkownicy końcowi nie muszą sztucznie przerywać pracy.
Stephen
72

Czas przepisać, gdy:

Koszt przepisania aplikacji + utrzymanie przepisanej aplikacji jest niższy niż koszt utrzymania obecnego systemu w czasie.

Niektóre czynniki, które sprawiają, że utrzymanie obecnego jest droższe:

  • Język jest tak stary, że trzeba płacić ludziom, którzy wiedzą, że można w nim dużo programować (COBOL).
  • (z doświadczenia, niestety) System działa na architekturze sprzętowej, która jest tak stara, że ​​musi przeszukać Ebay i ZBIERAĆ części, aby dodać je do maszyny, na której działa, ponieważ nie są już produkowane. Nazywa się to „podtrzymaniem trwałości sprzętu” i jest drogie, ponieważ ponieważ części stają się coraz rzadsze, mogą (mogą) wzrosnąć ceny lub (absolutnie) ostatecznie się skończą.
  • Stało się tak złożone, że //Here be dragons.komentarz jest w całym kodzie.
  • Nie możesz pisać żadnych innych projektów i dodawać nowej wartości do firmy, ponieważ zawsze łatasz tę brzydką bestię.
Ryan Hayes
źródło
Właśnie to skłoniło do przepisania, w którym uczestniczyłem. Kod był tak delikatny, a koszt dodawania nowych funkcji tak wysoki, że brak przepisywania nie był już opcją.
Frank Shearar
16
Chicham tutaj o punkcie 2.
Paul Nathan
4
@Paul: Ja też to zrobiłem, kiedy klient mi to powiedział, a potem dowiedziałem się, że są poważne ... i że będę zbierał wymagania dotyczące przepisywania. To był ekscytujący dzień.
Ryan Hayes
3
Problem polega na tym, jak mierzysz koszty.
2
Podoba mi się ta odpowiedź, zabawna i prawdziwa. Chciałbym dodać „ilościowo” tuż przed „mniej”. Tyle razy łatwo jest złożyć wniosek, ale ważne jest, aby móc oszacować zmarnowany czas.
Kevin Hsu,
17

Jeśli potrzebujesz fundamentalnej zmiany w architekturze projektu, być może czas zacząć od nowa.

Mimo to potencjalnie będą istnieć duże obszary kodu, które nadal warto ponownie wykorzystać w nowym projekcie.

Uważaj jednak na uczciwe ostrzeżenie. Obecny projekt zostanie przetestowany i dopracowany pod kątem reguł biznesowych przy niezliczonych roboczogodzinach, co nie będzie prawdą w przypadku projektu rozpoczętego od zera.

Wątpię, czy przedział czasowy lub przeczucie jest odpowiednią miarą tak drastycznego środka. Musisz mieć jasne , uzasadnione i dobrze zrozumiałe powody, aby wziąć udział w tym postępowaniu.

Dan McGrath
źródło
3
Musisz być bardzo ostrożny przy „ponownym projektowaniu dużych obszarów kodu”, może to prowadzić do nieużywanego starszego kodu i złej struktury kodu. Moim zdaniem refaktoryzacja jest lepszym rozwiązaniem.
mrwooster
1
Zgoda. Część tego stwierdzenia należy interpretować jako „refaktoryzację” do „nowego” projektu. To znaczy, jeśli rzeczywiście już popełniłeś tę drastyczną ścieżkę. Jak wspomnieli inni, jest to wyjątkowa rzadkość, której prawie nigdy nie należy robić.
Dan McGrath
1
+1. Również przepisanie zajmie trochę czasu, podczas którego trzeba będzie wykonać konserwację, ale te same zmiany będą musiały zostać wykonane w obu bazach kodu.
Larry Coleman
12

Chociaż zgadzam się z odpowiedzią Kramii i opinią Joela, zdarzają się sytuacje, w których należy przerobić. W aplikacjach długowiecznych (mówię o 10-20 lat lub więcej) utrzymanie z czasem staje się coraz droższe. Wynika to z faktu, że kod staje się coraz bardziej spaghetti, ponieważ oryginalna architektura jest poświęcana dla szybkich łat konserwacyjnych. Ponadto programiści starszych technologii stają się coraz rzadsi i drożsi. Wreszcie, sprzęt zaczyna się starzeć i coraz trudniej jest znaleźć nowy sprzęt, systemy operacyjne, frameworki itp. Do uruchomienia starej aplikacji. Ponadto firmy ewoluują i najprawdopodobniej starszy system nie będzie odpowiadał potrzebom biznesowym organizacji, tak jak zupełnie nowy system.

Musisz więc wyważyć wszystkie bieżące koszty utrzymania, a także potencjalne korzyści płynące z nowego systemu dla firmy, z kosztami przepisania rzeczy od zera. Bądź bardzo pesymistyczny w swoich szacunkach dotyczących kosztu przepisania. Prawie zawsze kosztuje więcej i trwa dłużej niż mogłoby się wydawać.

RationalGeek
źródło
+1 za wzmiankę o prawie Hofstadtera .
Baelnorn
11

Zatrzymać! Przepisywanie prawie nigdy nie jest odpowiedzią. Najczęściej refaktoryzacja jest lepszym rozwiązaniem.


Oczywiście, chwile, kiedy przepisać to uzasadnione:

  • Przechodzisz na nową platformę, na której nie istnieją narzędzia migracji (lub których nie można napisać wystarczająco tanio).
  • Aplikacja do przepisania jest trywialna.
  • Utracono kod źródłowy oryginalnej aplikacji, a odzyskiwanie jest droższe niż przepisywanie.
  • Zdecydowana większość reguł biznesowych zawartych w istniejącej aplikacji nie ma już zastosowania.
  • Istnieje niewielu aktywnych użytkowników istniejącego kodu.
  • Masz zasoby (czas, talent i narzędzia), aby dokonać przepisywania.
  • Istniejącej aplikacji nie można uruchomić w środowisku produkcyjnym, ze względów prawnych lub praktycznych.

Aby zrozumieć, dlaczego zalecam refaktoryzację zamiast przepisywania, zastanów się, co jest związane z przepisywaniem. Musisz:

  1. Poznaj niuanse tego, co robi istniejąca aplikacja. Nie jest to zwykle trywialne, gdy weźmie się pod uwagę wszystkie subtelne reguły biznesowe, które zawiera, środowisko (ludzkie i techniczne), w którym działa, oraz zalety i wady obecnego rozwiązania. Częściej niż nie, jedynym miejscem, w którym te informacje istnieją (jeśli gdziekolwiek są), jest kod źródłowy istniejącej aplikacji. Szkoda, że ​​jednym z głównych powodów przepisywania jest to, że istniejący kod jest trudny do zrozumienia i utrzymania.

  2. Odtwórz tę funkcję (lub jej zaktualizowaną wersję) w nowej, przetestowanej i niezawodnej aplikacji. Istniejący kod może nie zostać zrozumiany przez programistów, ale zazwyczaj jest dobrze zrozumiany przez jego użytkowników. Może nie spełniać ich bieżących potrzeb biznesowych, ale mogą przynajmniej powiedzieć ci, co robi aplikacja w różnych okolicznościach.

Dużymi zaletami refaktoryzacji są:

  • Możesz wziąć rzeczy po jednym kawałku na raz.
  • Wszelkie zmiany można przetestować w kontekście istniejącej, działającej aplikacji.
  • Hipotezę dotyczącą sposobu działania istniejącego kodu można przetestować, wprowadzając niewielkie zmiany i obserwując, co się dzieje.
  • Zmiany mogą być często dostarczane użytkownikom etapami, a nie naraz.
  • Uczenie się od wczesnych etapów refaktoryzacji może pomóc w późniejszych etapach refaktoryzacji.
  • Jeśli porzucisz proces w połowie, nadal będą korzyści w postaci czystszej bazy kodu (w przeciwieństwie do przepisywania, które należy wykonać, aby zaoferować jakiekolwiek korzyści dla użytkownika lub programistów).

Pamiętaj też, że jeśli przepiszesz, masz gwarancję wprowadzenia wielu nowych błędów i bałaganu w nowej bazie kodu.

Kramii
źródło
2
Czy możesz rozwinąć tę odpowiedź, wyjaśniając, dlaczego refaktoryzacja jest lepsza niż przepisywanie? A kiedy będzie przepisanie być odpowiedź?
gablin
Biorąc pod uwagę fakt, że przepisywanie najczęściej jest po prostu tym samym bałaganem w innym stroju, masz rację. Jeśli możesz wyeliminować ten pojedynczy problem, to się mylisz. Nie ma absolutów, gdy robią to odpowiedni ludzie.
JensG
10

Ta grafika może pomóc, jest to funkcja jakości bazy kodu i wartości biznesowej aplikacji:

wprowadź opis zdjęcia tutaj

Wykres udaje, że jest wskazówką, kiedy przeprojektowanie starszego oprogramowania jest uzasadnione, a kiedy nie. Na przykład, jeśli oprogramowanie ma wysoką wartość biznesową, a jakość kodu jest niska, uzasadnione jest ponowne zaprojektowanie.

61852
źródło
4
Dlaczego miałbyś inwestować w przepisywanie projektu o niskiej wartości biznesowej? Po prostu złomuj to!
Jørgen Fogh
Właśnie dlatego statess „zamień lub ...”. Możesz zastąpić coś, co ma wartość. Lub zrób z tego coś, co ma wartość. Ale masz rację. Zmienię go, aby dodać opcję „złom”.
Tulains Córdova
8

Myślę, że jestem jedyną sytuacją w mojej karierze, w której duże przepisanie jest odpowiedzią:

Fuzja firm, ogromne nakładanie się funkcjonalności systemów. Wiele systemów zostało połączonych i wycofanych, a inne wciąż są w trakcie procesu.

Odziedziczyłem system od innej firmy, która nadal żyje. Ma ogromną bazę kodu, która obsługiwała wiele działów bardzo podobnych do naszego, ale z zupełnie innym wyglądem i strukturami. Został z niego tylko jeden sektor biznesowy, który zarabia wystarczająco dużo pieniędzy, aby utrzymać to przy życiu w stanie zombie. Cała stara wiedza zniknęła, nie ma dokumentacji. Obciążenie związane z obsługą jest wysokie, a awarie co tydzień. Nie został włączony do systemów naszych firm, ponieważ nasza firma nigdy nie wspierała tego konkretnego sektora działalności, więc nie mamy funkcjonalności ani wiedzy specjalistycznej.

Wygląda na to, że jest to jedyny przypadek, w którym konieczne jest przepisanie. Wygląda na to, że będę musiał zrozumieć tego giganta, wyciągnąć elementy funkcjonalności dedykowane dla tego biznesu i przepisać elementy, które należy dodać do naszych istniejących systemów. Kiedy to się stanie, nasze istniejące systemy będą w stanie obsługiwać ten nowy sektor, a bestia może zostać wyeliminowana z nędzy. W przeciwnym razie stracę zdrowie psychiczne.

Sójka
źródło
Wygląda na to, że Twój pracodawca musi porozmawiać z klientami i wyjaśnić sytuację, aby dowiedzieć się, jaki może być najlepszy sposób, aby im pomóc, nawet jeśli oznacza to, że muszą początkowo płacić więcej, ponieważ zaoszczędzą na dłuższą metę.
7

Pracowałem dla małej firmy programistycznej, która miała kilka aplikacji DOS, które zostały zaktualizowane do obsługi Y2K, przepisane jako 16-bitowa aplikacja Windows, a następnie całkowicie przepisane jako aplikacja 32-bitowa z jedną dodatkową „małą” funkcją (ostatecznie wykorzystywaną tylko przez jeden klient), który wpłynął na całą strukturę.

Przeniesienie 16-bitowego kodu do 32 mogło być wykonane w ciągu miesiąca przez jedną osobę, ale NOOOOOOOOO, musieliśmy go przepisać, aby Soooooooooo było znacznie lepsze. Ta rzecz może być przystosowana do innych gałęzi przemysłu, miałaby pełną specyfikację i kod psuedo, zanim jeszcze zaczęły. Specyfikacje zostały utworzone, ale zajęło to tak dużo czasu, że nie było nawet czasu na napisanie prawdziwego kodu. Został wydany późno, z większą liczbą błędów niż 16-bitowy „zaczął” (był na wersji 3.0 i wreszcie do tego stopnia, że ​​prawie zrobiliśmy to tydzień bez kogoś zgłaszającego nowy błąd).

Można by pomyśleć, że przepisanie tej samej aplikacji 3-4 razy przyniosłoby pewne ulepszenia, ale nie sądzę, żeby interfejs GUI był tak uzasadniony.

To była moja pierwsza praca IT jako szef działu wsparcia technicznego. Powinienem napisać książkę o tym, jak nie tworzyć oprogramowania do dystrybucji. Oczywiście popełniliśmy wiele błędów, ale fakt, że nadal przepisywaliśmy aplikacje, spotęgował niekompetencję.

JeffO
źródło
5

Miałem przypadek bardzo podobny do twojego, ale kod nawet nie używał Struts. Zamiast tego wybrałem obszary docelowe, które były wyjątkowo kiepskie ORAZ powodujące wiele problemów. To ukierunkowane podejście poprawiło nas stopniowo.

W ciągu 2 lat pracowaliśmy nad refaktoryzacją bitów i elementów, a także pracami ulepszającymi. Zawsze pracowaliśmy nad zadaniem „hartowania” w planie projektu. Koncentrując się na konkretnych obszarach, które nie działały dobrze, uzyskaliśmy największe zyski. Rzeczy, które działały, zostawiliśmy w spokoju. Krytyczne jest również to, że praca ta została wykonana w trakcie normalnego rozwoju i została wydana. Problem z dużym przepisywaniem polega na tym, że robisz to przez rok lub dłużej, a potem, kiedy wracasz, wszystkie rzeczy i tak się zmieniły, a niektóre z paskudnych błędów zostały wygładzone i straciłeś ROI.

Nigdy nie napisaliśmy tego od nowa. Przestaliśmy jednak używać tej platformy do nowej pracy i przygotowaliśmy nową świeżą platformę do nowego dużego projektu. Zostało to zatwierdzone i dostarczyliśmy świetny produkt w rozsądnym czasie.

Bill Leeper
źródło
5

Więc tutaj siedzę przy biurku i zacząłem ponownie pisać kod dla tego absolutnego bałaganu jednego dużego pliku aspx, bazy danych za nim i zastępując interfejs MS Access MsSQL.

Ten program asp jest zaśmiecony takimi rzeczami jak

  • include(close.aspx) który w środku ma jeden wiersz kodu, który zamyka ostatnie otwarte połączenie z bazą danych.
  • Stary kod został po prostu skomentowany losowo
  • Brak wynagrodzenia za bezpieczeństwo
  • Kod spaghetti, tysiące jego linii. Wszystko w jednym pliku.
  • Funkcje i zmienne bez wyraźnego znaczenia za ich nazwami

Jeśli kiedykolwiek będziemy musieli wprowadzić niewielką zmianę, to tak, jakbyśmy grali w pięć jednoczesnych gier kal-toh w trybie koszmaru.

Zostałem zatrudniony do replikacji funkcjonalności i stworzenia produktu, który można dostosowywać i sprzedawać innym w branży. Problem polega na tym, że ta rzecz została napisana w ciągu ostatnich 10 lat, aby zaspokoić każdą potrzebę biznesową (cóż, i tak powiedziałbym o pięciu lub sześciu sigmach z nich).

Gdybyśmy nie chcieli sprzedawać produktu, prawdopodobnie nie potrzebowaliby ponownego napisania, ponieważ robi większość tego, czego chcą - być może nie elegancko, ale wydawanie pieniędzy na robienie dobrego kodu nie było rozsądne. 'Zrób to samo.'

Incognito
źródło
4

Joel Spolsky ma doskonały artykuł na ten temat: Rzeczy, których nigdy nie powinieneś robić, część I

Po tytule, który można powiedzieć, jest on jednostronny (mówi o tym, dlaczego nigdy nie należy rzucać kodu) IMO, jest w tym wiele prawdy, ostatnio widziałem wideo channel9 w 25. rocznicę Excela, gdzie niektórzy deweloperzy powiedzieli, jak to zrobić nawet dzisiaj, jeśli zajrzysz do źródła, sprawdzisz wersję i wrócisz do kodu używanego przez program Excel, który został napisany 20 lat temu.

Nie można być w 100% pewna (gdy nawet Netscape popełnia błędy (od Joels artykułu)), mam ochotę artykułu Joela był Bóg posłał, bo mogę być pesymistą i miłości wyrzucać kod myślenie zawsze mogę napisać to lepiej drugi czas, ale zdałem sobie sprawę, że dopiero teraz to dużo kosztuje .

Aby dać konkretną odpowiedź, chciałbym tylko powiedzieć, że musisz przeprowadzić dokładną analizę kosztów w porównaniu do wartości .

Mój świat rzeczywisty: aplikacja Silverlight, w której do tej pory pracuję nad wersją v0.6, zawiera wiele wywołań asynchronicznych, które powodują, że kod jest tak zawiły. Odkąd odkryłem Reactive Extensions w tym tygodniu, naprawdę chcę ponownie napisać większość kodu, ale teraz co mam powiedzieć mojemu klientowi? Program działa idealnie dobrze (z pewnymi przeciekami pamięci), ale czy ich to nie obchodzi? Nie mogę im powiedzieć, że biorę jeszcze 2-3 tygodnie, bo chcę coś zrobić ponownie. Mam jednak zamiar rozgałęzić kod i ponownie go napisać / grać w wolnym czasie.

Tylko moje 2 centy ok !?

gideon
źródło
Twoja pierwsza implementacja jest często nieoptymalna, ponieważ są rzeczy, których jeszcze nie wiesz przy projektowaniu. Zwykle będzie można go przekształcić w kształt zamiast zaczynać od nowa, ponieważ najprawdopodobniej zrobiłeś coś dobrze. Jeśli nie, jest to dowód koncepcji i często należy je wyrzucić.
+1 za rozgałęzienie. Wiele osób mówi „nie przepisuj”, ponieważ wygląda na to, że wyrzucasz stary kod - ale tak nie jest. Możesz mieć równoległe podstawy kodowe.
lunchmeat317
Szczerze mówiąc, jeśli jesteś osobą, która prosi Joela Spolsky'ego o radę, nie powinieneś robić kompletnego przepisywania :-) A w przeciwnym razie powinieneś przepisywać tylko, jeśli możesz przekonać wszystkich interesariuszy, dlaczego argumenty Joela się nie liczą w twoim konkretnym przypadku.
gnasher729
3

Istniejące rozwiązanie nie jest skalowane.

Patrzę na ciebie, MS Access.

użytkownik21007
źródło
Nie jestem pewien, czy patrzysz na właściwą. Jet Red nigdy nie miał być skalowany, AFAIK.
JensG
Jak to odpowiada na zadane pytanie?
komar
3

Według Joela duże przepisywania są najgorszym strategicznym błędem, jaki może popełnić firma:

Rzeczy, których nigdy nie powinieneś robić, część I

... Ważne jest, aby pamiętać, że kiedy zaczynasz od zera, nie ma absolutnie żadnego powodu, aby wierzyć, że wykonasz lepszą robotę niż za pierwszym razem. Po pierwsze, prawdopodobnie nie masz nawet tego samego zespołu programistów, który pracował nad wersją pierwszą, więc tak naprawdę nie masz „większego doświadczenia”. Ponownie popełnisz większość starych błędów i wprowadzisz nowe problemy, których nie było w oryginalnej wersji.

Stara mantra, którą można wyrzucić, jest niebezpieczna, gdy stosuje się ją w zastosowaniach komercyjnych na dużą skalę. Jeśli piszesz kod eksperymentalnie, możesz chcieć zerwać funkcję napisaną w zeszłym tygodniu, gdy myślisz o lepszym algorytmie. W porządku. Możesz zrefaktoryzować klasę, aby była łatwiejsza w użyciu. To też w porządku. Ale wyrzucenie całego programu jest niebezpiecznym szaleństwem, a gdyby Netscape rzeczywiście miał jakiś nadzór dorosłych z doświadczeniem w branży oprogramowania, mogliby nie rzucić się tak mocno w stopę.

3287
źródło
5
Tak. Szukałem przeciwwskazań do tego. Czasem trzeba to zrobić.
Jonn
3
Każdy argument przepisywania nie jest kompletny bez odniesienia do artykułu Joela. To, co mówię, że artykuł ma pewne dobre strony, ale do cholery, pomyśl sam. Może powinieneś powiedzieć, dlaczego zgadzasz się z tym artykułem. Nie zgadzam się osobiście z Joelem - po prostu dlatego, że czasami lepiej jest wykopać sobie nową dziurę niż zanurzyć się głębiej w otchłań, która kończy się smutkiem. W każdym razie, przepisanie, jak sądzę, przyniosłoby te ukryte procesy biznesowe na powierzchnię do ponownej oceny.
Ahmad
Artykuł Joelsa jest dobry, ponieważ dokładnie wyjaśnia, jak złe rzeczy mogą pójść.
6
Joel używa przykładu przeglądarki Netscape Navigator. To produkt konsumencki, który znajdował się w środku ogromnej krzywej wzrostu, działając przeciwko konkurencji z dużym budżetem. To był strategiczny błąd dla Netscape. Z drugiej strony, wewnętrzne niestandardowe projekty oprogramowania dla przedsiębiorstw są inne. Nie śpieszysz się po udział w rynku. Nie ma niebezpieczeństwa, że ​​wszyscy użytkownicy przejdą na konkurencyjny produkt. Wszystko sprowadza się do decyzji biznesowej: czy koszt przepisywania zwróci się na dłuższą metę i / czy jest to najlepszy sposób na osiągnięcie celów biznesowych?
Scott Whitlock,
Myślałem, że Joel uderzył w kluczową koncepcję: „Nigdy nie wiadomo, jakie decyzje nie zostały udokumentowane, że będziesz musiał się uczyć na
własnej skórze
2

Nigdy, zawsze refaktoryzuj - prawda jest taka, że ​​jeśli kod został napisany przez ciebie - nie będziesz w stanie zrobić nic lepszego.

O ile nie chcesz zmienić technologii, w kodzie brakuje jakiejkolwiek struktury (widziałem go bardzo dawno temu na jakiejś stronie PHP, autor po prostu kopiuje / wkleja spahgetti zamiast include / class / function) lub przejąłeś coś od innej osoby, która bardzo źle napisane.

Wszystko powinno być zaprojektowane jako blackbox. Modułowy, prosty interfejs API, co jest w środku ... to mniej ważne :) Jeśli masz spaghetti, być może będziesz w stanie zamknąć go w blackboksie, aby nie zanieczyścił dobrego kodu.

Sławek
źródło
Wspaniale, Slawek! extremeprogramming.org/rules/refactor.html
Lukas Eder
+1 Podoba mi się Twoja opinia. Chciałbym poznać Twoje przemyślenia na temat ponownego napisania na nowszy zestaw API? (Zobacz moją odpowiedź poniżej)
gideon
Tak, to są dobre punkty. Microsoft przepisał kod WinXP i nie mogli nawet usunąć / skopiować pliku bezpośrednio w pierwszej wersji detalicznej Visty. Podczas gdy po prostu robili postępy w zakresie kodu, stale poprawiamy jakość (W3.11 => W95 => W98 => ME => XP), Vista, w której przepisali wiele kluczowych części, była katastrofą. W przypadku nowego interfejsu API ... oddzieliłem bieżący kod, aby mieć jak najwięcej nienaruszonych, i użyłem nowego interfejsu API na wyższej warstwie. Na przykład. Twoje podstawowe klasy pozostają bez zmian, ale integracja odbywa się za pomocą nowego interfejsu API. Chyba że wszystko jest tak niechlujne, że nic innego nie można zrobić niż zacząć od 0.
Sławek
1
„... prawda jest taka, że ​​kod został napisany przez ciebie - nie będziesz w stanie zrobić nic lepszego”. Oddałbym głos tego postu, gdybym miał wystarczająco dużo przedstawicieli Jest to najbardziej porażające, nierealne i sugeruje, że ludzie nie mogą przejść do tego stopnia, że ​​kod, który piszą, jest ulepszeniem kodu, który napisali w przeszłości.
JᴀʏMᴇᴇ
1
@ JᴀʏMᴇᴇ: Zgoda - jeśli niczego się nie nauczyłeś i nie zdobyłeś doświadczenia przy wdrażaniu go po raz pierwszy i / lub jeśli nie możesz wykonać lepszej pracy teraz, gdy masz więcej wiedzy / doświadczenia / perspektywy; wtedy jesteś ziemniakiem, a nie programistą.
Brendan
2

Myślę, że głównym powodem uzasadniającym przepisywanie są zmiany platformy. Na przykład, jeśli masz aplikację GUI dla systemu Windows, a właściciel firmy zdecyduje, że chce, aby następna wersja była aplikacją internetową. Chociaż nie zawsze, z mojego doświadczenia wynika, że ​​będzie to wymagało przepisania, chyba że pierwotni programiści napisali bardzo modułowy i wielokrotnego użytku kod (rzadko się zdarza).

Craig
źródło
2

Jest taki klasyczny żart: „gdybym jechał na XI, nie zacząłbym od tego miejsca”.

Raz podjąłem pracę, gdzie główną motywacją pracodawcy było sprowadzenie talentu na pokład, aby uruchomić od dawna opóźnione przepisanie aplikacji o krytycznym znaczeniu dla biznesu. Pytanie, którego nie zadałem, brzmiało: dlaczego znalazłeś się w takiej sytuacji? Powinna to być czerwona flaga, niezależnie od tego, czy była tego przyczyna

  • zbyt duży nacisk, aby dodać funkcjonalność do utrzymania i stopniowego refaktoryzacji bestii,

  • zbyt mało umiejętności w dziale,

  • zbyt małe zaangażowanie ze strony klientów lub kierownictwa do pracy przyrostowej,

czy cokolwiek innego, a to powoduje odejście, aż problem osiągnie nie do zniesienia poziom.

Więc zgodzę się z Joelem, że masowe przepisywanie jest prawdopodobnie bardzo złym pomysłem - chyba że masz mocne dowody, że wszystkie podstawowe przyczyny, dla których poważna przeróbka wydaje się tak konieczna, zostały rozwiązane , istnieje duże prawdopodobieństwo zamierzam powtórzyć problem we właściwym czasie.

Julia Hayward
źródło
2

Jest to odpowiedź, gdy przepisanie pozwala organizacji realizować strategię, która zapewnia przewagę konkurencyjną lub pozwala lepiej obsługiwać klientów w taki sposób, że obecna architektura nie jest w stanie tego zaakceptować.

Zamiast tego przepisywanie często zdarza się, aby zmniejszyć obawy związane z zarządzaniem:

  • wszystko powinno być w .NET,
  • nasi programiści twierdzą, że nasz kod jest do bani,
  • technicznie pozostajemy w tyle,
  • nie będziemy w stanie znaleźć zasobów do obsługi naszego systemu lub, bardzo często,
  • minęło dziesięć lat, więc czas.

Większość tych zmartwień nie zmaterializuje się, a jeśli tak, to można je rozwiązać. Ten ostatni jest jednak najgorszy. Zasadniczo: nie mamy powodu.

Tak, podobnie jak samochód, system zacznie wykazywać oznaki zużycia. Można to złagodzić poprzez rutynowe serwisowanie. Wiesz, co mówią o tym, jak mała konserwacja zapobiegawcza przechodzi długą drogę. Jako inwestycja rutynowe serwisowanie (tj. Refaktoryzacja i standaryzacja) prawie zawsze wiąże się z niższymi kosztami niż przepisywanie.

Musimy jednak przewidzieć, że przepisanie będzie ostatecznie konieczne. Ustal daty i wstępnie je zaplanuj, ale w miarę zbliżania się terminu, aby realizować inne strategiczne cele, dopóki nie będziesz miał ważnego powodu, takiego jak ...

W ostatnich latach straciliśmy okazję do zdobywania dużych kont, ponieważ nie mogliśmy zaspokoić ich potrzeb w odpowiednim czasie lub kosztownie. Nasz system zostanie przepisany przy użyciu rozszerzalnej architektury, która pozwala na podłączanie dostosowań (i nie jest zakodowana na stałe, jak obecnie). To radykalnie skróci czas i koszty przystosowania klientów o specjalnych potrzebach. Wygrywamy więcej kont i lepiej zaspokajamy potrzeby naszych obecnych klientów.

Mario T. Lanza
źródło
Wydaje się, że powinieneś być w stanie refaktoryzować w tym kierunku. Podczas refaktoryzacji należy zapewnić niezbędną elastyczność, aby kolejna funkcja była łatwa do napisania.
Ian
1

Przy przejściu do całkowicie nowej technologii potrzebna jest pożądana funkcjonalność.

„Zupełnie nowy”: jeśli planujesz przepisać, ale używasz tej samej platformy, refaktoryzacja i rozsądna restrukturyzacja są prawie na pewno lepszym rozwiązaniem. „Platforma”, jak tutaj użyto, jest nieco niejasna - weź pod uwagę, że obejmuje ona język i być może system operacyjny (rozciągający się z Linuksa na Windows lub odwrotnie), ale prawdopodobnie nie jest strukturą (np. Zastępuje Struts Springem).

„Potrzebne do zapewnienia pożądanej funkcjonalności”: około 2000 roku zainicjowałem projekt przepisania ważnego komponentu serwerowego w Javie z C ++, aby umożliwić gotowe wątki, buforowanie obiektów i transakcje kontrolowane przez klienta. W tym czasie istniało wiele bibliotek wątków dla C ++, które musieliśmy obsługiwać, a obsługa wątków w dużej części naszego kodu bazy danych wymagałaby prawie całkowitego przepisania. Jeśli chodzi o transakcje kontrolowane przez klienta ... nie stanie się to ze starą architekturą.

Nawet wtedy nie jestem pewien, czy zrobiłbym to na nowo, poza tym, że miałem szczegółową wiedzę na temat zachowania obecnego systemu i był to stosunkowo czysty kod, który nie rozwinął zbyt wielu brodawek w ciągu 11 lat swojego życia.

Zaraz
źródło
0

Aby zdecydować, od kiedy powinieneś zacząć od nowa, musisz ustalić, gdzie wartość kontynuacji bieżącego projektu jest mniejsza niż wartość rozpoczynania od nowa.

Powodem tego jest to, że dokonujesz dokładnego oszacowania prędkości rozwoju zespołu w nowym projekcie, dopóki go nie uruchomisz. To powiedziawszy, jeśli, używając BARDZO konserwatywnego oszacowania twojej prędkości rozwoju w nowym projekcie, szacuje się, że projekt zapewnia opłacalny zwrot z inwestycji, to masz uzasadnienie biznesowe, aby zacząć od nowa.

Nikt
źródło
0

W przypadku moich danych musisz spełnić dwa warunki, aby uzasadnić przepisanie:

  1. Po przepisaniu nowe funkcje będą łatwiejsze / szybsze / mniej błędów w pisaniu
  2. Przepisanie zajmie mniej lub więcej czasu niż dodanie bieżącej nowej funkcji.

Nawet wtedy chcesz ograniczyć zakres przepisywania. Na przykład mieliśmy w firmie trochę starszego oprogramowania napisanego w C ++ z myślą o programistach C, którzy nie wiedzieli o modułowości. Efektem końcowym był kod speghetti w postaci skończonej maszyny stanów, która obejmowała wiele klas i bibliotek DLL. Mieliśmy nowy wymóg, który bardzo różnił się od założeń wbudowanych w kod i miał stanowić część opatentowanej przez firmę wartości dodanej dla jej klientów.

Po spędzeniu czasu z kodem na implementacji innych funkcji, miałem naprawdę dobry pomysł, ile czasu zajmie ustalenie, które z kilku instrukcji switch muszę zmienić itp. Moją propozycją było przepisanie sekcji kodu, która była ogromna skończona maszyna stanów - powinno to zająć mi mniej czasu niż rozszerzenie istniejącego kodu. Udało mi się skonsolidować w jedną bibliotekę DLL, która kiedyś była trzy, i zapewnić znacznie bardziej zorientowaną obiektowo strukturę, która znacznie ułatwiłaby wykonanie nowej, krytycznej funkcjonalności wraz z ułatwieniem dodania nowej funkcjonalności.

Były też trzy inne aplikacje korzystające z bibliotek, które wymagały przepisania, więc nie chciałem całkowicie przepisywać tych programów. Zakres był ograniczony do biblioteki i tego, co było konieczne do powiązania biblioteki z istniejącym oprogramowaniem. Moje prognozy nie były daleko, a praca się zwróciła. Wkrótce po przeprojektowaniu miałem za zadanie dodać nową funkcję. To, co zajęłoby mi tydzień ze starą konstrukcją, zajęło mi tylko dzień z nową konstrukcją.

Berin Loritsch
źródło
0

OP nie wskazuje zakresu projektu, ale główną wskazówką, którą podjąłem, było „napisane w starym [języku / dialekcie] przy użyciu starych [libs]”, które według mnie są głównymi sterownikami przepisywania. W rzeczywistości większość projektów, na których prowadziłem znaczącą długowieczność rynku, w końcu zdaje sobie sprawę, że dostosowanie aktualizacji do kompilatorów / interpretatorów / systemów operacyjnych jest ważnym zadaniem w utrzymaniu bazy kodu.

Krótko mówiąc, planowałbym ponowne pisanie etapami, najpierw nadając priorytet aktualizacji w libs. Być może po drodze możesz się zakraść w innych optymalizacjach, ale fakt, że planujesz odroczyć niektóre zmiany w późniejszej fazie, może być świetnym sposobem na dotrzymanie harmonogramu i uniknięcie „utknięcia”.

MarkHu
źródło
0

Cóż, mogę sobie wyobrazić hipotetyczne scenariusze, w których mógłbym po prostu wyrzucić istniejącą bazę kodu (hipotetyczne sytuacje, w których kulki mają zerową wagę i objętość, gdzie nikogo to nie obchodzi, jeśli stracimy tygodnie lub miesiące produktywności, starając się dodać przeoczone funkcje i błąd poprawki w systemie, a gdy system jest tak trywialny i nienawidzony przez organizację, że mogę zastąpić całą rzecz i armię serwerów notatnikiem ++ i netbookiem w ciągu dziesięciu minut, a także zwiększyć produktywność i moralność wszystkich.)

Jednak w przypadku prawie każdego scenariusza z prawdziwego świata po prostu polecam refaktoryzację na miejscu. ^ _ ^. Zwykle pojawia się zbyt wiele ukrytych, nieprzewidzianych kosztów, aby przepisać, gdy pojawiają się nieudokumentowane wymagania prawne i biznesowe, a ostatnia minuta wspólnego hakowania rzeczy w ostatniej chwili zaczyna się pojawiać.

== Refaktoryzacja na miejscu dla większego dobra i rzeczy ==

Refaktoryzacja starszego kodu za pomocą zwykłego starego podejścia przyrostowego,

  1. Jeśli masz szansę przekonwertować na UML i udokumentować, jaka jest mała knarly architektura.
  2. Jeśli korzystasz z kontroli wersji, sprawdź generowanie raportów rezygnacji z kodu i dowiedz się, które pliki i sekcje plików były najczęściej zmieniane. Zanotuj je, ponieważ prawdopodobnie będą to obszary, z którymi najpierw będziesz chciał się uporać.
  3. Przed zmianą kodu zawsze staraj się dodać trochę pokrycia testowego (wystarczą nawet brzydkie testy funkcjonalne pełnego stosu). Jeśli masz do czynienia z dużą niechlujną logiką ekstrakcji kodu proceduralnego, zamierzasz zmienić się na jakąś rozsądnie nazwaną metodę lub funkcję i, jeśli to możliwe, dodaj kilka przypadków testowych, które zweryfikują twoją nową metodę. zrób okropnego boga, którego musisz, i jeśli to możliwe, sparaliżuj zmianę, jeśli jest to coś często modyfikowanego, np. szerokość marginesu lub tytuł, więc następnym razem będzie trochę łatwiej.
  4. Użyj wzorca adaptera i pracuj nad ukrywaniem fragmentów starszego kodu pod dywanem logicznie nazwanych klas i metod, aby w przypadku najczęściej wykonywanych zadań Ty i inni programiści nie musieliście się martwić o przerażające fragmenty za tymi małymi, czystymi, czystymi metodami i klasami, które ukryłeś za tym starszym kodem - jak te miłe rodziny, które trzymają zdeformowanych morderczych byłych członków rodziny zombie w stodołach, aby nie zepsuły codziennych zajęć gospodarstwo rolne . . . normalnie
  5. W miarę usuwania i usuwania fragmentów kodu nadal zwiększasz zasięg testu. Teraz możesz kopać jeszcze głębiej i „przepisywać” jeszcze więcej kodu, gdy jest to potrzebne / pożądane z coraz większą pewnością.
  6. Powtórz lub zastosuj dodatkowe metody refaktoryzacji, aby nadal ulepszać bazę kodu.

Rozgałęzienie według abstrakcji

  1. Zdefiniuj miejsce problemu w kodzie, który chcesz usunąć (warstwa trwałości, generator pdf, mechanizm liczenia faktur, generator widżetów itp.).
  2. uruchom (napisz, jeśli to konieczne) niektóre przypadki testów funkcjonalnych (automatyczne lub ręczne, ale wiesz, że zautomatyzowane) w stosunku do bazy kodu, która kieruje tę funkcjonalność wraz z ogólnym zachowaniem.
  3. Wyodrębnij logikę związaną z tym komponentem z istniejącej bazy źródłowej do klasy z pewnym rozsądnym interfejsem.
  4. Sprawdź, czy cały kod używa teraz nowego interfejsu do wykonywania działania X, które wcześniej było losowo rozproszone w całym kodzie (Grep baza kodu, dodaj ślad do nowej klasy i sprawdź strony, które powinny ją wywoływać itp.), I że możesz kontrolować, która implementacja będzie używana, modyfikując pojedynczy plik. (rejestr obiektów, klasa fabryczna, cokolwiek IActivityXClass = Ustawienia.AcitivtyXImplementer ();)
  5. uruchom ponownie funkcjonalne przypadki testowe, które sprawdzą, czy wszystko nadal działa z całym wprowadzeniem Activity X do nowej klasy.
  6. W miarę możliwości napisz testy jednostkowe wokół nowej klasy opakowania X działania.
  7. wdrożyć nową klasę o mniej szalonej logice spaghetti niż starsza implementacja, która jest zgodna z tym samym interfejsem co starsza klasa.
  8. sprawdź, czy nowa klasa przeszła testy jednostkowe napisane dla starszych klas.
  9. zaktualizuj swój kod, zmieniając rejestr / factorymethod / cokolwiek, aby użyć nowej klasy zamiast starej.
  10. sprawdź, czy testy funkcjonalne nadal przebiegają pomyślnie.

Otwarta zasada zamknięta i wspólna warstwa logiki biznesowej / trwałości

Do pewnego stopnia możesz nie być w stanie oddzielić warstwy prezentacji, biznesu i trwałości oraz napisać nową aplikację, która jest w pełni kompatybilna wstecz ze starszym rozwiązaniem, lub przynajmniej może obsługiwać dane wprowadzone przez starsze rozwiązanie. Prawdopodobnie nie zaleciłbym tego podejścia, ale czasami jest to rozsądny kompromis czasu / harmonogramu / zasobów / wymaganej nowej funkcjonalności.

  • Co najmniej oddziel warstwę prezentacji od warstwy biznesowej i trwałej.
  • zaimplementuj nowy interfejs użytkownika i lepszą warstwę prezentacji, która korzysta z tej samej wspólnej warstwy biznesowej i trwałej.
  • Sprawdź, czy dane utworzone za pomocą nowego interfejsu użytkownika nie psują starego interfejsu użytkownika. (będziesz w gorącej wodzie, jeśli użytkownicy nowego narzędzia przerywają użytkownikom starego narzędzia). Jeśli dążysz do pełnej kompatybilności wstecznej, powinieneś zapisywać wszystko na tych samych warstwach trwałości. Jeśli chcesz tylko kompatybilność do przodu w nowym narzędziu, skorzystaj z nowej bazy danych i nowych tabel lub tabel rozszerzeń, aby śledzić dane spoza starszego systemu.
  • Do nowej funkcjonalności i trwałości warstwa musi dodać nowe tabele, a metody nie zmieniają istniejącej logiki, ani nie dodają kolumn, ograniczeń do istniejących tabel. np. jeśli chcesz rozpocząć śledzenie kontaktu awaryjnego z pracodawcą, a niektóre inne pola nie modyfikują istniejącej tabeli pracowników (nie mamy pojęcia, jakie założenia przyjmują starsze dane na temat tej tabeli), dodaj tabelę rozszerzeń identyfikator_użytkownika, identyfikator_użytkownika, identyfikator_ataktu_atakowego, etc_id.
  • Powoli migruj użytkowników do nowego systemu. jeśli to możliwe, przełącz starszy system w tryb tylko do odczytu lub po prostu dodaj ostrzeżenie informujące użytkowników, że nie będzie już dostępny po dacie X.
  • zaimplementuj w nowym interfejsie wszelkie pominięte funkcjonalności lub wymagania biznesowe o wysokim priorytecie
  • najedź bazą użytkowników.
  • kontynuować oczyszczanie logiki biznesowej i użytkowników warstwy trwałości za pomocą innych metod refaktoryzacji.
Keith przynosi
źródło
0

Powiedziałbym, że jest trzecia kategoria w przestrzeni Refactor vs. Rewrite ... A to aktualizuje twoje wersje językowe, kompilatory i biblioteki ... Czasami po prostu zastosowanie nowoczesnych technik kodowania ma wielką zaletę.

Weźmy na przykład C #, kod v7 pisze o wiele czystsze, bezpieczniejsze i bardziej zwięzłe niż v2 .. Rzeczy takie jak Elvis i operator koalescencji zerowej pomagają tonować.

Przełączanie kompilatorów może także tchnąć nowe życie w starszy kod. Podobnie mogą być nowe biblioteki, które mogą ułatwić pracę i wdrożenie ... Sieć jest doskonałym przykładem spektrum trudności związanych z implementacją.

Wbudowane systemy Linux ... Pomyśl o instalacji nowych narzędzi - przełącz się na git z svn. lub dodaj Vi do swojego systemu itp.

Nie zawsze musi to być refaktoryzacja kontra przepisywanie .. Twoja architektura prawdopodobnie wymaga ulepszeń, ale działa ... może po prostu musisz pomyśleć o tym, jak napisany jest kod itp.

lepkość
źródło
-2

Nie sądzę, że kiedykolwiek widziałem ludzi przepisujących starszą aplikację.

To, co się dzieje, polega na tym, że ludzie piszą zupełnie nowe aplikacje o innej architekturze, technologiach itp., Które mają pewne cechy wspólne z poprzednią generacją. Nazywa się to app 2.0, ale w rzeczywistości ma niewiele wspólnego z oryginałem.

Ale tak naprawdę nie jest to „przepisywanie” oryginału w tym sensie, że próbujesz osiągnąć parzystość funkcji.

Xavier T.
źródło