Jak powszechne są poprawki „bandaż”? [Zamknięte]

18

Wyobraź sobie następujący scenariusz:

Wykryłeś, że w twoim (lub czyimś programie) jest błąd - funkcja daje nieprawidłowy wynik po podaniu określonego wejścia. Sprawdzasz kod i nie możesz znaleźć niczego złego: wydaje się, że po prostu wpada w błoto, gdy otrzyma te dane wejściowe.

Możesz teraz zrobić jedną z dwóch rzeczy: albo dalej analizujesz kod, aż znajdziesz właściwą przyczynę; lub policzkujesz bandaż, dodając ifinstrukcję sprawdzającą, czy dane wejściowe są konkretnymi danymi wejściowymi - jeśli tak, zwróć oczekiwaną wartość.

Dla mnie stosowanie bandaża byłoby całkowicie niedopuszczalne. Jeśli kod zachowuje się nieoczekiwanie na tym wejściu, na jakie inne pominięte wejście zareaguje dziwnie? To po prostu nie wydaje się rozwiązaniem - po prostu odsuwasz problem pod dywan.

Ponieważ nawet nie zastanawiałbym się nad tym, jestem zaskoczony, jak często profesorowie i książki przypominają nam, że stosowanie poprawek „bandaż” nie jest dobrym pomysłem. Zastanawiam się więc: jak często występują tego rodzaju „poprawki”?

gablin
źródło

Odpowiedzi:

19

Presja czasu / terminu jest jednym z powodów.

Jeśli zbliża się napięty termin i szef oddycha w dół szyi (być może dosłownie!), To robienie tego i myślenie „wrócę i naprawię to później” jest bardzo kuszące i może być jedyną rzeczą, którą możesz mogę zrobić.

Oczywiście, ile razy faktycznie wracasz i naprawiasz to poprawnie, jest ich bardzo niewiele, ponieważ masz nowy problem, który wymaga naprawy wczoraj.

ChrisF
źródło
10

O ile my, programiści, nie lubimy się do tego przyznawać, pięknie zakodowane oprogramowanie nie zawsze przekłada się na większą wartość dla firmy lub klientów. Jest to podwójnie prawdziwe w przypadku katastrofy, na przykład oprogramowanie podwójnie ładuje karty kredytowe ludzi. Czasami, podobnie jak bandaż, wystarczy zatrzymać krwawienie wszelkimi niezbędnymi środkami i obiecać powrót po ustabilizowaniu się pacjenta i naprawienie podstawowego problemu.

Sztuczka polega na tym, że gdy nie ma już potrzeby, naprawdę trudno jest przekonać kogokolwiek, aby priorytetowo potraktował zastąpienie bandaża prawdziwą poprawką. Zwłaszcza biorąc pod uwagę, że za pierwszym zawsze czeka kolejna pilna sprawa. Musisz tylko zachować czujność, aby pozostać przy problemie wykraczającym poza szybkie rozwiązanie.

JohnFx
źródło
Och, takie prawdziwe, takie bardzo prawdziwe. Założyłem więcej bandaży, niż mi się wydaje, i większość z nich nie została później naprawiona.
Corin,
Czasami ostateczne wydanie kodu zawiera więcej bandaży niż faktyczna poprawka. Nawet niektórzy programiści zaczęli kopiować bandaże w innych projektach.
Prasham,
7

Czas

Jest moim zdaniem powodem nr 1. Chociaż jeśli problem jest uzasadniony, może zająć więcej czasu, aby go zbadać. Często moje poprawki „bandażowania” obejmują poprawki CSS lub interfejsu użytkownika. Napisałem trochę nieprzyjemnych wbudowanych CSS i JavaScript, aby szybko sobie z nimi poradzić. Wracając i naprawiając to zawsze jest opcja, jeśli masz czas.

Josh K.
źródło
Wczoraj (niedziela. NIGDY nie pracuję w niedzielę, co powinno powiedzieć o tym, jaki tydzień mam tutaj do czynienia). Napisałem wyrażenie regularne, aby zamienić ciąg „NaN” na „0” w instrukcji SQL tuż przed jej otrzymaniem przesłane do serwera. Nie wiem, dlaczego w tym momencie jest to NaN i jestem zainteresowany, ale po prostu nie mam czasu, aby go wytropić.
Dan Ray
5

