Nauczyłem się znacznej ilości kodowania, jednak zawsze odbywało się to w środowisku naukowym (nie w informatyce), całkowicie samoukiem bez nikogo, kto poprowadziłby mnie we właściwym kierunku. Tak więc moja podróż do kodowania była ... niechlujna. Zauważyłem teraz, że za każdym razem, gdy buduję jakiś program, do końca zdaję sobie sprawę, jak mogłem to zrobić o wiele bardziej elegancko, o wiele bardziej wydajnie oraz w sposób, który jest o wiele bardziej elastyczny i łatwy w zarządzaniu. W niektórych okolicznościach faktycznie wróciłem i odbudowałem wszystko od podstaw, ale zwykle nie jest to praktycznie możliwe. Chociaż większość moich programów była do tej pory stosunkowo niewielka, zupełnie nieporęczne jest przepisywanie dużych programów za każdym razem, gdy coś tworzysz.
Zastanawiam się tylko, czy to normalne doświadczenie? Jeśli nie, w jaki sposób temu zapobiec? Próbowałem planować z wyprzedzeniem, ale nie mogę przewidzieć wszystkiego, dopóki nie zacznę opracowywać kodu.
Odpowiedzi:
To uczucie jest całkowicie normalne i oczekiwane. Oznacza to, że się uczysz. Niemal za każdym razem, gdy zaczynam nowy projekt, zaczynam w jednym kierunku, a na końcu projektuję go inaczej.
Powszechną praktyką jest najpierw opracowanie prototypu, zanim zacznie się od rzeczy. Powszechne jest także ponowne odwiedzanie starego kodu i refaktoryzacja go. Jest to łatwiejsze, jeśli Twój projekt ma budowę modułową - możesz łatwo przeprojektować fragmenty i elementy jednocześnie, bez konieczności całkowitego wyrzucania starego projektu.
Dla niektórych osób pomaga najpierw napisać pseudo-kod . Inni uważają, że warto zacząć od napisania komentarzy opisujących, co zrobi kod, a następnie napisz kod, gdy tylko pojawi się ogólna struktura. Te dwie rzeczy pomogą ci lepiej zaplanować swój projekt i mogą uniknąć konieczności przepisywania.
Jeśli należysz do zespołu, proces przeglądu ma kluczowe znaczenie dla procesu projektowania. Poproś kogoś o sprawdzenie Twojego kodu, abyś mógł dowiedzieć się, jak ulepszyć swój projekt.
źródło
To bardzo częste doświadczenie
Większość ludzi, z którymi mam kontakt, i ja również tak się czuję. Z tego, co mogę powiedzieć, jednym z powodów jest to, że dowiadujesz się więcej o domenie i narzędziach, z których korzystasz podczas pisania kodu, co prowadzi do rozpoznania wielu możliwości ulepszenia już po napisaniu programu.
Innym powodem jest to, że możesz mieć pomysł na idealne rozwiązanie dla czystego kodu, a potem przeszkadza ci świat rzeczywisty i jego bałaganiarskie ograniczenia, zmuszając cię do pisania niedoskonałych obejść i włamań, które mogą cię rozczarować.
„Każdy ma plan, dopóki nie zostanie uderzony w twarz”.
Co z tym zrobić
W pewnym stopniu będziesz musiał nauczyć się akceptować, że Twój kod nigdy nie będzie idealny. Jedną z rzeczy, które mi w tym pomogły, jest sposób myślenia „Jeśli nienawidzę kodu, który napisałem miesiąc temu, oznacza to, że nauczyłem się i zostałem lepszym programistą”.
Sposobem na rozwiązanie tego problemu jest ciągłe poszukiwanie potencjalnych ulepszeń w trakcie pracy i ciągłej korekty. Upewnij się, że osiągniesz właściwą równowagę między refaktoryzacją a dodawaniem nowych funkcji / naprawiania błędów. To nie pomoże w dużych problemach projektowych, ale ogólnie pozostawi Ci bardziej dopracowaną bazę kodu, z której możesz być dumny.
źródło
Naucz się refaktoryzacji - sztuka stopniowego ulepszania kodu. Wszyscy uczymy się cały czas, więc bardzo często zdajemy sobie sprawę, że kod, który sam napisałeś, może być napisany w lepszy sposób.
Ale powinieneś być w stanie przekształcić istniejący kod, aby zastosować te ulepszenia bez konieczności rozpoczynania od zera.
źródło
Jeśli masz doskonałe wymagania statyczne i dobrze je rozumiesz i masz czas na szczegółową analizę, masz szansę na wymyślenie dobrego projektu, z którego nadal będziesz zadowolony, kiedy skończysz.
Nawet w tym błogim przypadku możesz nauczyć się nowych funkcji językowych, które pomogłyby w stworzeniu lepszego projektu.
Jednak zwykle nie będziesz miał tyle szczęścia: wymagania będą mniej niż gwiezdne i niekompletne i chociaż myślałeś, że je zrozumiałeś, okazuje się, że istnieją obszary, w których podjąłeś błędne założenia.
Następnie wymagania zmienią się, gdy użytkownicy zobaczą twoje początkowe wyniki. Wtedy coś, czego użytkownicy nie kontrolują, zmieni się, np. Prawo podatkowe.
Wszystko, co możesz zrobić, to zaprojektować, zakładając, że wszystko się zmieni. Przeanalizuj, kiedy możesz, ale zdaj sobie sprawę, że czas i budżet często oznaczają, że twój końcowy produkt nie jest tak elegancki, jak byłby, gdybyś wiedział na początku to, co wiesz teraz.
Z czasem lepiej zrozumiesz otrzymane wymagania i dostrzeżesz, w których częściach twojego projektu prawdopodobnie będzie potrzebna elastyczność, aby wchłonąć zmiany.
W końcu jednak zaakceptuj tę zmianę i zignoruj przekleństwo, które mówi: „Mógłbym to zrobić lepiej”. Bądź dumny i szczęśliwy, że w ogóle dostarczyłeś rozwiązanie.
źródło
Co możesz zrobić, to stworzyć prototyp, który można wyrzucić, zanim zaczniesz robić „prawdziwy” projekt. Szybko i brudno. Następnie, gdy otrzymasz prototyp potwierdzający koncepcję, poznajesz system i jak właściwie to robić.
Ale nie zdziw się, jeśli po N latach wrócisz do tego kodu i pomyślisz „co za bałagan”.
źródło
Pamiętaj o tej mantrze:
Idealne rozwiązanie nie zawsze jest idealnym rozwiązaniem. Idealnym rozwiązaniem jest to, które osiąga status „wystarczająco dobre” z najmniejszą ilością pracy.
Jeśli odpowiesz twierdząco na wszystkie te pytania, oznacza to, że twoje oprogramowanie jest „wystarczająco dobre” i nie ma żadnego dobrego powodu, aby przepisać je od zera. Zamiast tego zastosuj zdobyte lekcje projektowania do następnego projektu.
Jest to zupełnie normalne, że każdy programista ma w przeszłości kilka niechlujnych programów. Zdarzyło mi się kilka razy w trakcie mojej kariery jako programisty, że spojrzałem na jakiś kod, zastanawiałem się „Jaki idiota napisał ten bałagan?”, Sprawdziłem historię wersji i zauważyłem, że to ja sprzed kilku lat.
źródło
Kuszące jest myślenie, że idealne planowanie zapewni doskonałe projektowanie / architekturę oprogramowania, jednak okazuje się, że jest to kategorycznie fałszywe. Są z tym dwa duże problemy. Po pierwsze, „na papierze” i „kod” rzadko się zgadzają, a powodem jest to, że łatwo jest powiedzieć, jak należy to zrobić, a nie w rzeczywistości . Po drugie, nieprzewidziane zmiany wymagań stają się widoczne na późnym etapie procesu projektowania, o których nie można było mówić od samego początku.
Czy słyszałeś o ruchu Agile? Jest to sposób myślenia, w którym cenimy „reagowanie na zmiany”, a nie „przestrzeganie planu” (między innymi). Oto manifest (to szybki odczyt). Możesz także poczytać o Big Design Up Front (BDUF) i o tym, jakie są pułapki.
Niestety, wersja korporacyjna „Agile” jest nieprawdziwa (certyfikowani mistrzowie scrum, ciężki proces w imieniu „Agile”, wymuszanie scrum, wymuszanie 100% pokrycia kodu itp.), I zwykle powoduje zmiany asinine procesu, ponieważ menedżerowie myślę, że Agile to proces i srebrna kula (której nie ma). Przeczytaj zwinny manifest, słuchaj ludzi, którzy rozpoczęli ten ruch, takich jak wujek Bob i Martin Fowler, i nie daj się wciągnąć w nonsensowną wersję „corporate Agile”.
W szczególności zazwyczaj można uciec od zrobienia TDD (Test Driven Development) na kodzie naukowym i istnieje duża szansa, że twój projekt oprogramowania okaże się całkiem cholernie dobry. Wynika to z faktu, że udany kod naukowy ma przeważnie bardzo przydatne interfejsy, a wydajność stanowi drugorzędną (a czasem konkurencyjną) kwestię, dzięki czemu można uzyskać bardziej „chciwy” projekt. TDD zmusza twoje oprogramowanie do ultra-użyteczności , ponieważ piszesz, jak chcesz , aby rzeczy były nazywane (najlepiej) przed ich faktyczną implementacją. Wymusza również małe funkcje za pomocą małych interfejsów, które można szybko wywołać w prosty sposób „wejściowy” / „wyjściowy”, i daje ci dobrą pozycję do refaktoryzacji w przypadku zmiany wymagań.
Myślę, że wszyscy możemy się zgodzić, że
numpy
odnosi sukcesy naukowe oprogramowanie komputerowe. Ich interfejsy są małe, super użyteczne, a wszystko ładnie się gra. Zauważ, żenumpy
przewodnik referencyjny wyraźnie zaleca TDD: https://docs.scipy.org/doc/numpy-1.15.1/reference/testing.html . W przeszłości korzystałem z TDD w oprogramowaniu do obrazowania SAR (radar z syntetyczną aperaturą): mogę również stwierdzić, że działa on wyjątkowo dobrze w tej konkretnej dziedzinie.Zastrzeżenie: Część projektowa TDD działa gorzej w systemach, w których fundamentalne refaktoryzacja (np. Decyzja, że potrzebujesz oprogramowania, aby była wysoce współbieżna) byłaby trudna, jak w systemie rozproszonym. Na przykład, jeśli musiałbyś zaprojektować coś takiego jak Facebook, na którym masz miliony równoczesnych użytkowników, zrobienie TDD (by poprowadzić twój projekt) byłoby błędem (nadal można używać po przygotowaniu wstępnego projektu i po prostu „przetestować pierwszy rozwój” „). Ważne jest, aby pomyśleć o zasobach i strukturze aplikacji przed wskoczeniem do kodu. TDD nigdy nie doprowadzi Cię do wysoce dostępnego, rozproszonego systemu.
Biorąc powyższe pod uwagę, powinno być nieco oczywiste, że idealny projekt jest w rzeczywistości niemożliwy do osiągnięcia, więc pogoń za idealnym projektem jest grą głupców. Naprawdę możesz się tylko zbliżyć. Nawet jeśli uważasz, że możesz przeprojektować od zera, prawdopodobnie nadal istnieją ukryte wymagania, które się nie pokazały. Co więcej, przepisywanie zajmuje przynajmniej tyle czasu, ile zajęło opracowanie oryginalnego kodu. Niemal na pewno nie będzie krótszy, ponieważ jest prawdopodobne, że nowy projekt będzie miał własne nieprzewidziane problemy, a ponadto musisz ponownie wdrożyć wszystkie funkcje starego systemu.
Inną rzeczą do rozważenia jest to, że Twój projekt ma znaczenie tylko wtedy , gdy zmieniają się wymagania .Nie ma znaczenia, jak zły jest projekt, jeśli nic się nigdy nie zmienia (zakładając, że jest w pełni funkcjonalny w obecnych przypadkach użycia). Pracowałem nad linią bazową, która zawierała 22 000 instrukcji przełączania linii (funkcja była jeszcze dłuższa). Czy to był okropny projekt? Cholera, to było okropne. Naprawiliśmy to? Nie. Działało to dobrze, a ta część systemu nigdy tak naprawdę nie powodowała awarii ani błędów. Dotknęło go to tylko raz w ciągu dwóch lat pracy nad projektem, a ktoś, jak się domyślacie, umieścił inną obudowę w przełączniku. Ale nie warto poświęcać czasu na naprawę czegoś, co jest dotykane tak rzadko, że po prostu nie jest. Niech niedoskonały projekt będzie taki, jaki jest, a jeśli nie jest zepsuty (lub ciągle pęka), nie naprawiaj go. Więc może mógłbyś zrobić lepiej ... ale czy warto byłoby przepisać? Co zyskasz
HTH.
źródło
W pełni zgadzam się z odpowiedzią udzieloną przez Andreasa Kammerlohera, ale jestem zaskoczony, że nikt jeszcze nie zasugerował nauki i stosowania najlepszych praktyk kodowania. Oczywiście nie jest to srebrna kula, ale zastosowanie podejścia otwartego, wzorców projektowych, zrozumienia, kiedy pachnie kod i tak dalej, sprawi, że będziesz lepszym programistą. Zbadaj, jakie jest najlepsze wykorzystanie bibliotek, frameworków itp. Na pewno jest o wiele więcej, po prostu drapię się po powierzchni.
Nie oznacza to, że nie będziesz patrzeć na swój stary kod jak na całkowitą śmieci (faktycznie zobaczysz najstarsze programy nawet więcej śmieci niż bez tej wiedzy), ale przy każdym nowym oprogramowaniu zobaczysz poprawiasz się. Zauważ też, że liczba najlepszych praktyk kodowania rośnie z czasem, niektóre po prostu się zmieniają, więc nigdy nie dojdziesz do perfekcji. Zaakceptuj to lub całkiem ścieżkę.
Jeszcze jedną dobrą rzeczą jest rewizja kodu. Kiedy pracujesz sam, łatwo jest skracać rogi. Jeśli druga osoba sprawdza kod, będzie w stanie wskazać, gdzie nie przestrzegasz tych najlepszych praktyk. W ten sposób stworzysz lepszy kod i nauczysz się czegoś.
źródło
Aby dodać do innych doskonałych odpowiedzi tutaj, jedną rzeczą, która uważam za pomocną, jest wiedza, gdzie chcesz się dostać .
Rzadko daje się wyrazić zgodę na samodzielną poważną refaktoryzację. Ale często możesz wykonywać mniejsze fragmenty refaktoryzacji podczas pracy, „pod radarem”, podczas pracy nad każdym obszarem bazy kodowej. A jeśli masz na myśli cel, możesz wykorzystać te możliwości, by krok po kroku iść we właściwym kierunku.
Może to zająć dużo czasu, ale większość kroków poprawi kod, a końcowy wynik będzie tego wart.
Również poczucie, że możesz zrobić lepiej, to dobry znak ! To pokazuje, że zależy ci na jakości swojej pracy i że oceniasz ją krytycznie; więc prawdopodobnie uczysz się i poprawiasz. Nie pozwól, aby te rzeczy Cię martwiły - ale nie przestawaj ich robić!
źródło
Przypadkowo natknąłeś się na jedno z największych wyzwań ludzkości (przygody), pomost między człowiekiem a maszyną. Most między człowiekiem a strukturą fizyczną, na przykład inżynieria lądowa, trwa od około 200 lat lub dłużej.
Ponieważ tworzenie oprogramowania naprawdę stało się głównym nurtem dopiero w latach 90., ma ono około 30 lat. Dowiedzieliśmy się, że to nie tyle dyscyplina inżynierii, co nauki społeczne, i dopiero się zaczęliśmy.
Tak, spróbujesz TDD, Refaktoryzacja, Programowanie funkcjonalne, Wzorzec repozytorium, Pozyskiwanie zdarzeń, MV coś, Skrypt Java (<- Zrób to, to szalone), Wiązanie modelu, Brak Sql, Kontenery, Agile, SQL (<- zrób to jest potężny).
Nie ma jednej poprawki. Nawet eksperci wciąż chwytają się słomek.
Witajcie i ostrzegajcie, to samotne miejsce; ale absolutnie fascynujące.
źródło
Pójdę trochę podbić ziarno. Jest to niezwykle powszechne , ale nie do przyjęcia . Oznacza to, że nie rozpoznajesz dobrych sposobów organizacji kodu podczas pisania. To uczucie pochodzi z tego, że kod nie jest prosty .
Twoje doświadczenie było również moje przez długi czas, ale ostatnio (w ciągu ostatnich kilku lat) produkuję więcej kodu, który nie sprawia, że czuję, że muszę wszystko wyrzucić. Oto mniej więcej to, co zrobiłem:
Mój kod jest teraz bardziej „proceduralny”, co oznacza, że jest uporządkowany według działań, które podejmuje, a nie według używanych struktur danych. Używam obiektów w językach, w których samodzielne funkcje nie mogą być zastępowane w locie (C # i Java nie mogą zastępować funkcji w locie, Python może). Mam teraz tendencję do tworzenia większej liczby funkcji narzędziowych , które po prostu odsuwają od siebie irytującą płytkę, aby móc odczytać logikę mojego kodu. (Np. Kiedy potrzebowałem przetworzyć wszystkie kombinacje elementów na liście, odsunąłem indeks zapętlony na metodę rozszerzenia, która zwraca
Tuple
s, aby pierwotna funkcja nie była zaśmiecona tymi szczegółami implementacji.) Teraz przekazuję do funkcji o wiele więcej parametrów jako parametrów, zamiast zwracania się do jakiegoś innego obiektu, aby go pobrać. (Dzwoniący pobiera lub tworzy go i przekazuje.) Teraz zostawiam więcej komentarzy, które wyjaśniają rzeczy, które nie są oczywiste po prostu patrząc na kod , co ułatwia przestrzeganie logiki metody. Testy piszę tylko w ograniczonych przypadkach, gdy martwię się logiką czegoś, co właśnie stworzyłem, i unikam używania próbnych. (Robię więcej testów wejścia / wyjścia na izolowanych elementach logicznych.) W rezultacie powstaje kod, który nie jest idealny , ale w rzeczywistości wydaje się być w porządku, nawet 2 lub 3 lata później. Jest to kod, który dość dobrze reaguje na zmiany; drobne rzeczy można dodawać, usuwać lub zmieniać bez rozbijania całego systemu.Do pewnego stopnia, to muszą przejść przez okres, gdzie rzeczy są bałagan tak, że masz pewne doświadczenie, aby przejść off. Ale jeśli wszystko jest nadal tak popsute, że chcesz to wszystko wyrzucić i zacząć od nowa, coś jest nie tak; nie uczysz się.
źródło
Pamiętając, że Twój czas jest ograniczony. A twój przyszły czas jest również ograniczony. Niezależnie od tego, czy chodzi o projekty zawodowe , szkolne czy osobiste, jeśli chodzi o działający kod, musisz zadać sobie pytanie: „czy przepisuje to najlepiej, jak najlepiej wykorzystuję mój ograniczony i cenny czas?” A może „czy jest to najbardziej odpowiedzialne wykorzystanie mojego ograniczonego czasu”?
Czasami odpowiedź będzie jednoznacznie tak . Zwykle nie. Czasami będzie na ogrodzeniu i będziesz musiał użyć własnego uznania. Czasami dobrze wykorzystujesz swój czas po prostu z powodu rzeczy, których nauczysz się, robiąc to.
Mam wiele projektów, zarówno zawodowych, jak i osobistych, które korzystałyby z portu / przepisywania. Mam też inne rzeczy do zrobienia.
źródło
Jest to całkowicie normalna część nauki. Zaczynasz zdawać sobie sprawę z błędów.
W ten sposób stajesz się lepszy i nie powinieneś tego unikać.
źródło
Możesz dać sobie doświadczenie, wiedząc, że uwodzicielska chęć przepisywania jest zwykle nieproduktywna. Znajdź stary, owłosiony, nieelegancki projekt o otwartym kodzie źródłowym o umiarkowanej złożoności. Spróbuj napisać od nowa i zobacz, jak sobie radzisz.
W końcu twój instynkt zmieni się z myślenia „Mogę przepisać ten system o wiele lepiej” na myślenie, że „kruchość tego systemu może wskazywać na pewną złożoność, która nie jest od razu widoczna”.
źródło