Słaba jakość kodu w dużej firmie?

2

@TomRiddle:

TomRiddle napisał(a):
ref napisał(a):

refaktor to jest koszt dla firmy

Poza tym; kurde; ile można jechać na tym samym. Jak ja robię refaktor to mi to zajmuje kilka sekund albo minut max, i back commit. Więcej Ci zajmie czasu żeby napisać post o tym żeby nie refaktorować niż ten faktyczny refaktor.

Nie przesadzaj z tymi łatwymi refaktorami. Historia z dzisiaj. Robię zamianę 4 parametrów powtarzających w wielu metodach na parameter-object. Generalnie poprawka na 15 minut mechanicznego kodowania, ale trzeba jeszcze sprawdzic unit testy. Te czerwone wyglądają tak:

  • 10 linijek mockito when()
  • mockowane są nie tylko test double, ale też dane wejściowe i interakcja między nimi: when(price1.add(eq(price2)).thenReturn(price3)
  • 6 linijek z verify() sprawdzających takie bzdury jak powyżej.
  • 0 asercji.
  • niejawne poleganie na fakcie, że mockito domyślnie zwraca null, gdzie w kodzie produkcyjnym to niemożliwe.

Na doprowadzenie tego do działania (bez posprzątaniu tych overmocków) minął mi dzień.

To jest w miarę świeży kod. Napisał go kolega z zespołu, który ewidentnie jest nowy w unit testach. Z tego, co widzę, to on jest jedynym koderem w projekcie, któremu chce się pisać testy. Więc to jest przypadek dobrych intencji, ale braku wiedzy/doświadczenia.

0

Słaba jakość kodu to domena większości firm. Mój przypadek- miałem okazję współpracować z firmą gdzie szło się po trupach do celu- klientowi obiecano złote góry i trzeba robić, robić, robić. Byle jak, byle działało, ale ma być w terminie. Nikt niczego nie przemyślał, przedyskutował, zero dokumentacji, koncepcji itp. Przez lata szefostwo zadowolone- kasa płynęła, klienci przychodzili. Tylko że w pewnym momencie osiągnieto masę krytyczną- problemy wydajnościowe, kod którym nie da się zarządzać, tu coś zmienisz, a tam połowa systemu się sypie. W końcu podjęto próbę przepisania/ poprawy istniejących systemów i... po paru latach klapa. Nikt nie wiedział jak to działa, jakie były założenia, każdy manager się na tym wykładał i w konsekwencji firma zaczęła tracić klientów... Ja nie mowię, że każda linia kodu ma być przedyskutowana i 100% pokryte testami, tak się zwykle nie da jak gonią terminy, ale robienie tasków na hurra w nierealnym terminie w końcu odbija się boleśnie na kondycji firmy.

1

@micheangelo: moim zdaniem jest tak dlatego, że różne poziomy w firmie mają różne cele
ci na górze muszą się wykazać że robota idzie - a jak to wykazać - jak ci na dole coś tam robią i robią, kasa na to idzie, a wartości biznesowej nie przybywa - czyli firma na zewnątrz nie ma się czym pochwalić

kiedyś był tu taki wpis, samotność programisty
że praca deva jest na tyle abstrakcyjna, ze trudno się nią pochwalić, pokazać, pogadać z kimś kto w tym nie robi, jest się tak z tym sam
mechanik, lekarz, fliziarz, piekarz, kucharz mogą pogadać z kimś spoza branży i to jakoś będzie szlo, a dev - co powie, kurde tu myślałem dwa dni i połączyłem strategie z fasadą, zmieniłem IoC na Autofaca i Drapera na EF6 (czy tam na odwrót, lub dowolny inny przykład) i kto to zrozumie, doceni, wejdzie w rozmowę?

1
ArchitektSpaghetti napisał(a):

@TomRiddle:

TomRiddle napisał(a):
ref napisał(a):

refaktor to jest koszt dla firmy

Poza tym; kurde; ile można jechać na tym samym. Jak ja robię refaktor to mi to zajmuje kilka sekund albo minut max, i back commit. Więcej Ci zajmie czasu żeby napisać post o tym żeby nie refaktorować niż ten faktyczny refaktor.

Nie przesadzaj z tymi łatwymi refaktorami. Historia z dzisiaj. Robię zamianę 4 parametrów powtarzających w wielu metodach na parameter-object. Generalnie poprawka na 15 minut mechanicznego kodowania, ale trzeba jeszcze sprawdzic unit testy. Te czerwone wyglądają tak:

  • 10 linijek mockito when()
  • mockowane są nie tylko test double, ale też dane wejściowe i interakcja między nimi: when(price1.add(eq(price2)).thenReturn(price3)
  • 6 linijek z verify() sprawdzających takie bzdury jak powyżej.
  • 0 asercji.
  • niejawne poleganie na fakcie, że mockito domyślnie zwraca null, gdzie w kodzie produkcyjnym to niemożliwe.

To jest problem tego że masz słabe testy. Jasno widać że blokują Cię przed refaktorem więc nie mogą być dobre.

Testy pisze się między innymi właśnie po to żeby móc łatwo refaktorować cały kod, więc jeśli Ty sam teraz zauważasz że nie możesz refaktorować przez testy, to wartość tych testów jest bardzo niska. W zasadzie zniszczyłeś cały sens ich istnienia.
Gdybyś miał posprzątane w kodzie, i dobre testy to ten refaktor faktycznie zająłby mało czasu. Z definicji refaktor ma nie zmienić działania aplikacji, a tylko jego strukturę; więc żaden test nie powinien sfailować, chyba że zmieniasz API swojego modułu, ale tego bym nie nazwał refaktorem.

Dobre testy umożliwiają refaktor, refaktor umożliwia pisanie dobrych testów, a z kolei dobre testy umożliwiają więcej refaktoru.

Jeśli pracujesz w syfie którego nie sprzątasz, to masz słabe testy, które utrudniają w refaktorze, a to sprawia że masz gorszy nietestowalny kod, przez co masz gorsze testy, przez co utrudniony refaktor.

3
TomRiddle napisał(a):

Jeśli pracujesz w syfie którego nie sprzątasz, to masz słabe testy, które utrudniają w refaktorze, a to sprawia że masz gorszy nietestowalny kod, przez co masz gorsze testy, przez co utrudniony refaktor.

Ale przecież on to posprzątał. :|
A Ty masz do niego pretensje, że posprzątał. :|

2
ArchitektSpaghetti napisał(a):

@TomRiddle:

TomRiddle napisał(a):
ref napisał(a):

refaktor to jest koszt dla firmy

Poza tym; kurde; ile można jechać na tym samym. Jak ja robię refaktor to mi to zajmuje kilka sekund albo minut max, i back commit. Więcej Ci zajmie czasu żeby napisać post o tym żeby nie refaktorować niż ten faktyczny refaktor.

Nie przesadzaj z tymi łatwymi refaktorami. Historia z dzisiaj. Robię zamianę 4 parametrów powtarzających w wielu metodach na parameter-object. Generalnie poprawka na 15 minut mechanicznego kodowania, ale trzeba jeszcze sprawdzic unit testy. Te czerwone wyglądają tak:

  • 10 linijek mockito when()
  • mockowane są nie tylko test double, ale też dane wejściowe i interakcja między nimi: when(price1.add(eq(price2)).thenReturn(price3)
  • 6 linijek z verify() sprawdzających takie bzdury jak powyżej.
  • 0 asercji.
  • niejawne poleganie na fakcie, że mockito domyślnie zwraca null, gdzie w kodzie produkcyjnym to niemożliwe.

Na doprowadzenie tego do działania (bez posprzątaniu tych overmocków) minął mi dzień.

To jest w miarę świeży kod. Napisał go kolega z zespołu, który ewidentnie jest nowy w unit testach. Z tego, co widzę, to on jest jedynym koderem w projekcie, któremu chce się pisać testy. Więc to jest przypadek dobrych intencji, ale braku wiedzy/doświadczenia.

To jest coś czego niektórzy nie łapią. Jak są metody zwracające void z pierdyliardem zależności, metodami na 50 lini to napisanie w ogóle testu jest trudne.

0
scibi_92 napisał(a):

To jest coś czego niektórzy nie łapią. Jak są metody zwracające void z pierdyliardem zależności, metodami na 50 lini to napisanie w ogóle testu jest trudne.

No tak; bo kod jest nietestowalny. A jest nie testowalny bo się nie robi refaktorów (Albo się nie umie robić). A nie robi sięrefaktoru bo nie ma testów, błędne koło. Trzeba je złamać i zacząć pisać testy i refaktorować.

0

@TomRiddle: ogólnie z Twoim przeslaniem trudno się nie zgodzić, masz sporo racji w tym co piszesz
wydaje mi się mi się że w tym wszystkim przeceniasz rolę zwykłego dev-a (przynajmniej ja tak to odbieram)

to tak jak mechanik - wymienia klocki czy tarcze i mówi do klienta zakładamy taką za x PLN czy lepszą, trwalszą za 3x PLN
klient mówi - ta za x wystarczy - i chociażby czasem mechanika serce kłuło to robi to czego chce klient
mam kumpla wykończeniowca to też mówi, że $ często decyduje i zamiast dać więcej na materiały, które po latach będą się prezentować to kupuje się na teraz - to ze teraz nie widać różnicy, a różnica wyjdzie np. po 5 czy 7 latach użytkowania, a kogo to w danym momencie obchodzi
tak jest wszędzie - na końcu pieniądz i doraźna korzyść decydują

dlatego moim zdaniem czasem ciężko przerwać to błędne koło bo klient (firma) sobie tego nie życzy i za dobre chęci będziesz przykładnie ukarany :)
to nie jest niemożliwe
ale czasami ma się dość dopominania się o robotę (czas) i koniec końców wygrywa chcesz masz, jakby co mówiłem, że tak będzie....

0
ref napisał(a):

@TomRiddle: ogólnie z Twoim przeslaniem trudno się nie zgodzić, masz sporo racji w tym co piszesz
wydaje mi się mi się że w tym wszystkim przeceniasz rolę zwykłego dev-a (przynajmniej ja tak to odbieram)

to tak jak mechanik - wymienia klocki czy tarcze i mówi do klienta zakładamy taką za x PLN czy lepszą, trwalszą za 3x PLN
klient mówi - ta za x wystarczy - i chociażby czasem mechanika serce kłuło to robi to czego chce klient
mam kumpla wykończeniowca to też mówi, że $ często decyduje i zamiast dać więcej na materiały, które po latach będą się prezentować to kupuje się na teraz - to ze teraz nie widać różnicy, a różnica wyjdzie np. po 5 czy 7 latach użytkowania, a kogo to w danym momencie obchodzi
tak jest wszędzie - na końcu pieniądz i doraźna korzyść decydują

Tylko to ma wtedy znaczenie, kiedy te dwa koszty się różnią. Gdyby różnica pomiędzy wytrzymalszym a mniej wytrzymałym wynosiła np 1-2%, to każdy mechanik wybrałby wytrzymalszy bez pytania.

Mam wrażenie, że wszystko sprowadza się do nieumiejętności refaktorowania i nieumiejętności testowania. Refaktor to nie jest rewloucja, że wchodzisz z armatoą i zaczynasz wszystko zmieniać, wystarczą dobre zmiany, ale systematyczne.

Wystarczy przy każdym PR'ze który robisz, zmienić nazwę na lepszą. Wydzielić jakąś funkcję, zininlein'ować jakąś funkcje. Dopisać jeden brakujący test, porpawić istniejący; małymi krokami, stopniowo zwiększać jakoś, i mieć z tyłu głowy żeby nie pogarszać kodu. Jeśli wrzucasz do repo świerzutki kodzik z nowego PR'a który już na starcie wymaga refaktoru, to wprowadzasz dług technologiczny bez żadnego powodu i powinieneś dostał łopatą po głowie.

Bo jakby smutnie to nie zabrzmiało; to nie wszyscy jesteśmy równi. Niektórzy programiści są lepsi niż inni, i są lepsi skuteczniejsi i bezpieczniejsi w refaktor. Jeśli jesteś słaby, nie umiesz tego robić, albo nie wiesz jak; to łatwo jest mówić "aaaaaaaaa zbyt kosztowne to jest", zamiast wyjść ze strefy komfortu i nauczyć się robić to poprawnie i szybko. Jeśli mechanikowi zajęłoby 4 dni żeby wymienić olej, to oczywiście że będzie sobie wmawiał że wymiana oleju nie ma sensu.

9
TomRiddle napisał(a):

Jak ja robię refaktor to mi to zajmuje kilka sekund albo minut max, i back commit. Więcej Ci zajmie czasu żeby napisać post o tym żeby nie refaktorować niż ten faktyczny refaktor.

vs

TomRiddle napisał(a):

Gdybyś miał posprzątane w kodzie, i dobre testy to ten refaktor faktycznie zająłby mało czasu.

vs

TomRiddle napisał(a):

Jeśli pracujesz w syfie którego nie sprzątasz, to masz słabe testy, które utrudniają w refaktorze, a to sprawia że masz gorszy nietestowalny kod, przez co masz gorsze testy, przez co utrudniony refaktor.


Jak masz dobry kod, to masz proste refaktory, a jak masz zły kod, to masz trudne refaktory - szok i niedowierzanie.

0
Afish napisał(a):

Jak masz dobry kod, to masz proste refaktory, a jak masz zły kod, to masz trudne refaktory - szok i niedowierzanie.

Jak wrzucisz "kod produkcyjny" i "testy" do jednego worka "kod", to faktycznie wychodzi paradoks.

Ale to jest właśnie najlepsza metoda wychodzenia z legacy code'u.

  1. Masz legacy shit code i nic nie warte testy. Każdy refaktor niesie ryzyko, bo nie masz testów. Dopisanie testów jest trudne, bo kod jest nietestowalny.
  2. Dodajesz jeden prosty, dobry unit test. Czyli taki któy nie jest tightly-coupled do logiki, testuje to co ma testować, jest odseparowany od innych testów, działa szybko i rzetelnie na wielu systemach; nie failuje randomowo, i jest w stanie wygryć buga.
  3. Teraz możesz zrefaktorować tylko tą funkcję/linijkę pod którą masz testy.
  4. Piszesz jeden kolejny test, i jednocześnie dodajesz jeden mały refaktor. Możesz zmienić nazwę metody, wydzielić coś, przeniesć metodę w inne miejsce, usunąć niepotrzebny komentarz, zmienić nazwy zmiennych i, j, k np na row, column, sheet.
  5. Piszesz więcej testów, każdy z nich jest szybki, nie wie nic o szczegółach implementacyjnych, jest w stanie wygryć jak Twój refaktor coś zepsuje, ale nie failuje jak robisz zwykły refaktor.
  6. Zaczynasz zauważać że niektóre testy są do siebie podobne, a inne do innych; domyślasz się że to znaczy że te dwa testowane elementy są od siebie niezależne więc przenosisz częśc testów do jednego pliku, inne zostawiasz. Domyślasz się że to dlatego, że testowana logika też może być od siebie niezależna więc wydzielasz klasy z innych klas; a teraz masz już testy pod to które to sprawdzają więc możesz to zrobić.
  7. Potwarzają kroki 3..6

Pierwszych kilka iteracji będzie trudne, ale potem wzorst będzie wykładniczy. Kiedy pisałem edytor https://4playeditor.net/ napisanie pierwszego testu zajęło mi 10h, dlatego że nie funkcji która mogłaby osadzić edytor w virtualnym domie. Drugiego, do widoku 6h, bo nie miałem asercji pod style. Teraz, dodanie nowego testu to kwestia dwóch sekund, podobnie jak refaktora. Można to porównać do picia gorącej kawy, pierwszych parę łyków pijesz powooolutku, bo jest gorąca, ale za chwilę ostygnie i też przywykniesz do tego i bierzesz całe łyki.

Oczywiście, to jest przy założeniu że ktoś faktycznie umie pisać dobre unit testy, bo spora część ludzi nie umie, tylko im się wydaje że umieją; ale w rzeczywistości ich testy tylko pogarszają sprawę.

@Afish: Teraz odpowiedź na Twoje pytanie.

  • Czy w każdym legacy code'zie jest sens to robić? Nie.
  • Czy jesteś w stanie to zrobić w projekcie który już jest średni i ludzie nie robią tego dookoła? Prawdodpoobnie nie.
  • Czy to znaczy że musisz teraz przerobić każdy projekt nad jakim pracujesz? Oczywiście, nie.

Ale.

Metodologia sama w sobie jest poprawna, i należy ją stosować w nowych projektach i tam gdzie masz szansę, np podczas dokładania nowych feature'ów do projektu. Argumentowanie, że "refaktor i pisanie testów nie ma sensu", albo "refaktor i pisanie testów jest nieopłacalne" albo "to zajmie za dużo czasu" jest niepoprawny, krótko mówiąc. Bo refaktor i pisanie testów jest tanie, bardzo tanie; dużo tańsze niż utrzymywanie legacy code'u i testy manualne. Wprowadzenie ich do już istniejącego shitu, czasem może być drogie; czasem też możę być droższe niż to co mogą dać; ale to nie zmienia faktu że technika sama w sobie to jedyny sposób na posiadanie taniego projektu, w którym można szybko i bezpiecznie wprowadzać zmiany.

2

@TomRiddle: Każdy inżynier mówiąc o kosztownym refaktorze ma na myśli sytuację, gdy kod nie jest na to gotowy. Możesz się zacietrzewiać i dowodzić, że refaktor zajmuje minutę, ale nie o takiej sytuacji jest tu rozmowa.

1
Afish napisał(a):

@TomRiddle: Każdy inżynier mówiąc o kosztownym refaktorze ma na myśli sytuację, gdy kod nie jest na to gotowy. Możesz się zacietrzewiać i dowodzić, że refaktor zajmuje minutę, ale nie o takiej sytuacji jest tu rozmowa.

"Duży refaktor" to nic innego jak duża sekwencja małych refaktorów.

Im więcej dobrych testów masz, i im bardziej loosely-coupled jest Twoja aplikacja, tym więcej ich możesz wrzucić na raz; ale to nigdy nie jest 0. To nie jest tak że "teraz możemy zrobić 0 refaktorów".

0

To co up + to, że firmy na początku piszą gównokod, bo trzeba szybko wydać produkt, żeby zarobić a jak odziedziczysz coś takiego i jest podejście, żeby nie zmieniać syfu to nic nie zrobisz. No i do tego dochodzi wiek, inne podejscie i przestarzałe technologie. Kiedyś pisano o wiele brzydszy i gorszy kod niż teraz, więc jak jest stary projekt to już wiesz, że idziesz do utrzymaniówki w której będziesz spędzał tydzień na napisanie jednego/dwa ify, bo samo debbugowanie z źle napisanymi testami to magia. Mówię z prespektywy programisty c++. W innych językach moze być prościej, bo sama technologia nie podstawia kłód pod nogi.

1
Czitels napisał(a):

To co up + to, że firmy na początku piszą gównokod, bo trzeba szybko wydać produkt, żeby zarobić a jak odziedziczysz coś takiego i jest podejście, żeby nie zmieniać syfu to nic nie zrobisz.

Taka strategia nigdy nie działa.

Sporo startupów failuje nie dlatego że nie mogłoby sobie poradzić komercyjnie; tylko dlatego że zwiększają niepotrzebnie koszty utrzymania zaraz na starcie.

No i do tego dochodzi wiek, inne podejscie i przestarzałe technologie. Kiedyś pisano o wiele brzydszy i gorszy kod niż teraz, więc jak jest stary projekt to już wiesz, że idziesz do utrzymaniówki w której będziesz spędzał tydzień na napisanie jednego/dwa ify, bo samo debbugowanie z źle napisanymi testami to magia. Mówię z prespektywy programisty c++. W innych językach moze być prościej, bo sama technologia nie podstawia kłód pod nogi.

Jasne, to są ważne problemy.

Ale jednak nadal najwięszym problemem jest niechęć programistów do zmian, do zaczęcia robienia refaktoru i pisania testów; i do kontynuowania robienia poprawnie programów. Z wszystkim innym można sobie poradzić.

5
TomRiddle napisał(a):

Taka strategia nigdy nie działa.

Wszystkie firmy z kijowym oprogramowaniem, z faangiem na czele, raczą się nie zgodzić.

2

@TomRiddle:
Porównania do wymiany oleju nie mają sensu bo wymiana oleju jest konieczna a refactor nie.
Refactor jest jak odmalowywanie ściań w mieszkaniu żeby było ładnie i świeżo można się pokusić to zrobić co jakiś czas.
Ale jak nawet i przez 30 lat tych ściań nie pomalujesz to też się nic nie stanie.

0
smieszekheheszek napisał(a):

@TomRiddle:
Porównania do wymiany oleju nie mają sensu bo wymiana oleju jest konieczna a refactor nie.

Tak i nie. Z refaktorem jest tak, że nie jest konieczny, ale jego brak spowalnia przyszłą pracę bardziej i bardziej. Jeśli wymiana oleju Ci nie pasuje jako argument, to powiedziałbym że to bardziej jak ustawianie kolejnych brudnych talerzy w zlewie. Im więcej ich dodasz, tym trudniej będzie cokolwiek w nim umyć, a jeśli masz odpowiednio dużą górę talerzy, to nawet umycie jednej łyżeczki staje się trudne. Nie sprzątaj zlewu kilka miesięcy lub lat, i nic nie będziesz mógł w nim umyć.

Refactor jest jak odmalowywanie ściań w mieszkaniu żeby było ładnie i świeżo można się pokusić to zrobić co jakiś czas.
Ale jak nawet i przez 30 lat tych ściań nie pomalujesz to też się nic nie stanie.

Nie, nie, to na pewno nie. Refaktoru nie robi się po to żeby "zaspokoić jakiś zmysł estetyczny", i nie ma nic wspólnego z tym czy coś jest "ładne" czy nie. Refaktor to jest tylko i wyłącznie czynność konserwatorska, jak sprzątanie, ale nie po to żeby było ładnie, tylko po to żeby w danym miejscu się dało pracować. Jak sprzątanie warsztatu. Czynność którą się robi żęby zachować odporność na zmiany w programie. Nie rób wystarczająco długo żadnego refaktora, i wprowadzanie zmian w Twoim oprogramowaniu stanie się nie możliwe (a jeśli coś zmienisz to narazisz się na bugi i defekty). Jak dla mnie kod mógłby być nabrzydszy na świecie, byle byłby łatwy do zmiany (a łatwt do zmiany znaczy: małe klasy, lóźne połączenie/loose coupling, dużo małych testów, abstrakcje w odpowiednich miejscach, nie poleganie na szczegółach implementacyjnych).

Mit o tym że "kod jest ładny lub nieładny" to bajka, łuda. Tak na prawdę nie ma "ładnego" i "nieładnego" kodu. Jest tylko kod odporny na zmiany, albo kod który przy okazji zmiany się psuje. Refaktor to dbanie o to żeby kod się nie psuł kiedy coś w nim zmieniamy.

Jeśli tego nie rozumiesz to Twoje aplikacje nigdy nie będą dobre, nie będą wolne od bugów i defektów, i nie będzie można w nich wprowadzić łatwo zmian; będą wymagały natomiast dużo czasu i pieniędzy żeby wprowadzić w nich zmiany i przetestować je (najpewniej manualnie, bo bez refaktora ciężko napisać dobre testy automatyczne). Odejście od pewnych zależności będzie niemożliwe, a update niektórych bibliotek będzie się wiązał z ryzykiem wywalenia się całej aplikacji.

Powodzenia w tworzeniu dobrego oprogramowania z takim podejściem.

0

@TomRiddle:

Refaktor to dbanie o to żeby kod się nie psuł kiedy coś w nim zmieniamy.

Chyba mamy inne definicje refaktora. Dla mnie refaktor to po prostu próba przerobienia danego fragmentu kodu, a to niekoniecznie musi wyjść na lepsze.

to czy kod się psuje gdy coś zmieniamy prędzej dotyka OOP/SOLIDA.

Jeśli tego nie rozumiesz to Twoje aplikacje nigdy nie będą dobre, nie będą wolne od bugów i defektów, i nie będzie można w nich wprowadzić łatwo zmian; będą wymagały natomiast dużo czasu i pieniędzy żeby wprowadzić w nich zmiany i przetestować je (najpewniej manualnie, bo bez refaktora ciężko napisać dobre testy automatyczne).
uważam że wiele da się napisać

To czy się łatwo testuje czy nie, wynika z tego jak zaprojektowałeś, a nie czy refaktorowałeś. Możesz za pierwszym razem napisać dobrze :)

0
1a2b3c4d5e napisał(a):

@TomRiddle:

Refaktor to dbanie o to żeby kod się nie psuł kiedy coś w nim zmieniamy.

Chyba mamy inne definicje refaktora. Dla mnie refaktor to po prostu próba przerobienia danego fragmentu kodu, a to niekoniecznie musi wyjść na lepsze.

Musi. Jak wychodzi na gorsze, to cofasz na to co było wcześniej; nie commitujesz zmian. Po co zostawiać w kodzie zmianę na gorsze?

to czy kod się psuje gdy coś zmieniamy prędzej dotyka OOP/SOLIDA.

No, pretty much. Ale też innych zasad. Refaktor to trochę proces z przejscia kodu "Nie OOP/SOLID" na "OOP/SOLID", i inne dobre praktyki jakie uznasz. Refaktor to po prostu zmiana kodu na lepsze, bez zmiany zachowania. "Lepsze" mam na myśli "łatwiejsze"/"tańsze do zmiany" w przyszłości, i mówiąc przyszłość mam na myśli cos czasem w obrębie dni, tygodni, miesięcy, etc.

Jeśli tego nie rozumiesz to Twoje aplikacje nigdy nie będą dobre, nie będą wolne od bugów i defektów, i nie będzie można w nich wprowadzić łatwo zmian; będą wymagały natomiast dużo czasu i pieniędzy żeby wprowadzić w nich zmiany i przetestować je (najpewniej manualnie, bo bez refaktora ciężko napisać dobre testy automatyczne).
uważam że wiele da się napisać

No to good luck with that.

To czy się łatwo testuje czy nie, wynika z tego jak zaprojektowałeś, a nie czy refaktorowałeś. Możesz za pierwszym razem napisać dobrze :)

