W książce The Pragmatic Programmer pisarze wspominają o programowaniu przez przypadek . Wyjaśnia, co to jest, dlaczego jest spowodowany, jakie niebezpieczeństwa możesz napotkać, i porównuje to z polem minowym podczas wojny.
Czy oglądasz kiedyś czarno-białe filmy wojenne? Zmęczony żołnierz ostrożnie wysuwa się z zarośli. Przed nami polana: czy są jakieś miny, czy można bezpiecznie przejść? Nic nie wskazuje na to, że jest to pole minowe - żadnych znaków, drutu kolczastego ani kraterów. Żołnierz szturcha go bagnetem ziemi i krzywi się, oczekując eksplozji. Nie ma jednego Tak więc przez chwilę ostrożnie przechodzi przez pole, szturchając i szturchając go. W końcu, przekonany, że pole jest bezpieczne, prostuje się i maszeruje dumnie do przodu, by zostać roztrzaskanym na strzępy.
Początkowe sondy żołnierza do wykopalisk nic nie ujawniły, ale było to po prostu szczęście. Doprowadzono go do fałszywego wniosku - z katastrofalnymi skutkami.
Jako programiści pracujemy również na polach minowych. Każdego dnia czekają na nas setki pułapek. Pamiętając opowieść o żołnierzu, powinniśmy uważać na wyciąganie fałszywych wniosków. Powinniśmy unikać programowania przez przypadek - polegając na szczęściu i przypadkowych sukcesach - na rzecz programowania celowo ...
Ale nie jestem bardzo zadowolony ze sposobu, w jaki opisują kwestię „jak to przezwyciężyć”. Tak, musisz pomyśleć przed napisaniem kodu, ale jak to ćwiczyć? Jedyne, co mogę myśleć, to dodanie funkcji do istniejących projektów Open Source, w których musisz mieć wiedzę zarówno na temat „tego, co robię teraz”, jak i „jak działają inne fragmenty kodu”, i nie ma to zastosowania kiedy piszesz własne projekty.
EDYTOWAĆ:
streszczenie z twoich postów:
- Nie zgaduj następnego ruchu, udowodnij, że jest poprawny
- W razie potrzeby test jednostkowy i refaktoryzacja w miarę możliwości
- Często dodawaj funkcje - kompiluj - testuj
- Jeśli nie potrafisz wyjaśnić kodu noobowi, prawdopodobnie programujesz przez przypadek.
BTW, trudno jest zaakceptować odpowiedź, to naprawdę trudne. Wszystkie odpowiedzi są naprawdę świetne :)
źródło
Odpowiedzi:
Nie musisz myśleć z wyprzedzeniem, po prostu bądź bardzo jasny na temat tego, co zostało zrobione, i bądź bardzo jasny na temat tego, co robisz teraz.
Podprogramy powinny mówić, co robią, robić to, co mówią i nie mieć ukrytych zależności. Wtedy ktoś, kto do nich zadzwoni, może łatwiej zrozumieć, co zrobi.
Unikaj stanu globalnego. (Zmienne, singletony itp.) Im więcej musisz mieć w głowie, aby zrozumieć, co się dzieje, tym trudniej jest zrozumieć, co się stanie i znaleźć przypadki skrajne.
Napisz testy jednostkowe. Testy jednostkowe świetnie nadają się do przechwytywania rzeczywistego zachowania właśnie napisanego kodu, a nie do idealnego zachowania, które chcesz znaleźć.
Skróć cykl edycji / kompilacji / testu. Gdy dodasz dużą część kodu i źle przetestujesz, istnieje prawdopodobieństwo, że będzie on zachowywać się inaczej niż myślisz. Następnie „naprawiasz” go losową zmianą i na chwilę masz właściwą odpowiedź, ale nie masz pojęcia, jak to się naprawdę stało. Programujesz teraz przez przypadek. Ale gdy dodasz 5 wierszy, a następnie przetestujesz, szanse na poprawną odpowiedź, ponieważ działa tak, jak myślisz, są lepsze. Mogę powiedzieć z doświadczenia, że 5 fragmentów po 10 linii każdy, indywidualnie testowanych, to zupełnie inna bestia niż 50 linii kodu testowanych jednocześnie.
Refaktoryzujcie bezwzględnie. Wiele razy zauważyłem refaktor, który sprawi, że mój kod będzie nieco prostszy, ale zajmie się pracą, której nie chciałem wykonywać. Po tym, jak zacząłem celowo zajmować się tymi refaktorami w pierwszej kolejności, przekonałem się, że zazwyczaj zwraca się ono w ciągu miesiąca. Zwróć jednak uwagę na klucz. Refaktory, na których się skupiam, to takie, które upraszczają codzienne życie, a nie takie, które spełniają dowolną estetykę lepszej lub bardziej ogólnej. Te refaktory, na których nauczyłem się być znacznie ostrożniejszym.
Żadna z tych rzeczy nie wymaga wcześniejszego planowania. Ale wszystkie ułatwiają zrozumienie istniejącego kodu, a tym samym ułatwiają celową implementację następnego małego fragmentu.
źródło
UNION
tam, gdzie potrzebowałemUNION ALL
.) I tak dalej.Sprowadza się to prawie do zgadywania . Robią to głównie nowi programiści, ale widziałem też weteranów, ponieważ myślą, że to oszczędza czas na badania. Coś nie działa, więc dodajesz a
+1
lub a-1
, zmieniasztrue
na afalse
lub odwrotnie, porządkujesz niektóre instrukcje, dodajesz lub zmieniasz opóźnienia, zmieniasz priorytety wątków i inne małe transformacje, w zasadzie testując losowe permutacje, aż to zadziała.Dotyczy to głównie zmiany istniejącego kodu, ale jest również czynnikiem w nowym kodzie, ponieważ nikt tak naprawdę nie zaczyna od zera. Zawsze opierasz się na standardowych bibliotekach, systemach operacyjnych lub przynajmniej architekturze procesorów.
Innymi słowy, nie skończysz, dopóki nie dowiesz się, dlaczego poprawka działa. Droga, którą podążasz, aby tam dotrzeć, nie ma tak wielkiego znaczenia. Nawet przypadkowe permutacje mogą czasem być pomocne w zawężeniu błędu, który jest trudny do zdiagnozowania, pod warunkiem, że poświęcisz trochę czasu, by zadać sobie pytanie: „Dobra, zmieniając wartość true na false, naprawiłem to, ale dlaczego?”
źródło
Najbardziej przerażającym komentarzem, jaki kiedykolwiek spotkałem w programie, był
i to jest przerażające tylko dlatego, że przyznaje, że fragment kodu był wynikiem programowania przez przypadek .
Aby uniknąć programowania przez przypadek, powinieneś być w stanie wyjaśnić (współpracownikowi, tobie lub gumowej kaczce ) dokładnie, co robi kod i dlaczego działa. Punktory do celowego programowania są głównie pomocą w dążeniu do celu, jakim jest możliwość wyjaśnienia kodu.
1 W przypadku kontekstu ten komentarz pojawił się w kodzie, który obsługuje przełączniki kontekstu w prymitywnym systemie operacyjnym. Kod był już produkowany przez kilka lat, kiedy go spotkałem.
źródło
Dla nowych programistów najważniejszą częścią przezwyciężenia tego jest prawdziwe zrozumienie tego, co robią.
W wielu obszarach, gdy nie wiesz, jak coś zrobić, po prostu przechodzisz próbę i błąd. Spróbuj czegoś; jeśli to działa, świetnie, jeśli nie, spróbuj czegoś innego.
W programowaniu, szczególnie przy użyciu języka, który ma pojęcie niezdefiniowanego zachowania (takiego jak C lub C ++), to podejście po prostu nie działa, ponieważ sukces nie jest już decyzją typu boolean. Możesz mieć rzeczy, które „w pewnym sensie” działają, które czasami działają, które działają dla niektórych danych wejściowych, ale nie dla innych.
Czasami szkoliłem nowych programistów, a tendencja do pisania losowych rzeczy, aby sprawdzić, czy to działa, jest powszechna. Wpisują wiersz, a następnie zwracają się do mnie i pytają: „Czy to działałoby w ten sposób?” podczas gdy było jasne, że nie mieli absolutnie pojęcia, czy to możliwe.
Na wynos jest to, że jako nowy programista naprawdę musisz być w stanie wyjaśnić, co robi Twój kod. Musisz nauczyć się czytać kod, a nie tylko pisać.
(Oczywiście dotyczy to również doświadczonych programistów, ale moje doświadczenie tutaj dotyczy głównie nowych kompletnych początkujących).
źródło
Zbyt łatwo jest kodować, testować i naprawiać „na linii wyścigowej”. Masz jakąś funkcjonalność, która dała X i Y, tworzy Z. Ale co, jeśli X jest uszkodzony, a Y jest niedostępny? Co jeśli nie możesz wyprowadzić Z? Zawsze pamiętaj o tym, co może pójść nie tak, i zanotuj to w cyklu testowym.
Rób krótkie i opisowe procedury - najlepszy kod wymaga niewielu (jeśli w ogóle) komentarzy.
Znaczące nazwy metod, klas i zmiennych znacznie ułatwiają czytelność.
Jeśli natrafisz na zapach kodu, zatrzymaj się. Ten zapach raczej nie zniknie, a odrobina wysiłku może teraz zaoszczędzić Ci ogromnej ilości żalu.
Uwzględnij testy w swoim procesie rozwoju. Byłbym zwolennikiem używania BDD zamiast TDD, ponieważ zmusza cię to do opisania tego, co chcesz osiągnąć, zamiast ślepo polegać na szeregu testów, które mogłyby dać fałszywe poczucie bezpieczeństwa.
Oprzyj się pokusie dodania dodatkowych fajnych funkcji (chyba że jest to twój własny projekt dla zwierząt). Każdy dodatkowy kod musi być zaprojektowany, napisany, przetestowany i utrzymany. Jeśli nie jest to wymagane przez klienta / firmę - ryzykujesz, że stanie się to ogromnym obciążeniem zasobów.
źródło