Masturbacija

Nedugo nakon što sam započeo ovaj blog, Vuk je citirao izjavu Alexandera Kjerulfa, koju sam ja zatim uzeo kao slogan bloga:

Vizija bez izvedbe je halucinacija.

(Digresija: Zanimljiva stvar se događa ako tu izjavu upišete u Google: u prvih nekoliko rezultata ćete je pronaći pripisanu raznim velikim ljudima, od Thomasa Edisona preko Alberta Einsteina do Stevea Casea. Ali nije važno tko je autor, izjava i dalje stoji.)

No danas mi je sinulo da se može konstruirati i druga izjava, svojevrstan antipod ovoj prvoj:

Izvedba bez vizije je masturbacija.

Ako pogledamo oko sebe, vidjet ćemo da su znakovi ovog pravila svuda oko nas, a u mojoj branši najbolje se mogu vidjeti u mnoštvu Web development frameworka koji niču kao gljive poslije kiše. Danas kao da svaki Web developer ima ideju kako najbolje napraviti razvojno okruženje, pa potroši mjesece na konstruiranje raznih hijerarhija klasa, lukavih rješenja pristupa bazi ili templating enginea. Odmah treba reći da nisu svi frameworci nastali na taj način — najbolji primjer je sveprisutni Ruby on Rails, koji je izvorno bio samo temelj aplikacije Basecamp, a isto vrijedi i za Django te još bezimeni framework kojeg naš Ilija planira izvući iz activeCollaba. No, brojna rješenja su nastala samo kako bi se razvili neki teorijski koncepti, ili iz autorovig ego-tripa, bez konkretne, praktične namjene — WACT, Willowgarden i QCodo samo su neki od njih (posebna su kategorija klonovi Ruby on Railsa, kao što su CakePHP ili PHP on Trax).

To ne znači da se na tim platformama ne može razviti suvisla aplikacija — no kako već neko vrijeme tvrdim, frameworci u osnovi nikome ne koriste, jer su s jedne strane ili preopćeniti (za one koji ne žele programirati, već samo složiti nekakav jednostavan dinamički site; za takve su idealni CMS-ovi kao što su Joomla, Xoops, Typo3 ili Drupal) ili preograničeni (za programere koji ne žele otkrivati toplu vodu, ali i imaju potrebe za većom fleksibilnošću; njima više koriste generički libraryji kao što su ADOdb, EZcomponents ili Solar). No developeri frameworka prečesto imaju običaj igrati se s nebitnim detaljima, fokusirajući se na besmislene fines — moj omiljeni primjer je feature da se tablice u bazi nazivaju u množini (npr. ‘people’) a ActiveRecord klase u jednini (npr. ‘person), i da framework to sam prepozna i poveže. To je takav očit primjer suvišnog i nepotrebnog kodiranja da se to ne može nazvati drugačije nego masturbacija.

Dakle možemo zaključiti da su vizija i izvedba dvije strane istog novčića, i jedno bez drugog nema puno smisla. Tako da ću sad sukladno tome i modificirati svoj slogan. :)

Popularity: 50% [?]