Tak, jeśli napiszesz od razu dobrze, to się łatwo testuje to prawda. Ale jeśli zaprojektowałeś źle, to musisz zrefaktorować, poprawić.

1

@TomRiddle:

Musi. Jak wychodzi na gorsze, to cofasz na to co było wcześniej; nie commitujesz zmian. Po co zostawiać w kodzie zmianę na gorsze?

Bo może to po prostu nie być oczywiste w momencie refactora.

Nie tylko programista "weryfikuje" dobry kod, bo również rzeczywistość, czas i userzy/klient.

Do czego będziesz revertował jak ciebie od pół roku nie ma w firmie, a nikt z nowych nawet nie wie że tam był inny design :D

A zatem, refaktor to tylko próba ratowania.

1

Ja stosuję taktykę salami Putlera. Jeżeli jest jakiś projekt który dotykam i nie ma testów to piszę pierwsze testy. Do tego konfiguruję w CI/CD, że testy są odpalane. Od tego momentu każdy kto dotknie tego kodu musi zapewnić, żeby testy które napisałem przechodziły oraz powinien napisać nowe testy bo mu o tym przypomnę w PR.

Jeżeli piszę nowy projekt to też piszę testy i CI/CD. Jeżeli jest projekt, którego jeszcze nie dotknąłem to olewam dopóki go nie dotknę.