Robimy je wyjątkowo.


W przypadku poprawek podczas programowania upewniamy się, że nie zostanie wykonana żadna poprawka bez znajomości podstawowej przyczyny. Jednak:

  • Wyjątkowo poszukiwanie pierwotnej przyczyny zacznie trwać zbyt długo lub przeciągnie się ORAZ jest trudny termin,
  • Wyjątkowo zmiany kodu mające na celu usunięcie pierwotnej przyczyny są taktycznie niewykonalne (zmiana potrwa zbyt długo, a termin zbliża się)

W takich przypadkach wybieramy poprawki „bandażujące”. Następnie otwieramy defekty wewnętrzne, aby rozwiązać pierwotną przyczynę. Tak, najczęściej te wady wewnętrzne są traktowane z bardzo niskim priorytetem.


W przypadku poprawek w strumieniu konserwacji upewniamy się, że żadna poprawka nie zostanie wykonana bez znajomości podstawowej przyczyny. Jednak:

  • Bardzo wyjątkowo poszukiwanie pierwotnej przyczyny utknie w martwym punkcie,
  • Wyjątkowo może się zdarzyć, że ustalenie pierwotnej przyczyny jest taktycznie niewykonalne (zmiana nie jest trywialna, a klient potrzebował poprawki wczoraj).

W takich przypadkach wybieramy najpierw tymczasową „bandaż”, a gdy klient jest zadowolony, pracujemy nad poprawką, a dopiero potem wada zostaje usunięta.

finrod
źródło
4

Ujednoznacznienie.

  • Biorąc pod uwagę konkretny błąd, istnieje znaczna trudność w obiektywnym zdefiniowaniu, czy dana poprawka jest „bandażem”, ponieważ: „prawidłowe rozwiązanie” może być „bandażem” innej osoby.
  • Używam więc następującej definicji: naprawić defekt w sposób mniej elegancki i mniej dobrze przestudiowany, niż chciałbym zrobić to profesjonalnie.

Po pierwsze, jeśli chodzi o częstotliwość poprawek „bandaż”:

  • Nowy kod: prawie żaden.
  • Stary kod:
    • Znajdziesz kilka, choć są one zazwyczaj napisane na tyle elegancko (patrz „łagodzenie danych” poniżej) , że nie wyglądają jak bandaże i przetrwają wszystkie recenzje kodu.
    • Zwróć także uwagę na „niewidzialny bandaż”: po prostu nie wywoływaj tej funkcji. Przy braku kodu nie ma nawet śladu wskazującego na istnienie błędu.
  • Stary kod z wieloma zewnętrznymi zależnościami:
    • Prawie pełny.
    • Prawie zawsze było napisane dla przestarzałej wersji zależności i nikt tak naprawdę nie przeczytał „informacji o wydaniu” zależności przed zaktualizowaniem zależności do nowej wersji.

Po drugie, moja rada:

Jeśli błąd wystąpi we własnym kodzie źródłowym zespołu programistów:

  • Napraw to w profesjonalny sposób. (Jeśli to naprawisz, jesteś właścicielem).
  • Pod presją czasu rób wszystko, co możesz - co wymaga:
    • Spójrz na potencjalny wpływ na użytkownika końcowego: samego błędu i proponowanej poprawki, aby zdecydować, czy zaakceptować poprawkę.
    • Analizuj powiązane fragmenty kodu (korzystając z informacji historycznych z narzędzia do zarządzania kodem źródłowym) i dyskutuj ze współpracownikami (ale nie zajmuj zbyt wiele czasu), dopóki nie zrozumiesz dobrze problemu i rozwiązania.
  • Zawsze śledzić błąd za pomocą systemu śledzenia defektów .

Jeśli błąd występuje w kodzie źródłowym innego zespołu:

  • Popchnij ten zespół, aby naprawić błąd.
  • Zawsze zgłaszaj ten błąd do systemu śledzenia wad drugiego zespołu .

Jeśli błąd wystąpi w produkcie innej firmy (lub żadnej firmy):

  • W takim przypadku poprawki taśmy izolacyjnej (lub obejścia oparte na danych ) mogą być jedynym sposobem naprawienia błędu.
  • Jeśli jest to oprogramowanie typu open source, i tak napisz ten błąd do jakiegoś (prawdopodobnie publicznego) systemu śledzenia defektów , aby ktoś mógł go obejrzeć.
