Czy kiedykolwiek w życiu mieliście taką sytuację, że myśleliście, że jesteście za głupi na programowanie? Obecnie studiuję, w szkole średniej nie miałem nigdy z niczym problemów, na studiach w zasadzie też jest ok, ale kiedy próbuje tworzyć coś swojego co jest trochę trudniejsze niż rzeczy ze studiów to owszem, udaje mi się to napisać, jednak po skończeniu okazuje się, że można by to napisać lepiej, krócej i szybciej. Pisze więc na nowo, zmieniam parę rzeczy i znów okazuje się, że można jeszcze coś zmienić. I to nie chodzi o proste dopisanie czegoś tylko o pewne części kodu, które można napisać zupełnie inaczej. I tak w zasadzie bez końca. Zupełnie jakbym był zbyt głupi na to, żeby od razu w pierwszej wersji coś w miarę sensownie napisać. I to naprawdę nie chodzi o to, że poszedłem na studia "bo jest po tym praca", bo ja naprawdę lubię to robić, czuje duże emocje gdy mi coś wyjdzie (i to się raczej nie zmieni jeszcze długo), ale jestem w miejscu gdy zaczynam jakby odczuwać pewne braki intelektualne. A może zwyczajnie brak mi jeszcze doświadczenia i to się później wykształci?
ciekawy napisał(a):
I to nie chodzi o proste dopisanie czegoś tylko o pewne części kodu, które można napisać zupełnie inaczej. I tak w zasadzie bez końca. Zupełnie jakbym był zbyt głupi na to, żeby od razu w pierwszej wersji coś w miarę sensownie napisać.
Złota zasada: kod nigdy nie jest tak dobry, jak chciałby tego programista. Nie da się stworzyć idealnego kodu, przewidzieć wszystkiego za pierwszym razem. Tworzony kod ma po prostu spełniać wymagania, inaczej będziesz poprawiał bez końca.
ciekawy napisał(a):
A może zwyczajnie brak mi jeszcze doświadczenia i to się później wykształci?
To na pewno też. Przede wszystkim stawiasz sobie zbyt wysokie wymagania, Twoim celem jest zrealizowanie projektu, nie jest nim uczynienie kodu idealnym. Z czasem nabierzesz doświadczenia w realnej ocenie jakości kodu, będziesz wiedział, kiedy/czy należy dany fragment zrefaktoryzować, jaki jest bilans kosztów do zysków.
Druga złota zasada: istnieją programy idealne... i programy ukończone.
ciekawy napisał(a):
udaje mi się to napisać, jednak po skończeniu okazuje się, że można by to napisać lepiej, krócej i szybciej. Pisze więc na nowo, zmieniam parę rzeczy i znów okazuje się, że można jeszcze coś zmienić. I to nie chodzi o proste dopisanie czegoś tylko o pewne części kodu, które można napisać zupełnie inaczej. I tak w zasadzie bez końca.
Lepiej, krócej i szybciej pisze się z wykorzystaniem tablic i pętli, zamiast zestawu zmiennych v1 do v1000 oraz skopiowanych bloków kodu. Czy o takie coś Ci chodzi? Czy raczej o dzielenie kodu na metody i klasy? (O i le w ogóle pytasz o OOP.)
Bez końca lepiej, krócej i szybciej? Nie sądzę, w pewnym momencie dochodzisz do jakiegoś ograniczenia, w którym możesz zrobić co najwyżej niewiele znaczącą kosmetyczną zmianę (typu zamiana pętli for na while), na której zaoszczędzisz (albo stracisz) raptem kilka linijek kodu.
Zupełnie jakbym był zbyt głupi na to, żeby od razu w pierwszej wersji coś w miarę sensownie napisać.
To kwestia braku doświadczenia, nie głupoty.
Moja złota zasada brzmi mniej więcej tak: piszę najpierw kod tak, żeby działał, potem testuje oprogramowanie, wprowadzam ewentualne poprawki a dopiero na koniec jak mi się jeszcze chce to sprawdzam co można napisać krócej i 'wydajniej'.
IMO nie brakuje Ci 'wiedzy' lub 'nadawania się' do programowania... jedyne czego Ci brakuje to solidnej motywacji. Ale pamiętaj, że motywacją nie mogą być pieniądze bo programować trzeba z pasją a nie dla pieniędzy bo możesz się ostro przejechać.
@ciekawy:
Przejmujesz się pierdołami. Jeśli Cię to gryzie, to polecam przestać. Samodoskonalenie się, krytyczne podejście do swojego kodu i znajdowanie w nim wad i kompromisów jest dobre, ale jeśli masz przy tym zdecydowanie negatywne odczucia i uważasz, że wychodzisz na kogoś o "brakach intelektualnych", to już jest to szkodliwe.
Widząc temat myślałem, że napiszesz o tych momentach, gdy programista jest w kropce. Albo gdy widzi, że inni zdają się łapać coś szybciej od niego. Takie momenty też się zdarzają, nawet bardzo dobrym programistą, choć "bycie kropce" zdarza się coraz rzadziej w miarę tego jak nabywamy doświadczenia.
Uważanie, że ktoś inny jest nie wiadomo jak inteligentny, a my jesteśmy "głupi", zwykle jest spowodowane tym, że za mało o tej osobie wiemy i luki wypełniamy na swój sposób. Ludzie mają tendencje do przesadzania. Częste jest też robienie z innych ludzi osób niby-doskonałych. Taki rodzaj błędu poznawczego. Wydaje Ci się, że ten koleś wymiata jako koder? Może ma po prostu dobry dzień, a Ty masz słaby (np. ze względu na zmęczenie). Albo koleś rozwiązuje problem podobny do tego, z czym wielokrotnie spotkał się już wcześniej. I koleś zapewne parę dni czy tygodni temu sam miał beznadziejny dzień. Ty tego nie widzisz, bo takich dni nie widać. Najlepsi programiści robią czasem suchary.
Ta zasada dotyczy nie tylko programowania. Idealizujemy rzeczy, których w danym momencie nie mamy i których nie znamy za dobrze. Ta parka na ławce w parku lub na imprezie wydaje się superszczęśliwa i idealna? W domu pewnie też się czasem żałośnie kłócą. Spora Część z takich parek się rozpadnie.
"Idealne" samochody mają swoje wady. "Idealni" sportowcy mają swoje ograniczenia. "Idealnie" wyglądające dziewczyny też mają "wady" w wyglądzie.
Bo są tylko ludźmi. Tak jak programiści.
Może chodzi o to, że obiektów stricte idealnych (prawie?) nie ma. Szczególnie jeśli te obiekty są złożone. Jak np. ludzie. Można więc w ogóle nie używać słowa "idealny" lub zmienić jego znaczenie.
Np. powiedzieć, że idealny programista NIE napisze idealnego kodu, ale napisze kod czytelny (zapewne poza jakimiś fragmentami), o niewielkiej liczbie defektów, dobrze realizujący specyfikację i pewne atrybuty jakościowe. Idealny programista, gdy ktoś znajdzie defekt w jego kodzie, podziękuje znalazcy i szybko błąd naprawi. Zastanowi się, co może zrobić, by uniknąć takiego błędu w przyszłości i doda do testów kod, który wykryje podobne defekty w przyszłości.
Ty w treści posta opisujesz coś trochę innego niż w temacie. Zobaczmy...
ciekawy napisał(a)
Obecnie studiuję [...] kiedy próbuje tworzyć coś swojego co jest trochę trudniejsze niż rzeczy ze studiów to owszem, udaje mi się to napisać,
Jak się udaje, to nie jest źle.
ciekawy napisał(a)
po skończeniu okazuje się, że można by to napisać lepiej, krócej i szybciej
Niestety, nie pamiętamy przyszłości, tylko przeszłość. Wnioskujemy zaś na podstawie naszej wiedzy, tj. tego, co zapamiętaliśmy (czasem usiłując przewidywać przyszłość, zwykle z marnym skutkiem). Normalne, że po zakończeniu pracy masz znacznie większą wiedzę na dany temat i potrafiłbyś wymyślić lepsze rozwiązanie problemu niż to, które wymyśliłeś tydzień temu, gdy jeszcze tej wiedzy nie miałeś.
Zresztą: prawie każdy kod da się napisać lepiej, krócej lub szybciej
Powiedzieć Ci coś o atrybutach jakościowych?
Niektóre z nich się wykluczają. Utrzymywalność (+czytelność) i modyfikowalność często kłócą się z wydajnością. Nie da się mieć i tego, i tego na najwyższym poziomie. Dlatego jaki kod jest "idealny"? Może po prostu taki, który dobrze spełnia wymagania funkcjonalne i niefunkcjonalne, a także został ukończony w terminie? Ten kod może być 2x mniej wydajny od optymalnego wydajnościowo rozwiązania, ale w danym projekcie może nie mieć to znaczenia.
ciekawy napisał(a)
Zupełnie jakbym był zbyt głupi na to, żeby od razu w pierwszej wersji coś w miarę sensownie napisać.
Z pewnością jesteś zbyt głupi na to, żeby od razu, w pierwszej wersji, napisać większy fragment idealnego kodu. To samo może powiedzieć o sobie każdy programista.
Tworzenie oprogramowania to bardzo trudna rzecz. Liczba ruchomych części, abstrakcyjnych bytów i zależności jest olbrzymia. Wymagania potrafią się zmieniać jak chyba w żadnej innej branży, czasu jest mało bo branżowe tempo jest bardzo duże... M.in. stąd tyle defektów i kompromisów. Przekroczonych deadline'ów. Stąd potrzeba wprowadzenia inżynierii oprogramowania.
ciekawy napisał(a)
Pisze więc na nowo, zmieniam parę rzeczy i znów okazuje się, że można jeszcze coś zmienić. [...] . I tak w zasadzie bez końca.
I to jest prawdziwy problem, który... jest całkowicie normalny. Chyba każdy dobry programista, jakiego znam, przechodził przez to.
Jest kilka stadiów tej choroby.
Pierwsze to przepisywanie całych, ogromnych fragmentów kodu lub nawet całego programu całkowicie od nowa.
Rozwiązaniem jest tutaj refaktoryzacja. Możesz poczytać o niej w książkach takich jak "Refaktoryzacja" Martina Fowlera lub "Czysty kod" Roberta C. Martina. To poprawianie struktury istniejącego kodu. Stopniowo, małymi krokami. Najczęściej: bez wyrzucania jakichkolwiek wielkich połaci kodu.
Dzięki refaktoryzacji piszesz i poprawiasz cały czas ten sam program. Możesz płynnie, stopniowo przetransformować słaby kod w dobry. Ma to daleko idące konsekwencje.
Pisanie czegoś od zera nie jest wcale takie dobre. Kod, który już działa od pewnego czasu, ma w sobie dobrą "historię". Znaleziono w nim już dużo defektów i po prostu w miarę dobrze działa. O kodzie zupełnie nowym nic jeszcze nie wiadomo -- on też musi przejść przez proces żmudnych bug-fixingów.
Poza tym, ludzie często pamiętają to uczucie czystego kodu gdy zaczynali pisać daną aplikację. Gdy piszą ją od nowa, znowu mają to uczucie. Zależności jest mało, kod jest prosty. Potem jednak gdzieś "coś się psuje" i całość robi się nieczytelna. I programiści często uważają, że to w późniejszej fazie coś sknocili i że w nowej aplikacji tego unikną. Tymczasem bardzo możliwe, że w starszej wersji nawet te niby-czyste fundamenty były tak naprawdę do bani i były powodem porażki. Czyniły pewne założenia, które były błędne i niemożliwe do spełnienia. Wyglądało to niby dobrze, gdy było proste, ale architektura tak naprawdę nie była przemyślana i wyrosła na niej jakaś pokraka. Bo musiała wyrosnąć na takim fundamencie.
Refaktoryzacja pozwala na reagowanie na problemy w kodzie. Jeśli nasze założenia odnośnie przyszłych modułów okazały się złe i zobaczyliśmy to dopiero w czasie implementacji tych modułów, to możemy zrefaktoryzować stare moduły (i nasze założenia) i naprawić błędy.
Stosowanie małych kroków i częstych, nie psujących niczego commitów do repozytorium czyni refaktoryzację bezpieczną. Po każdym kroku testujemy. Powinny to być testy automatyczne, ale w ostateczności mogą być i ręczne. Dzięki temu nie jest tak, że nagle coś spieprzymy i wszystko się zawala. Nie, aplikacja cały czas działa, tylko stan jej bebechów powoli się poprawia.
Pierwsza choroba to niestosowanie refaktoryzacji, tylko przepisywanie (OK, czasem przepisanie jest dobre, ale dużo rzadziej niż się wydaje).
Druga choroba to nie zauważanie, że trzeba już przestać.
Nie jest to aż tak istotne, gdy się uczymy i mamy mnóstwo czasu. Rzeczywista praca jest jednak niemal zawsze inna. Zadaniem profesjonalnego programisty jest dostarczenie projektu również w ramach określonego budżetu. Planowanie refaktoryzacji i uzyskania odpowiedniej jakości to też element naszej pracy.
Musimy umieć wyznaczyć priorytety. Zwykle, algorytmy przy jakichkolwiek optymalizacjach są proste, ale -- o dziwo -- wiele osób ich nie stosuje.
Np. jeśli chodzi o wydajność, należy za pomocą pomiarów (!) wyznaczyć wąskie gardła w aplikacji. Zwykle za 90% czasu wykonania odpowiada zaledwie 10% kodu. Na tych 10 krytycznych procentach należy się skupić. Kilkukrotne poprawienie wydajności jakiegoś nieistotnego fragmentu może się przełożyć zaledwie na 0.0001% zysk z punktu widzenia całej aplikacji. A jeśli superistotny fragment poprawimy nawet nie o 100%, tylko o 50%, to cała aplikacja może odnotować grubych kilka lub kilkanaście procent wzrostu wydajności.
Podobnie priorytetyzować trzeba jakość. Zostały mi np. 3 dni na poprawienie jakości kodu. Co jestem w stanie przez te 3 dni zrobić? Lekko ogarnąć kilkanaście modułów, a może porządnie przerobić jeden, najważniejszy? Albo dwa-trzy doprowadzić do bardzo dobrego stanu? Jak mogę wykorzystać te 3 dni tak, by program zyskał najwięcej?
Wyznaczasz te cele, a potem je realizujesz aż starczy czasu.
W ramach ćwiczeń, również do swoich projektów możesz wyznaczyć deadline'y.
To, co napisałem wyżej, jest prawdziwe na kilku poziomach.
@somekind pisał o tablicach i pętlach vs 1000 zmiennych i kopiowaniu/wklejaniu. Żadna osoba, która wybiera tę drugą opcję, nie może się nazwać profesjonalistą. Mi chodziło bardziej o strukturę aplikacji. Tylko że i ona dzieli się na wiele poziomów.
Studenci często używają copy-pasty. Relatywnie dobrzy programiści bardzo rzadko i tylko w określonych przypadkach.
Na kolejnym poziomie, problemem są duże klasy i duże funkcje (ponownie: zobacz "Czysty kod").
Jeśli to rozwiążesz i opanujesz, równolegle z podstawami architektury, to już pewnie będziesz się mógł nazywać profesjonalistą (o ile dorzucisz do tego trochę innych umiejętności i znajomość Twojej dziedziny).
Jednak nawet wtedy nie musisz się zatrzymywać. Możesz się skupić na pisaniu bibliotek, super-reużywalnego kodu, architektury złożonych aplikacji, hardcore'owego programowania współbieżnego, aplikacji hiperwydajnych/systemów czasu rzeczywistego...
Stosunek "da się to zrobić lepiej!" jest fajny, ale niech Cię nie przytłacza. Najlepiej nigdy się nie zatrzymuj. Ale niech braki w Twojej wiedzy i umiejętnościach Cię nie załamują. Zawsze to powtarzam: możesz być junior developerem i to nie wstyd, a nawet coś fajnego, jeśli tylko będziesz DOBRYM junior developerem. Potem możesz być DOBRYM normalnym, potem DOBRYM seniorem, potem DOBRYM architektem etc. Przyj do przodu, ale bądź świadom, że nawet na obecnym szczeblu drabiny, mimo wszystkich Twoich wad (każdy je ma!) jesteś dobry i pewny swojej wiedzy. Nie gryzie się to z byciem pewnym, że ta wiedza za X lat będzie dużo wyższa :).
@Monixoth jesteś więc przedstawicielem koderów których najbardziej nie lubię. Czemu? Bo potem trafiam na kod takich gości i okazuje się że nie da się go zmodyfikować i trzeba go napisać od nowa. Ja uważam że kod od razu należy pisać porządnie i czytelnie. Oczywiscie nie ma sensu bawić się w optymaliazcję na początku, ale o czytelności i rozszerzalności trzeba myśleć cały czas. Bo kod ma tendencję do ewoluowania i to że klasa którą napisałeś teraz jest malutka to nie znaczy że zaraz 15 osób do niej czegoś nie dopisze. Jak od początku źle ją zaprojektowałeś to potem jest mogiła. Inna sprawa jest jeśli chcesz coś tylko zaprototypować albo sprawdzić czy w ogóle da się coś zrobić...
@ciekawy na moje oko zwykły brak doświadczenia, albo nieprzemyślenie projektu na początku. Poza tym programiści mają często tendencję do over-engineeringu, to znaczy lubią robić przekombinowane rozwiązania dla prostych problemów. Zawsze trzeba myśleć o rozszerzalności i modyfikowalności rozwiązania, ale to nie znaczy że każda klasa ma być generyczna i to nie znaczy że należy pousuwać wszystkie if'y w kodzie i pozamieniać je na wywołania polimorficzne z template method (i nagle z klasy na 40 linijek robi się hierarchia na 10 klas ;] w miejscu które nigdy się nie zmieni).
Zbytni perfekcjonizm to zło w dowolnej dziedzinie. Lepiej zaakceptuj, że Twój kod nigdy nie będzie idealny (a już na pewno nie na początku, jak się uczysz) albo będziesz tylko tracił nerwy. A nawet jeśli uda Ci się doprowadzić pisanie kodu do perfekcji to pójdziesz do pracy i trafisz na kody projektów które są DALEKIE od perfekcji i znowu będziesz się wkurzał.
Ja mam czasem takie wrażenie po ukończeniu projektu ,że tyle się na trzaskałem a coś można było zrobić prościej i mniej objętościowo. Dziwnie się czuje gdy więcej nakombinowałem niż wymaga tego sytuacja.
@ciekawy spójrz na to z innej strony, taki prosty przykład:
gdyby wszyscy pisali wszystko perfekcyjnie i bez poprawek to nie mielibyśmy tylu windowsów, powstałby jeden, idealny gdzieś na początku ery MS i pozamiatane (choć nie ma softu idealnego).
Miałem jeszcze gorsze zdanie o sobie ucząc się Haskella z dokumentacji, zacząłem się w pewnym punkcie zastanawiać jakim sposobem ja w ogóle matury zdałem...
A takimi rzeczami się nie przejmuj, jak piszesz artykuł na dany temat to po roku też widzisz, że tą część można było napisać jaśniej, tutaj więcej, a tamtą część usunąć. To jest taka praca, że zawsze da się coś zmienić i poprawić.