W ten sposób poprawiałem spore projekty.

0
1a2b3c4d5e napisał(a):

Musi. Jak wychodzi na gorsze, to cofasz na to co było wcześniej; nie commitujesz zmian. Po co zostawiać w kodzie zmianę na gorsze?
Bo może to po prostu nie być oczywiste w momencie refactora.
Nie tylko programista "weryfikuje" dobry kod, bo również rzeczywistość, czas i userzy/klient.
Do czego będziesz revertował jak ciebie od pół roku nie ma w firmie, a nikt z nowych nawet nie wie że tam był inny design :D
A zatem, refaktor to tylko próba ratowania.

Aha, wiem o co Ci chodzi. No dobra; no to sprostuje.

Refaktor to dbanie o to żeby kod się nie psuł kiedy coś w nim zmieniamy.

Chyba mamy inne definicje refaktora. Dla mnie refaktor to po prostu próba przerobienia danego fragmentu kodu, a to niekoniecznie musi wyjść na lepsze.

No, okej cudotwórcą i jasnowidzem nie jesteś, więc może nie wyjść na dobre; na dłuższą metę. Sure. Pewnie też im jesteś słabszy w refaktor i im słabszym programistą jesteś tym większa szansa na to.

Jeśli jednak masz duże doświadczenie w tym co robisz; i wiesz co Twoja zmiana możę poprosuć a co nie; i jeśli masz mniejsze lub wieksze pojecie w którą strone powinien pójść rozwój projektu, to jednak spora szansa że refaktor przyniesie pozytywne skótki.