rwong
źródło
2

Myślę, że wiele zależy od wieku bazy kodu. W starym kodzie myślę, że jest to bardzo powszechne, przepisywanie, że 20-letnia procedura COBOL nie jest zabawna. Nawet przy umiarkowanie nowym kodzie, który jest produkowany, wciąż jest dość powszechny.

Craig
źródło
2

Powiedziałbym, że to bardzo powszechne.

Sprawdź wpis na blogu Joela Spolsky'ego: The Duct Tape Programmer

Mogę z łatwością powiedzieć, że prawie w każdym projekcie, w którym kiedykolwiek byłem, musiałem zastosować jakiś bandaż lub taśmę klejącą, aby dotrzymać terminów i wykonać zadanie. Nie jest ładny, nie jest czysty, ale wykonuje zadanie, dzięki czemu firma może kontynuować działalność, a projekt może w jakiś sposób iść do przodu.

Istnieje różnica między światem akademickim a światem rzeczywistym, w którym oprogramowanie musi być dostarczane z opóźnieniem i ograniczeniami biznesowymi.

W pewnym sensie kładzie go pod dywanikiem, aby odłożyć poprawkę, do, miejmy nadzieję, później. Niestety zbyt często odroczona poprawka nigdy się nie zdarza i kod ten trafia do produkcji.

gąbka
źródło
1

Trudno powiedzieć bez większego kontekstu - dlaczego w twoim przykładzie dodanie instrukcji if nie jest poprawną poprawką? Czy to dlatego, że podobno jest tam gdzieś inny blok kodu, który powinien zajmować się tymi danymi wejściowymi?

To, jak często stosowane są poprawki bandażowe, zależy od wielu czynników, takich jak złożoność kodu, dostępność osoby najbardziej obeznanej z kodem (osoba odpowiedzialna za 20-letnią procedurę COBOL firmy Craig mogła opuścić firmę lata temu ) i związane z tym ramy czasowe.

Z terminem wpatrującym się w twoją twarz, czasami będziesz dążyć do bezpieczniejszego rozwiązania, nawet jeśli po prostu klepie tynk, a nie naprawia pierwotną przyczynę. Jest to w porządku, o ile nie pogorszysz sytuacji, ale ważne jest, aby śledzić fakt, że nadal nie jest poprawny i nadal musi zostać poprawnie naprawiony.

JohnL
źródło
ifOświadczenie nie jest poprawna, ponieważ funkcja podwładnym jeśli wadliwy.
Josh K
To może być prawda, ale nie zostało to pokazane w OP - wszystkie gablin powiedział, że funkcja zwraca niepoprawny wynik na podstawie danych wejściowych. Jeśli funkcja ma po prostu podjąć decyzję (np. W jakim trybie ma działać aplikacja), być może problemem był brak instrukcji if. Jeśli funkcja ma przetwarzać wartość (nie wybierając z dyskretnego zestawu opcji), prawdopodobnie masz rację. Nie wiedząc więcej na temat funkcji i jej zastosowania, nie można powiedzieć.
JohnL,
1

Są przypadki, w których taka poprawka jest naprawdę OK i prawdopodobnie idealna (jeśli chodzi o czas potrzebny na debugowanie).

Wyobraź sobie scenariusz, w którym masz 20 bibliotek DLL, które mają działać jako moduły dla głównego pliku wykonywalnego, ale wymagają także pewnych informacji z głównego pliku wykonywalnego.

Jeśli kiedykolwiek będziesz chciał użyć tych bibliotek DLL poza głównym plikiem wykonywalnym, będziesz musiał sfałszować niektóre zwracane wartości z głównego pliku wykonywalnego, ponieważ. A.) Nie istnieje w tym kontekście i B.) Nie chcesz, aby istniał w tym kontekście.

To powiedziawszy, lepiej umieść w swoim kodzie kilka dyrektyw kompilatora, aby upewnić się, że używasz zupełnie innego kodu, gdy fałszujesz wyniki, a kiedy osiągasz prawdziwe wyniki.

Zamiast ifwstawiać funkcję kogoś innego, umieściłem ją {$ifdef}wokół - w ten sposób nikt nie pomyli jej z czymś, co powinno tam być.

Peter Turner
źródło