17 Comments so far

  1. carr on September 9th, 2006

    na slazem se oko ovoga people/persons.
    zasto bi to bilo glupo i nepotrebno, nigdje nisi objasnio?

    po meni je to odlican feature, jer stvarno kad pogledam svoje tablice sve su users/user, entries/entry itd..

    cijela ideja je da ako se nesto unutar tvojeg razvoja ponavlja na 80% mjesta, prozovi to konvencijom, a ovih ostalih 20% posebnim slučajem, kojeg možeš hendlati odvojeno.

  2. berislav on September 9th, 2006

    Nisam rekao da je sasvim beskorisno: samo da je nepotrebno pimplanje detalja.

    Naime, u RoR-u i sličnim frameworcima, u većini slučajeva korištenje ActiveRecorda izgleda otprilike ovako:


    class Person extends ActiveRecord {}
    $person = new Person();

    Gornji kod podrazumijeva cijelu gomilu koda koji provjerava nazive i tako dalje, a svejedno nema koristi ako si ti recimo tablicu u bazi nazvao “osobe” (ja se osobno držim pravila da mi je sve na engleskom ali to ne mogu reći za većinu programera koje znam). A cijeli taj kod je savršeno suvišan ako se može napraviti (a većina implementacija ActiveRecorda to dopušta) ovo:

    $person = new ActiveRecord('people');

    I to je sve — DHH (ili od koga je on već pokupio ovaj koncept ActiveRecorda) radi klasičnu programersku grešku, a to je brkanje klasa i objekata. Nema nikakve potrebe raditi cijelu novu klasu ako ne dodajemo novu funkcionalnost; a ovdje se pošlo od (krive) pretpostavke da moramo, i složilo se vagon koda samo da bi se omogućila nepotrebna funkcionalnost.

    Ako treba dodati neku funkcionalnost — npr. da se neki broj prije spremanja u bazu zaokružuje i slično — onda je opravdano raditi novu klasu, ali i tada sve implementacije ActiveRecorda omogućuju nešto kao:

    class Person extends ActiveRecord
    {
    protected $table = 'people';

    // neki dodatni kod
    }

    Dakle cijela gomila koda da bi se u svakoj klasi izbjegla jedna dodatna linija, a koja (ta gomila koda) pritom radi samo u engleskom jeziku. Kako je to korisno? Kako bi to jedan moj bivši kolega nazvao, sve je to drkica.

  3. maxturbator on September 9th, 2006

    gdje se drka tu je dom ;)

  4. carr on September 9th, 2006

    Slazem se da to nije nesto prestrasno korisno bez cega se ne moze.

    Da ne ulazim u rails problematiku (jer ga ne koristim), reci cu zasto sam ja ovaj (slican) koncept implementirao u svoj framework.

    Uvidio sam da mi se na 80% mjesta pojavljuje relacija user/users (nisam isao toliko daleko da ubacim za nepravilne mnozine).

    Onda sam skuzio da posvuda imam action “add_user”, “update_user”, “delete_user” koji u 80% slucajeva rade potpuno istu stvar.

    Pa sam postavio ovako stvar
    - ako pozivamo action add_user, i ako taj action nije negdje posebno definiran sto radi, pretpostavi da dodaje u tablicu “users”

    itd…dakle na dosta mjesta u frameworku, npr.kraj vecine recordova imam polje tipa “document_time_published” koje mi uvijek prima time()…dakle jos jedna pretpostavka.

    U principu, zivcira me pisati non-stop jedan te isti kod, ili ga kopirati, pa sam koristeci razne konvencije, koje su zapravo same nikle iz prirodnog razvoja aplikacije pojednostavio si posao.

    Takodjer mi je to korisno u ranoj fazi razvoja, ako zelim sloziti brzi CRUD za neki dio aplikacije jer se “sve samo napravi”.

    A nije da sam bas napisao tonu koda za to, mislim da ima jedno 30-ak redova.

  5. berislav on September 10th, 2006

    I upravo si potkrijepio moju tvrdnju. Umjesto da si uzeo neki od frameworka sam si napisao kôd koji radi upravo ono što tebi treba.

  6. carr on September 11th, 2006

    ma naravno, frameworkovi su za loše programere i curice :)

    nebi htio da se krivo razumijemo - ne podrzavam one-size-fits-all frameworkove (barem meni osobno nikad nisu legli jer nikad nemaju ono sto meni tocno treba), ali podrzavam razne korisne librarye, bilo client side (tipa prototype) ili server side (tipa swift mailer) koji rijesavaju manje probleme - tu se slazemo cinimise potpuno.

    vise sam komentirao ovaj detalj oko activerecorda i imenovanja tablica…i to je obradjeno gore.

    pozdrav.

  7. Ilija Studen on September 12th, 2006

    Kada potpun stranac pogleda tvoj kod:

    $person = new Person();
    $person->getName();

    je mnogo logičnije nego:

    $person = new ActiveRecord(’person’);
    $person->name;

    Pisanjem podklase ti si odvojio osobu od načina na koji se sami podaci “skladište”. Nakon 6 meseci ti možeš da odlučiš da je DB previše nezgodan za problem koji želiš da rešiš i da bi ti više odgovaralo skladištenje u XML fajlove. Ili pak podatke o osobama vučeš sa nekog drugog servera u mreži kroz definisan API. U tom slučaju uzmeš klasu Person i samo je prešaltaš na novi sistem skladištenja umesto da projuriš ceo kod i traižiš ActiveRecord(’person’).

    Šta pokušavam reći: Person je jedan od tipova podataka kojima barataš u aplikaciju i treba da bude posmatran van načina na koji skladištiš podatke. Meni je to jednostavno prirodnije.

    Btw, ja koristim generator. On jednom prđe kroz tabele, smućka sve i “uprži” ih u bazne klase. Kad se nešto promeni samo opet projurim generator i on updatuje fajlove kojima su potrebne izmene. Meni je to bolje od ActiveRecorda.

  8. Berislav on September 12th, 2006

    Ilija, potpuno si u pravu, i priznajem da nisam ispravno naglasio svoju poantu. Nije problem u kreiranju klasa — tu stoji ovo što si napisao — već u suvišnom kodu.

    Da budem konkretniji, kompozicija je uvijek bolje rješenje od nasljeđivanja. Dakle, klasa Person ne bi trebala naslijediti klasu ActiveRecord, već bi trebala sadržavati atribut recimo $dataSource, koji bi pak bio ili ActiveRecord ili pak bilo koja klasa koja implementira određeni interface, nazovimo ga Persistable.

    U slučaju da se koristi ActiveRecord, imali bismo liniju koja kaže $this->dataSource = new ActiveRecord(’person’) koju jedinu treba izmijeniti da bi se dobila npr. podrška za XML.

    U idealnom rješenju imali bi (abstract) factory koji bi prema potrebi generirao način perzistencije, pa klasu Person više ne bismo ni trebali dirati.

  9. tomo on September 13th, 2006

    Što se tiče korisnosti framework-a, mislim da si tu potpuno u krivu.
    Zašto?
    Naveo si RoR kao pozitivan primjer, a CakePhp kao negativan. To po meni ne stoji. RoR je bio pionir, i napravio malu revoluciju u načinu programiranja, te su se mnogi programeri oduševili njegovom intuitivnošću i enormnom uštedom vremena pri programiranju.
    Slična stvar se može donekle postići ako si sam skrojiš vlastite klase za DB abstraction, Form generation, User autentification, MVC posebno i sl. No takav domaći frejmvork poznaje samo ekipa koja ga je pravila. Veliki frejmwork koji razvija više ljudi kontinuirano, i ima veliku bazu korisnika koji ga usmjeravaju, testiraju i unapređuju je jednostavno osuđen da bude bolji. A i lakše je napraviti tim od više pojedinaca ako su koristili isti frejmwork, nego ako su koristili različite.
    Zašto je CakePHP super, isto kao i npr. Symphony?

    Zato što iste te uštede vremena, produktivnost, uredno programiranje i razumljivost koda dugo vremena nisu bile široko dostupne u php-u. Sad napokon jesu.

    Dio CakePHP tima je radio na razvoju RoR-a, te i dalje surađuje s 37signals. Znaju kako bi stvari trebale funkcionirati, i ne samo da su uspješno prenijeli mnoge funkcionalnosti RoR-a u PHP, nego su otišli i mnogo dalje i dodali su, tj. i dalje dodaju neke nove i fenomenalne stvari. Jedan samo primjer je i MemCache koji bi trebao uskoro biti uključen u frejmvork.

    Ovakve površne ocjene bi mogle nekoga tko tebe smatra boljim programerom od sebe odvratiti od upoznavanja s takvim proizvodom, a ja osobno mislim da je to vrlo štetno. Eto.

  10. Berislav on September 13th, 2006

    Ovakve površne ocjene bi mogle nekoga tko tebe smatra boljim programerom od sebe odvratiti od upoznavanja s takvim proizvodom,

    Ha, ne laskam si da imam takav utjecaj na programere… :)

    U svakom slučaju, sve što si napisao stoji, ali to ne pobija ono što sam ja napisao; dapače čak i potvrđuje. Aktivnosti koje si naveo, ljudi koji se trude oko toga itd, to je sve fokusirano na razvijanje funkcionalnosti frameworka, što je aktivnost koja postoji sama zbog sebe.

    Nisam naveo RoR kao nešto što valja a CakePHP kao nešto što ne valja (kako si, čini mi se, shvatio) — naglasio sam različite puteve kojima su nastali. RoR u početku uopće nije postojao, već je razvijen Basecamp, a onda je iz njega izvučen RoR; CakePHP nije izvorno postojao kao dio nekog projekta, već je odmah napravljen kao kopija/emulacija/port/whatever. Po meni čak ni samo izvlačenje RoR-a kao frameworka nije imalo smisla; kopiranje nečega što nema smisla još je manje korisno.

    Slična stvar se može donekle postići ako si sam skrojiš vlastite klase […] No takav domaći frejmvork poznaje samo ekipa koja ga je pravila

    Nema nikakvog razloga zašto bi morao sve sam pisati — i u PHP-u i na drugim platformama postoji bezbroj libraryja i gotovoga koda za sve što ti padne na pamet. Dovoljno je samo reći CPAN, PEAR, PHP Classes, RubyGems itd. Problem frameworka je što oni ograničavaju tu mogućnost izbora; kažu mi npr. moraš koristiti Active Record a meni treba Data Mapper; ili mi koristimo Smarty, a ja bih Savanta; itd. I onda da bih dobio ono što želim moram kopati po kodu i prilagođavati framework.

    U pravu si da “sklepani” framework razumije samo ekipa koja ga je pravila, i to je dobra stvar. Jedini kome je bitno da neki framework može “jednostavno koristiti” bilo tko su oni koji rade framework kojeg može “jednostavno koristiti” bilo tko. Cilj ostalih je napraviti aplikaciju koja će raditi, i koju će oni sami razumjeti te ju moći prenijeti na druge programere uz malo edukacije.

    Pazi, da se razumijemo: nije baš da generički frameworci ne mogu nikome koristiti. Ali oni su korisni samo za relativno mali krug “intermediate” programera koji znaju više od običnog Webmastera čiji je domet instalacija Joomle, no još nisu stasali dovoljno da bi znali procijeniti prednosti ovog ili onog template enginea, database abstractiona ili mailing libraryja.

  11. tomo on September 13th, 2006

    Ok, razumijem da ti ne vidiš korisnost od toga. No mišljenja sam, da su korisni samo za mali krug “skoro pa programera”, onda ne bi npr. Alistapart magazin bio rađen u takvom frejmvorku. A njega rade top-knotch web developeri.

    Izmeđi ostalog ono što će pokazati da si u krivu je aplikacija koju s dečkima u firmi razvijam. :)

  12. Berislav on September 13th, 2006

    Iskreno, izuzetno me zanima o kakvoj se aplikaciji radi, kao i koja je to firma (ako hoćeš, javi mi na mail). A u svakom slučaju, izuzetno me zanimaju i tvoja iskustva s frameworkom — bilo bi zanimljivo pročitati o tome, a posebno me zanimaju iskustva na rubnim područjima: koliko ste morali izlaziti iz osnovnih parametara frameworka, zašto, te kako ste to riješili. Jasno, moguće je i da vam to neće biti potrebno, što me također zanima.

    Ovo gore o čemu sam pisao proizlazi s mojim iskustvima kod težih Web aplikacija koje su zahtijevale više od osnovnog CRUD-a (ne kažem da frameworci mogu raditi samo CRUD-ove, ali to je uvijek polazna točka).

    U svakom slučaju tebi i dečkima držim fige, i javite kako je bilo. :)

  13. Ilija Studen on September 13th, 2006

    Pre neki dan sam se sreo sa zanimljivim problemom. Naime, po defaultu će framework izvučen iz activeCollaba koristiti sličnu strukturu foldera kao Rails (strukturu koju i sad koristi), što zato što se pokazala kao dobra, što zato što je ljudima već poznata. Tu ne treba izmišljati toplu vodu IMO.

    Prvih par aplikacija koje napravim sa ovim frameworkom će koristiti default strukturu foldera i njima će ona ležati bez problema, ali jedna izuzetno bitna aplikacija koja će ga koristiti će zahtevati malo drugačiji raspored foldera - activeCollab. Plugini će uneti opštu pometnju - kontroleri, viewevi, klase modela, helperi, stilovi, JavaScript - sve će to biti rasuto na sve strane i uvezivano po potrebi. Potreba za takvim ponašanjem dovodi do dva izbora: ili framework pada u vodu jer ne može da odgovori na te potrebe ili mora biti dovoljno fleksibilan da može da se prilagodi programeru i zahtevima projekta umesto da bude obrnuto (da se programer i projekat prilagođavaju frameworku).

    Rešenje: nešto što sam nazvao Engineom (nije mi palo na pamet ništa pametnije). Unutar njega je implementirano ponašanje frameworka - način na koji oni nalazi kontrolere i vieweve, način na koji se incijalizuje, način na koji rezerviše i oslobađa resurse - sve. Unutar frameworka se nalazi default implementacija enginea, a unutar projekta klasa koja ga proširuje, ali bez implementacije. Sve radi samo od sebe pošto je sve implementirano u baznom frameworku. Ako je programeru potrebno da na ovaj ili onaj način izmeni ponašanje frameworka dovoljno je da overrideuje metode engina unutar klase koja mu je kulturno spremljena pri kreiranju projekta.

    Verujem da je moguće promeniti ponašanje frameworka i kod drugih okruženja, ali pitam se da li su oni dizjanirani da lako odgovore na taj zahtev.

  14. Sinisa Dukaric on September 15th, 2006

    Citam i ne znam …
    Nisam valjda evoluirao pa jos uvijek drzim do svog “frejmworka” koji bi vise u stvarnosti bio gomila meni svojstvenih konvencija, klasa, filesystem strukture i sve to povezano u jednu filozofiju kodiranja.

    No, evo - nedostatak vremena je ucinio svoje i na jednom projektu sam toplo preporucio uporabu Symfonya-a bez griznje savijesti.

    Ostao bih suzdrzan u polemikama “za ili protiv” - rekao bih da ovisi o onome sto zelis i kako zelis napraviti te o odnosu vrijeme/funkcionalnost.

    Mozda upravo ovakva funkcionalnost koju Ilija spominje u komentaru iznad mojeg je nesto sto bi bilo izuzetno korisno.

    No nista ne bi nazvao drkanjem - govorimo ovdje o gomili pretezno kvalitetnog OSS koda, respect.

  15. damir on September 22nd, 2006

    Kod je izražajniji ako se koriste jednina/množina pa mislim da nisi odabrao baš najsretniji primjer masturbacije ;)

    Primjerice has_and_belong_to_many deklaracija u railsima parent klasama na obje strane relacije dodaje hrpu metoda i puno je prirodnije da su nazivi u množini:

    category.products.delete(product1)

    ili obratno

    product.categories.find(bla).title

    Istina za imena tablica i nije toliko bitno pa se takvo ponašanje može isključiti globalno u postavkama, ili se može u klasi navesti ime pripadajuće tablice i polja ako se radi s nekom legacy bazom

  16. retro on September 23rd, 2006

    Tek sam sad vidio ovaj blog entry, inace bi i prije komentirao.

    Railsi su sto se frameworka tice dosta drugacija prica, jer rubyi ima otvorene klase, tako da jednostavno overrideas metodu koja ti ne pase i bok. Apsolutno sve mozes zapakirati u plugin, loadati i imati hrpu svojih promjena koje za tebe imaju smisla.

    Sto se tice jednine/mnozine, to stvarno doprinosi citljivosti koda. Npr kad pozoves

    company.adminstrator

    znas da firma ima jednog administratora i da ces natrag dobiti njegov objekt, a kad pozoves

    company.administrators

    znas da ima vise administratora i da dobivas array objekata. Meni osobno takav pristup jako odgovara i ubrzava programiranje. A ako ne zelis pratiti konvencije, jednostavno ces morati pisati vise koda…

  17. Berislav on September 23rd, 2006

    Retro i Damir, skroz ste fulali poantu onog što sam napisao i otišli u krivom smjeru. To nema veze ni s Rubyjem, ni s Railsom, ni s jedninom ili s množinom. Niti s time što RoR nije kraj svijeta što se tiče Web developmenta.

Leave a reply