Widzę że masz postawę "Nie warto robić refaktoru", i próujesz znaleźć milion powodów czemu ktoś miałby ich nie robić "a bo czas", "a bo kasa", "a bo manager", "a bo nie potrzebne", "a bo słabe testy"; tymczasem legacy code, nie refaktorowany z techdebtem to szambo pochłaniają czas i kasę jeśli chce się w nim wprowadzać zmiany. Dziekuje za uwage.

3

Widzę że masz postawę "Nie warto robić refaktoru", i próujesz znaleźć milion powodów czemu ktoś miałby ich nie robić "a bo czas", "a bo kasa", "a bo manager", "a bo nie potrzebne", "a bo słabe testy"; tymczasem legacy code, nie refaktorowany z techdebtem to szambo pochłaniają czas i kasę jeśli chce się w nim wprowadzać zmiany. Dziekuje za uwage.

Raczej to, że chyba za dużo przypisujesz refaktorowi.

Podstawą jest solidnie zamodelowany system na wstępie, a nie próba naprawiania 10 refaktorami.

Jasne, można i tak, ale po co, gdy można postarać się na początku?

Napisanie dobrze na początku ułatwia utrzymanie spójności w modelowanym systemie, gdzie maraton developowania featuresów na zmianę z refaktorem i deadline™ raczej tylko utrudnia.

