Przemyślenia po coding-rage’u: Agile są lepsze!

Przemyślenia po coding-rage’u: Agile są lepsze!

Dłubię pewien projekt.
<hermetyczny żart>Spędziłem 2 ostatnie dni i 2 ostatnie noce, czyli cztery dni, na kodzeniu.</hermetyczny żart> Staram się pisać zgodnie ze sztuką, dbać o detale, automatyzować co się da i pisać testy jak grzeczny chłopiec. Klepać kod zaczynając od niższych warstw w PHP, myśląc nad schematem bazy danych itp itp.

Gdy czytam cudzy kod i widzę, że jest niechlujny, bez testów, z ręcznym, by nie powiedzieć murzyńskim automatyzowaniem, coś mnie trafia.

Zacząłem się zastanawiać, dlaczego, na Latającego Potwora Spaghetti, idzie mi to tak wolno? Fakt, że kilka razy samemu coś spieprzyłem i próbowałem cofać zmiany ręcznie zamiast wesprzeć się Gitem. Fakt, że w końcu nauczyłem się jak używać takich wynalazków jak composer i bower. Fakt, że to mój pierwszy projekt w Laravel 4 (mam doświadczenie z Laravel 3). Ale do jasnej, dlaczego idzie mi to 3x wolniej, niż w trakcie uczenia kogoś, kto PHP widzi pierwszy raz na oczy?

Zacząłem myśleć nad tą sprawą. W pracy korzystam z RedBean, phpQuery i SlimFramework jako prostego routera z obsługą filtrów. Niby mam tam przygotowane snippety które sprawdzają dane z $_POST pod kątem zgodności z formularzem i zapisem do bazy danych ($_POST->phpQuery do formularza->html->phpQuery po polach formularza->redbean). Dziesiątki razy podczas zajęć z kursantami pisaliśmy autoryzację, czasem nawet sprawdzenie ról, prosty CMS.

Za każdym razem, gdy kogoś uczę, po murzyńsku dogrywamy zależności. Po murzyńsku, znaczy się ręcznie. Testujemy z kursantem kod również metodą murzyńską. Gdybym miał tłumaczyć jak działa phpUnit i Mockery, to kursant zrobiłby jeszcze większe oczy niż do tej pory, a o tym, że musiałby mi uwierzyć na słowo, że tak się robi to już nawet nie wspominam. W czasie jaki mam do wykorzystania NIE da się o wszystkim powiedzieć i wszystkiego pokazać. Domknięcia są proste, gdy ktoś wcześniej zobaczył jak działa jQuery, phpQuery z jQuery czerpie garściami, tylko selektory trochę bardziej zaawansowane, a kod trochę bardziej imperatywny i pisany bardziej wprost niż callbackowo-eventowy.
Baza danych? Jaka baza danych? RedBean sam robi schemat, dodaje potrzebne kolumny na zawołanie, zmienia ich typy gdy potrzeba. Foreach opisany w nawiasie wyżej – dane z $_POST trafiają do bazy danych, wstępnie zabezpieczone przed sql injection. Foreach w drugą stronę – dane z bazy danych trafiają do formularza, wstępnie zabezpieczone przed xss. Nie wiem, na ile to są pewne zabezpieczenia, nie miałem okazji ich sprawdzać. Seed bazy danych robiony banalnie prostym skryptem, na minimalnie szczątkowych danych. RedBean ma kilka często używanych metod opartych o statyczną fasadę – dispense, load, find, save, trash. Bez większej filozofii. Prosty design – jest Bootstrap. Składanie szablonu? PhpQuery wstrzykuje kawałki HTMLa do zbiorczego pliku. Pisanie formularzy? Bootsnipp, z gotowymi snippetami i z generatorem formularzy. Czego tutaj więcej potrzeba?

Opcjonalnie można nawet robić wstępną walidację danych po stronie klienta za pomocą angularjs ale jeszcze nie miałem okazji. Za mało czasu w trakcie kursu.

Mam nawet własny prototyp takiej aplikacyjki, z rozszerzonym SlimFramework i automatycznym ładowaniem funkcji/domknięć na wzór Laravel, aby nie trzymać wszystkiego w jednym olbrzymim pliku, a także z naiwnym RESTem opartym o BeanCan z RedBean, w którym na dobrą sprawę można wybrać i zmienić wszystkie dane gdyby człowiek się postarał. 🙂

I dotarło do mnie. Zardzewiałem. Z powodu wewnętrznego lenia, zacząłem traktować nowości typu composer jako ciekawostki, a nie praktyczne narzędzia. Przyzwyczaiłem się do często używanego pakietu narzędzi, a gdy przyszło mi pisać coś poważniejszego – to po prostu wolniej idzie. Gdy pracuję nad zleceniem, trzymam się innej metodyki niż gdy kogoś uczę. Takie coś leżące blisko waterfall z testami. W trakcie kursu mamy Agile pełną gębą, z testami murzyńskimi, bez specyfikacji, na czuja. I, do cholery ciężkiej, to jest totalnie dużo szybsze niż to, co robiłem przez ostatnie dni.

Może teraz też powinienem tak robić? :> A testy czy inne pierdoły pisać dopiero później? A co jeśli nie będzie mi się chciało? 😀

Ps. Nie, nie mam nic przeciwko murzynom i nie jestem rasistą. Mógłbym jeśli nie lubisz wykorzystywania murzynów, podstaw “chińczyk”, a jeśli i o nich się martwisz, wstaw mrówkę czy coś innego pracowitego, co też robi i nie dyskutuje.