1
1a2b3c4d5e napisał(a):
TomRiddle napisał(a):

Widzę że masz postawę "Nie warto robić refaktoru", i próujesz znaleźć milion powodów czemu ktoś miałby ich nie robić "a bo czas", "a bo kasa", "a bo manager", "a bo nie potrzebne", "a bo słabe testy"; tymczasem legacy code, nie refaktorowany z techdebtem to szambo pochłaniają czas i kasę jeśli chce się w nim wprowadzać zmiany. Dziekuje za uwage.

Raczej to, że chyba za dużo przypisujesz refaktorowi.

Podstawą jest solidnie zamodelowany system na wstępie, a nie próba naprawiania 10 refaktorami.

Jasne, można i tak, ale po co, gdy można postarać się na początku?

Napisanie dobrze na początku ułatwia utrzymanie spójności w modelowanym systemie, gdzie maraton developowania featuresów na zmianę z refaktorem i deadline™ raczej tylko utrudnia.

Tylko ze to jest nie możliwe bo musiałbyś znać wymagania i cele projektu od początku. Nawet zakładając że miałbyś taki pełny opis, to dobra, robisz idealnie dobrą strukturę na start, sure.

Ale potem trzeba ten projekt zmienić, dodawać więcej feature'ów, wypełniać requirementy, edytować UI, no po prostu wprowadzać w nim zmiany. Projekt się rozwija, a więc i wymagania co do niego się zmieniają. Rozwiązanie które było odpowiednie kiedyś, teraz już nie musi takie być, czasem więc musisz je zmienić.

Nie mówię że trzeba robić syf, a potem go sprzątać, broń boże. Jeśli możesz coś zrobić dobrze od razu, tak że nie wymaga refaktora, be my guest! Nawet Ci zrobię kawę jak miałbyś tak zrobić.

Ale to nie znaczy że refaktor jest zawsze zbędny, bo czasem natrafisz na głupie rozwiązanie, stare, obsolete, nie odpowiednie, Twoje lub czyjeś, słabej jakości, o zbyt niskich standardach. Wtedy, żeby poprawnie w prowadzić jakiś feature najpierw wypadałoby poprawić ten kod - refaktor.

Caly ten wątek, wszystkie moje wpisy dotyczą tylko tego żeby robić dobry, przadny kod. Albo od początku, jeśli umiesz, super. Ale jeśli już znajdziesz się w sytuacji w której rozwiązania są średnie, popraw je.

1a2b3c4d5e napisał(a):

Raczej to, że chyba za dużo przypisujesz refaktorowi

Ale co jest w tym złego? Jeśli widzę funkcje ze złą nazwą, czemu mam jej nie rename'ować? Jeśli widzę zbyt duże funkcje, czemu nie miałbym ich podzielić na mniejsze. Jeśli widzę zbyt duże klasy, czemu nie miałbym wydzielić mniejszych rzeczy z nich.

2
smieszekheheszek napisał(a):

A wskazywanie np loose coupling jako coś ogólnie dobrego to już jest wgle bez sensu. Wielokrotnie prowadziłem dyskusje z ludzmi którzy twierdzili że luźne połączenia to zło bo w dłuższym czasie prowadzą do "szybkiego sklejania kodu na taśme". Z czym się właściwie zgadzam ale i tak uważam loose coupling jako coś dobrego, ale to w sumie nie ważne, bo tu wchodzimy w obszar gdzie coś jednemu się podoba a drugi powie że to jakiś leszcz napisał czyli jest to takie troche "na oko" co się komuś podoba.

Nie chcę wejść w rozmowę czy loose-coupling powinno być wszędzie, czy nie - zbyt długo.

Ale na pewno, loose-coupling powinniśmy mieć między elementami w naszej aplikacji które powinny się zmieniać niezależnie od siebie. Np na pewno logika aplikacji powinna być oddzielona od widoku/od UI. Te dwa moduły muszą być loosely-coupled między sobą, żeby dało się szybko i tanio edytować aplikacje. Kolejnym przykładem mogłaby też być logika biznesowa i persystencja. Kolejnym dobrym przykładem jest to że testy powinny być loosely-coupled do logiki którą testują. A powód jest bardzo prosty - chcemy móc zmienić UI, tak żeby logika się nie musiała zmienić (to jest właściwie serce MVC). I chcemy zmienić logikę tak żeby testy się nie musiały zmienić.

Więc loose-coupling powinien być na granicach tych modułów/części; gdzie się komunikują. To czy loose-coupling musi czy nie musi być wewnętrz tych modółów? Np czy dwa elementy UI muszą być od siebie loosely-coupled? To nie mnie decydować.

smieszekheheszek napisał(a):
TomRiddle napisał(a):

nie będą wolne od bugów i defektów

nie zgadzam się to już podchodzi pod testy a testy to nie refactor. Refactor to jest coś co ma poszerzyć know how o projekcie i w przyszłości ułatwić czytelność kodu. A dopisywanie testów to dopisywanie testów nie mieszajmy tego z refactorem(często robi się to przy okazji ale to już nie jest czysty refactor).

Jeśli kod jest dobrze napisany; to faktycznie możesz po prostu wejść i napisać testy.

Także refaktor i pisanie testów to nie to samo; ale czasem jedno jest warunkiem drugiego. Czasem wejdziesz do projektu i znajdziesz nietestowalny kod. Autentycznie, kod którego się nie da przetestować, chyba że jakimiś niezdrowymi sposobami albo manualnie.

Więc wtedy masz do wyboru:

  • Albo testować to już całkiem manualnie
  • Albo używać hacków żeby napisać testy na siłę
  • Albo zostawić nieprzetestowane
  • Albo zrefaktorować kod, i napisać normalne testy

Spoiler alert: tylko jedna odpowiedź jest poprawna (zakładając że nadal chcesz rozwijać projekt).

Ale niektórzy czasem podejmują jedną z trzech złych wiadomości, i zostawiają kod nieprzetestowany; a wiadomo że bez testów, jak coś ruszysz to możesz coś zepsuć. Jak jest syf w kodzie to szansa że coś zepsujesz jest spora. I mamy związek przyczynowo skótkowy: słaby kod (ewentualnie słaby kod bez refaktoru) == brak możliwości napisania testów.

Czasem jest też tak, że ludzie jeszcze zaciskają tight-coupled pętle wokół testów; już nawet było to poruszone w tym wątku; że mamy tak dużo when() i verify() z mockito w testach, że nie możemy zrefaktorować kodu łatwo. To jest przykład tight-coupling w testach, i to jest dokładnie to co sprawia że edytowanie logiki jest trudne.

Więc, tak; zgadzam się. Refaktor nie jest kluczowym czynnikiem; bo masz rację, można napisać kod idealnie od początku. Wtedy tak. Jednak tutaj rozmowa toczy się o tym że kod jednak od początku jest ekstremum raczej w drugą stronę :>

Noi jest też druga strona monety: Czasem ciężko coś zrefaktorować, jeśli nie masz testów. Czasem cieżko napisać testy w niepotrzebnie tightly-coupled kodzie. Testy pomagają w refaktorze; a dobra struktura aplikacji i loose-coupling pomaga w pisaniu testów (którą można osiągnąć albo pisząc od razu kod idealnie albo refaktorem ;wink; @smieszekheheszek).

1
1a2b3c4d5e napisał(a):

Raczej to, że chyba za dużo przypisujesz refaktorowi.

Podstawą jest solidnie zamodelowany system na wstępie, a nie próba naprawiania 10 refaktorami.

Jasne, można i tak, ale po co, gdy można postarać się na początku?

Napisanie dobrze na początku ułatwia utrzymanie spójności w modelowanym systemie, gdzie maraton developowania featuresów na zmianę z refaktorem i deadline™ raczej tylko utrudnia.

Mam fundamentalnie odmienne zdanie na ten temat. Każdy pięknie zaprojektowany system ulega szybkiej degradacji bez refaktoru. Umiejetnosc refaktoru - nie tylko na poziomie kodu ale i architektury /evolutionary architecture/) jest DUZO ważniejsze niż pierwszy design, który w 99% i tak nie przetrwa próby czasu.

Jeśli zakładasz, ze na poczatku wiesz wszystko i zrobisz piekny design zeby tylko jak ognia uniknąć zmian - nie dajesz sobie wiele miejsca na popełnienie błędu, bo jak popełnisz (a kiedyś popełnisz) to albo sprawnie zrefaktoryzujesz, albo projekt jest na równi pochyłej w kierunku spaghetti. Kwintesencja waterfalla.

1
TomRiddle napisał(a):

Ale to jest właśnie najlepsza metoda wychodzenia z legacy code'u.

  1. Masz legacy shit code i nic nie warte testy. Każdy refaktor niesie ryzyko, bo nie masz testów. Dopisanie testów jest trudne, bo kod jest nietestowalny.
  2. Dodajesz jeden prosty, dobry unit test. Czyli taki któy nie jest tightly-coupled do logiki, testuje to co ma testować, jest odseparowany od innych testów, działa szybko i rzetelnie na wielu systemach; nie failuje randomowo, i jest w stanie wygryć buga.

Jak chcesz napisać "jeden prosty" test gdy "dopisanie testów jest trudne, bo kod jest nietestowalny"?

TomRiddle napisał(a):

Także refaktor i pisanie testów to nie to samo; ale czasem jedno jest warunkiem drugiego. Czasem wejdziesz do projektu i znajdziesz nietestowalny kod. Autentycznie, kod którego się nie da przetestować, chyba że jakimiś niezdrowymi sposobami albo manualnie.

Więc wtedy masz do wyboru:

  • Albo testować to już całkiem manualnie
  • Albo używać hacków żeby napisać testy na siłę
  • Albo zostawić nieprzetestowane
  • Albo zrefaktorować kod, i napisać normalne testy

Spoiler alert: tylko jedna odpowiedź jest poprawna (zakładając że nadal chcesz rozwijać projekt).

A to powyższe stoi w sprzeczności z tym wcześniejszym. Albo najpierw piszesz testy i potem refaktoryzujesz, albo najpierw refaktoryzujesz bez testów, a potem piszesz normalne testy.


Nie posądzam Cię o brak profesjonalizmu, ale czasami z Twoich wiadomości odnoszę wrażenie, że mówisz piękne rzeczy, ale utopijne i niezgodne z rzeczywistością. Coś jak "ludzie powinni się kochać" albo "scrum nie zajmuje dużo czasu". Jak masz dużo badziewnego kodu, to nie zrobisz refaktora w minutę, ani też nie napiszesz jednego prostego testu jednostkowego. Z radością zobaczyłbym, jak robisz takie rzeczy w ośmiotysięcznikach javascriptowych,

No i dochodzi cały kontekst biznesowy, który Ty całkowicie ignorujesz. W końcu ważniejsze jest, żeby kod był dobry, a nie żeby firma przetrwała na rynku i mogła zarabiać (to była ironia).

0
Afish napisał(a):
TomRiddle napisał(a):

Ale to jest właśnie najlepsza metoda wychodzenia z legacy code'u.

  1. Masz legacy shit code i nic nie warte testy. Każdy refaktor niesie ryzyko, bo nie masz testów. Dopisanie testów jest trudne, bo kod jest nietestowalny.
  2. Dodajesz jeden prosty, dobry unit test. Czyli taki któy nie jest tightly-coupled do logiki, testuje to co ma testować, jest odseparowany od innych testów, działa szybko i rzetelnie na wielu systemach; nie failuje randomowo, i jest w stanie wygryć buga.

Jak chcesz napisać "jeden prosty" test gdy "dopisanie testów jest trudne, bo kod jest nietestowalny"?

Ja najcześciej wybieram najprostszy kawałek obecenie do przetestowania. Część kodu może być bardzo zła; część tylko trochę zła. Można zacząć od tej trochę złej.

Są też inne metody; np zamiast edytować jakąś funkcję w miejscu, możesz napisać jej kopię, przetestować, a potem zacząć stopniowo używać tej nowej w innych miejscach, aż starej już nie ma użyć. Dużo jest na to sposobów, zależy od tego jak w dużym szambie jesteś.

Mogę o tym opowiedzieć więcej jeśli jesteś zainteresowany, jak to dokładnie działa.

Afish napisał(a):
TomRiddle napisał(a):

Także refaktor i pisanie testów to nie to samo; ale czasem jedno jest warunkiem drugiego. Czasem wejdziesz do projektu i znajdziesz nietestowalny kod. Autentycznie, kod którego się nie da przetestować, chyba że jakimiś niezdrowymi sposobami albo manualnie.

Więc wtedy masz do wyboru:

  • Albo testować to już całkiem manualnie
  • Albo używać hacków żeby napisać testy na siłę
  • Albo zostawić nieprzetestowane
  • Albo zrefaktorować kod, i napisać normalne testy