Agile cats can fly

  • Mam wrażenie, że mem „hermetyczny dowcip”, który pierwszy raz usłyszałem u Siwej, się przyjął.

  • Zależy jak rozumiesz testy. Jeżeli xUnitowe to moim zdaniem jednak powinny powstawać razem z kodem (nie jestem fanatykiem TDD, ale jeżeli ktoś daje radę to nawet lepiej). Jeżeli testy integracyjne, to spokojnie mogą moim zdaniem poczekać jak będzie wolniejsza chwila .

  • Unit testy. Pisałem coś w sumie niewielkiego, ale o sporej liczbie miejsc, w których się mogłem rąbnąć.
    I wyszło, że się rąbnąłem.
    Na szczęście wydało się wtedy, gdy napisałem testy, a zanim zacząłem wykorzystywać ten błędny kod.

  • Z ciekawości, piszesz jeszcze swojego klona Joggera czy się poddałeś? (jeśli cię denerwuje to pytanie to dziabnij komentarz i nie było rozmowy)

  • Staram się pisać zgodnie ze sztuką, dbać o detale, automatyzować co się da i pisać testy jak grzeczny chłopiec. Klepać kod zaczynając od niższych warstw w PHP, myśląc nad schematem bazy danych itp itp.

    Sztuka doradza raczej pisanie od najwyższych warstw, a potem wgłębianie się w detale, o ile się orientuję:)

  • Myślę, że z obu stron da radę. Na studiach mnie uczyli, że najpierw projektujesz, apotem piszesz. Na Google Summer of Code mi pokazano inne podejście – piszesz jak chcesz, a potem przepisujesz. Też działa.

  • Pewnie się da, ale jak idziesz „od góry” to przynajmniej będziesz miał w tabelach dokładnie co trzeba. Przepisywanie i tak cię nie ominie:D

  • Jak jedziesz od góry, ryzykujesz to, że złożoność cię przerośnie.

  • Na niższych też ci się to może zdarzyć. W mojej opinii. Trzeba mieć chyba po prostu umiejętność skupienia się na jakiejś funkcjonalności.

  • sprae

    Leń czyli brak motywacji pojawia się wtedy, kiedy czujesz, że to co robisz niczego ci nie daje.
    Na tej kanwie powstało „Po pierwsze ma działać!”.

  • @d4rky: Z kilkoma kolejnymi kursantami napisałem prosty panel administracyjny do systemu blogowego. Dalej mi się zwyczajnie nie chce, to się nudzi 😛 Do tego mam inne priorytety, fajniejsze projekty, a faza na pisanie kobyłki typu jogger gdzieś poszła przezimować, czeka na lepsze czasy. Gdyby mi zależało, mógłbym machnąć taki rapid: panel + blog + główna, ale myślę, że to by się do rozwijania nie nadawało. No i srało błędami na lewo i prawo, gdy coś się pozmienia, a tego przecież nie chcemy 🙂

  • @Sigvatr: pisząc od góry, muszę pisać na ślepo, nie widząc w pełni, co będzie niżej. I, jak dee napisał, może mnie przerosnąć złożoność.
    Poza tym, z moją zdolnością do koncentrowania się, rozmieniłbym się na drobne 🙂
    A pisząc od dołu, łatwiej się skoncentrować na pojedynczych funkcjonalnościach.

    Na studiach widziałem oba podejścia, zarówno projektowanie->pisanie jak i pisanie->przeprojektowanie, ten drugi model jest zwykle lepszy, bardziej trafia do klientów.

  • @d33tah: Tekst „macie 7 dni i 7 nocy, razem dwa tygodnie” słyszałem od wykładowcy, bazodanowca, który zajmował się tworzeniem systemu SARNA gdy powinien mieć z nami ćwiczenia XD
    Potraktowałem go jako hermetyczny, bo usłyszałem go na WAT. Dobrze wiedzieć, że i poza murami tej twierdzy też to żyje 🙂

  • Nie chodziło mi o treść żartu, tylko określenie „żart hermetyczny”. A dowcip złapałem dopiero teraz, kiedy przeczytałem go drugi raz 😀

  • @mt3o: dlatego kocham Railsy – nawet naklepany na szybko kod nadaje się do rozwijania i nie sra błędami 😉 Ale doskonale cię rozumiem, bo mam dokładnie to samo.

  • @mt3o: pisząc od góry, projektujesz, nie piszesz na ślepo, jest różnica. Klient zwykle gwiżdże na to, co jest w kodzie, tym bardziej gwiżdże na filozofię powstania, argument jest „więc inwalidą” 🙂

  • Hmm.. To trochę tak, jak prowadzę zajęcia dotyczące PHP.
    Muszę się nad tym zastanowić.
    Bo jeśli masz rację, to znaczy, że to jak do tej pory najczęściej pracowałem, jest złe. Tylko wtedy musiałbym się bardzo pilnować, żeby nie mnożyć funkcjonalności którą dopiero później będę musiał oprogramować.

  • Unit testy powinny powstawać razem z kodem. Ostatnio dostałem zlecenie: Mamy tu taki obrzydliwy, kilkuletni skrypt, który trzeba pilnie zrefaktorować. Póki co, napisz testy. Brrr. Nigdy więcej nie zwątpię, że pisanie testów zawczasu ma sens. Uściślając: jeżeli nie piszesz testów od razu, to najczęściej w końcowym efekcie wyjdzie Ci coś kompletnie nietestowalnego. 😉

    Co do pisania od góry/od dołu: moim zdaniem zdecydowanie od góry. To jest bardziej naturalne: najpierw definiujesz: co to jest, a dopiero potem: jak to działa. Innymi słowy: piszesz sobie funkcję main(), paćkasz w niej jakieś nieistniejące funkcje i nagle – tadam – już wiesz, co masz pisać dalej. Ja pisząc od dołu nigdy nie wiedziałem, dobra, co, k…, dalej??? 🙂