Spoiler alert: tylko jedna odpowiedź jest poprawna (zakładając że nadal chcesz rozwijać projekt).

A to powyższe stoi w sprzeczności z tym wcześniejszym. Albo najpierw piszesz testy i potem refaktoryzujesz, albo najpierw refaktoryzujesz bez testów, a potem piszesz normalne testy.

Okej, widzę czemu ktoś mógłby tak pomyśleć.

Ale tak po prostu jest. Im więcej refaktora robisz (innymi słowy, im bardziej odseparowane są elementy od siebie im lepiej kod jest zaprojektowany), tym lepiej się wprowadza testy. Oraz, zarówno; im masz więcej lepszych testów, tym lepszy refaktor możesz zrobić.

To są takie dwie machiny napędzające się nawzajem.

Jeśli obie stoją to będzie ciężko ruszyć którą kolwiek z nich; ale to właśnie musimy zrobić, po kawałku odpalać dwie na raz, na początku bardzo powoli, ale z czasem ruszą. I mówiąc "bardzo powoli" mam na myśli, że np jeden test, albo jeden prosty refaktor. Jednostkowo, te rzeczy można zrobić szybko, ale trzeba ich zrobić bardzo dużo na początku. Takiej średniej jakości projekt powinien mieć w mojej opinii około 2000-5000 testów jednostkowych, taki standardowy. Duże projekty, odpowiednio dużo więcej. Nie napiszesz tego w miesiąc czy dwa. Ale możesz zacząć od 1, potem od 5, 10, etc. i tak dalej.

Afish napisał(a):

Nie posądzam Cię o brak profesjonalizmu, ale czasami z Twoich wiadomości odnoszę wrażenie, że mówisz piękne rzeczy, ale utopijne i niezgodne z rzeczywistością. Coś jak "ludzie powinni się kochać" albo "scrum nie zajmuje dużo czasu".

No; ale co ja Ci poradzę. Ja tak robię w swoich projektach zarówno w pracy jak i prywatnie, i to jakoś działa. Także dla mnie to nie jest utopia tylko pewien konkretny (co prawda wysoki, ale konkretny) standard.

Osobiście, moim zdaniem największym problemem stojącym "rzeczywistości" na drodze jest przekonanie że się nie da. Gdyby tylko pokazać programistom: "Patrz, widzisz: tak mogę zrobić refaktor, tak mogę napisać test", to by to robili, tak mi się wydaje. Ale ponieważ mają bardzo mocno zakorzenione "Nie da się", albo mocno zakorzenione takie przekonanie "sprzątanie kodu jest po to żeby było ładnie, nie po to żeby działało", to ciężko walczyć z wiatrkami.

W Star Wars, jak się szkoliło Jedi to był taki etap nauki "Wyciszenie mąrości głupca". U programistów by się to przydało ;)

Afish napisał(a):

Jak masz dużo badziewnego kodu, to nie zrobisz refaktora w minutę,

Jak masz dużo badziewnego kodu, to nie zrobisz refaktora w minutę, Zależy co masz na myśli mówiąc "nie zrobisz refaktora". Czy masz na myśli to żę zrefaktorujesz cały projekt, albo chociaż jeden modół? Oczywiście że nie.

Ale czy zrefaktorujesz jedną funkcję lub jedną zmienną? Już możesz to zrobić w minutę; nawet nie wiem czy nie krócej. Ja przynajmnej bym mógł jedną funkcję.

Afish napisał(a):

ani też nie napiszesz jednego prostego testu jednostkowego.

Hmm, zależy. W dobrym środowisku; np kiedy piszesz nową funkcję albo dopisujesz kod do już dobrze zaprojektowanego kodu jaknajbardziej. Mi się czasem udało zrobić kilka testów w minutę. Czasem się da jeden test dodać w kilka sekund, i nie zartuję teraz. I to dobry test, rzetelny, nie mający false-negative'ów, i false-positive'ów i nie couplujący się do kodu. Oczywiśce nie zawsze jest to możliwe, czasem trzeba usiąść.

Jeśli natomiatst dostajesz metodę pełną globalnego stanu, statycznych zmiennych, poukrywanych zależności, taką która miesza logikę z widokiem, albo bóg wie co jeszcze, to oczywiście że nie napiszesz go szybko; ale nie dlatego że nie da się napisać testu szybko, bo da się - ale trzeba najpierw odseparować testowaną funkcję od reszty syfu, w miarę możliwości, i to zajmuje najwięcej czasu. Samo napisanie testu jest szybkie i proste (zakładając oczywiście że wie co się robi).

Afish napisał(a):

Z radością zobaczyłbym, jak robisz takie rzeczy w ośmiotysięcznikach javascriptowych,

Możemy kiedyś znaleźć taki i zrobić eksperyment.

Ale opowiedz mi, co Ci się wydaje. Myślisz że to co mówię brzmi spoko, ale gdybyś faktycznie miał spróbować odnieść takie praktyki do rzeczywistości to by się nie udało?

Afish napisał(a):

No i dochodzi cały kontekst biznesowy, który Ty całkowicie ignorujesz. W końcu ważniejsze jest, żeby kod był dobry, a nie żeby firma przetrwała na rynku i mogła zarabiać (to była ironia).

No oczywiście że ważniejsze jest żeby produkt robił to co ma robić - i jeśli stworzono go z myślą o zarabianiu to powinien to robić. I faktycznie może tak być, że g**no kod zarabia na siebie. Jeśli robię cokolwiek, to właśnie po to żeby firma przetrwała jak najdłużej, poprzez nie zwiększanie kosztów utrzymania oprogramowania. Najlepszy przykład to legacy code: w wielu firmach znajdziesz bardzo stare produkty, które są absolutnie odrażające gotowe, najgorszy kod na świecie; ale działają. Tylko one mają prawo działać tylko dlatego że nie ma żadnych zmian w nich. Nikt nie przychodzi, i nie mówi żeby to zmienić, to zmienić, to usprawnić. Także taki program, mimo że okropny, to jest stabilny i działa. 0 bugów, 0 dodatkowych feature'ów, po prostu działa tak jak ma działać. No ale z przykrą konsekwencją tego że jak coś w nim zmienisz to się posypie. Trochę tak jak domek z kart, dopóki go nie dotkniesz (albo coś innego go nie dotknie) to będzie stał. I ja bym bardzo chętnie zostawił taki legacy code tak jak jest.

Ale jak widać, że nowe zmiany dochodzą co tydzień albo codziennie; to musisz zadbać o to żeby te zmiany się dało wprowadzać szybko i tanio.

0
TomRiddle napisał(a):

Ja najcześciej wybieram najprostszy kawałek obecenie do przetestowania. Część kodu może być bardzo zła; część tylko trochę zła. Można zacząć od tej trochę złej.

Są też inne metody; np zamiast edytować jakąś funkcję w miejscu, możesz napisać jej kopię, przetestować, a potem zacząć stopniowo używać tej nowej w innych miejscach, aż starej już nie ma użyć. Dużo jest na to sposobów, zależy od tego jak w dużym szambie jesteś.

Jasne, że są, nawet książki o tym ludzie piszą, długie na kilkaset stron. Tylko to nie zajmuje minuty.

TomRiddle napisał(a):

No; ale co ja Ci poradzę. Ja tak robię w swoich projektach zarówno w pracy jak i prywatnie, i to jakoś działa. Także dla mnie to nie jest utopia tylko pewien konkretny (co prawda wysoki, ale konkretny) standard.

No i masz liczby potwierdzające, że refaktoring bardziej się opłaca? Jak ostatnio rozmawialiśmy, to nie miałeś żadnych danych biznesowych, tylko swoje przekonanie. Ja w swoich projektach mam konkretne liczby pokazujące, że pisanie najlepszego kodu nie jest optymalne.

TomRiddle napisał(a):

Osobiście, moim zdaniem największym problemem stojącym "rzeczywistości" na drodze jest przekonanie że się nie da. Gdyby tylko pokazać programistom: "Patrz, widzisz: tak mogę zrobić refaktor, tak mogę napisać test", to by to robili, tak mi się wydaje. Ale ponieważ mają bardzo mocno zakorzenione "Nie da się", albo mocno zakorzenione takie przekonanie "sprzątanie kodu jest po to żeby było ładnie, nie po to żeby działało", to ciężko walczyć z wiatrkami.

Bo walczą dla samego programowania, a pomijają cały kontekst biznesowy i inżynieryjny. Jak pokażesz szefostwu, że kosztowny i trwający refaktoring przyniesie w przyszłości zyski, przy uwzględnieniu sytuacji rynkowej, pozycji firmy, konkurencji i konkretnych liczb, to wtedy dostaniesz błogosławieństwo na każdym szczeblu.

TomRiddle napisał(a):

Jak masz dużo badziewnego kodu, to nie zrobisz refaktora w minutę, Zależy co masz na myśli mówiąc "nie zrobisz refaktora". Czy masz na myśli to żę zrefaktorujesz cały projekt, albo chociaż jeden modół? Oczywiście że nie.
Ale czy zrefaktorujesz jedną funkcję lub jedną zmienną? Już możesz to zrobić w minutę; nawet nie wiem czy nie krócej. Ja przynajmnej bym mógł jedną funkcję.

A idziesz do szefostwa z prośbą o zadanie na Jirze do refaktoryzowania nazwy zmiennej? No bądźmy poważni, albo rozmawiamy o rzeczywistości i naprawie poważnych problemów, albo przerzucamy się, że zmiana nazwy zmiennej trwa minutę, bo szkoda czasu na dyskusję o takich bzdurach.

TomRiddle napisał(a):

Hmm, zależy. W dobrym środowisku; np kiedy piszesz nową funkcję albo dopisujesz kod do już dobrze zaprojektowanego kodu jaknajbardziej. Mi się czasem udało zrobić kilka testów w minutę. Czasem się da jeden test dodać w kilka sekund, i nie zartuję teraz. I to dobry test, rzetelny, nie mający false-negative'ów, i false-positive'ów i nie couplujący się do kodu. Oczywiśce nie zawsze jest to możliwe, czasem trzeba usiąść.

O matko, znowu wyciągasz sobie jakieś pojedyncze słowa. Mogę to napisać jasno i pełnym zdaniem ----->Jak masz kijowy kod, to nie napiszesz dobrego testu jednostkowego w minutę<----. Nie zmieniaj sobie założeń na "dopisujesz do już dobrze zaprojektowanego kodu".

TomRiddle napisał(a):

Jeśli natomiatst dostajesz metodę pełną globalnego stanu, statycznych zmiennych, poukrywanych zależności, taką która miesza logikę z widokiem, albo bóg wie co jeszcze, to oczywiście że nie napiszesz go szybko; ale nie dlatego że nie da się napisać testu szybko, bo da się - ale trzeba najpierw odseparować testowaną funkcję od reszty syfu, w miarę możliwości, i to zajmuje najwięcej czasu. Samo napisanie testu jest szybkie i proste (zakładając oczywiście że wie co się robi).

Okej, czyli już wiemy, że refaktoring robimy minutę (bo to zmiana nazwy zmiennej), dobry test piszemy w minutę (jak już mamy odseparowany kod od syfu). To w takim razie jak nazywa się ten proces "zamiany syfnego kodu w kod, który można testować"? Zdajesz sobie sprawę, że uprawiasz logomachię?

TomRiddle napisał(a):

Ale opowiedz mi, co Ci się wydaje. Myślisz że to co mówię brzmi spoko, ale gdybyś faktycznie miał spróbować odnieść takie praktyki do rzeczywistości to by się nie udało?

Dam Ci ośmiotysięcznik w JS i nie zrobisz mi refaktoringu ani dobrego testu w minutę. Ponieważ masz jakieś niespójne definicje, to zaznaczę, że chodzi mi o zrobienie praktycznej zmiany, jak w kodzie produkcyjnym, a nie zmianę nazwy zmiennej czy napisania testu do nowej funkcji napisanej na boku.

TomRiddle napisał(a):

Ale jak widać, że nowe zmiany dochodzą co tydzień albo codziennie; to musisz zadbać o to żeby te zmiany się dało wprowadzać szybko i tanio.

Właśnie o to chodzi: szybko i tanio nie oznacza najszybciej i najtaniej. Kontrolowanie długu technicznego jest ważną częścią inżynierii oprogramowania, trzeba wiedzieć, kiedy olać refaktoring, a nie wywyższać się ponad menadżera. Wszystko poniżej jest oparte na błędnym założeniu.

TomRiddle napisał(a):

Mam wrażenie, że ludziom się wydaje że jak dodadzą trochę tech debtu, to on ich spowolni w przyszłości, ale to będzie daleka przyszłość, liczona w latach. Błąd. Weź napisz sobie prywatny projekt, byle jaki. Ściągnij jakąś pierwszą lepszą bibliotekę do czegokolwiek, gier, exceli, UI, czegokolwiek, zacznij pisać jakiś program który chcesz, kalkulator, paint, grę, edytor. Przez pierwszych pare godzin idzie sprawnie, bo jesteś na świerzym projekcie; ale po paru godzinach takiego testowania POC masz plik z 500-1000 linijek, i już on Cię spowalnia. Po paru godzinach zaledwie, dopóki go nie podzielisz na klasy i funkcje. Gówniany kod łapie programistów szybciej niż sobie zdają z tego sprawę.

Stabilny rozwój projektu powinien mieć techdebt feedback o wartości 0. Tzn z miesiąca na miesiąc mamy 0 techdebt. Projekt się po prostu rozwija stabilnie.

Dodatni feedback loop dodawania techdebtu może się skończyć tylko dwoma rzeczami:

  • Albo zmiany są zbyt kosztowne i projekt umiera
  • Albo podjęta jest decyzja o przepisaniu, i wtedy:
    • W 10% szans jeśli jest wyskoi budżet, motywacja i możliwości - to udaje się przepisać apkę, i wracamy na koniec cyklu
    • W 90% przepisanie się nie udaje i projekt jest tam gdzie był

Można też tego uniknąć cofając techdebt; tak żebyśmy mieli negatywny przyrost techdebtu w projekcie; i to jest w zasadzie jedyny sposób zeby wyratować projekt. Zrobić ewolucję, zamiast rewolucji. Stopniowo zwiększać jakoś projektu, do momentu w którym wprowadzanie dodatkowych zmian stanie się proste.

1 użytkowników online, w tym zalogowanych: 0, gości: 1