Honza Malý31.5.2011Zpět

Kvalitní programování není přežitek!

Proč vlastně v nadpisu tak samozřejmá věta? Zdálo by se, že v druhém desetiletí 21. století už pro nějaké to programování není místo, že se vše generuje automaticky a člověk jen u stroje magicky zadává povely a očekává „dostatečně dobrý“ výstup. Žel, ta doba je ještě daleko a zakázkový vývoj založený na programování požadované funkčnosti má stále své místo, byť se jeho podoba radikálně mění k lepšímu. Jak pro zadavatele, tak pro programátory, slušelo by se dodat. Jenže...

K vývoji webových aplikací a webů má bohužel dnes přístup také každý patlal. Víte, že k nastartování kariéry coby programátora webových systémů stačí začátečnická znalost několika jazyků a systémů a open-source software? Není tedy divu, že se do oboru s vidinou rychlých zisků žene každý, kdo čerstvě odmaturoval (a kolikrát ani to ne). A protože narozdíl od znalostí překypují sebevědomím, i dnes stále dostáváme pod ruku po předchozích tvůrcích systémy pokřivené, zcela nesmyslně zabezpečené a mizerně rozšiřitelné. O jejich kvalitě majitelé a provozovatelé většinou ani netuší, dokud nepřijde první problém. Hlavně, že to šlo levně...

Nyní je pro laiky programováním nedotčené, a zejména zákazníky potencionální, správná doba na otázku: „A proč bych vlastně měl dbát na kvalitní realizaci?

Jsou dva zásadní důvody, které si můžete dovolit podcenit jen v případě, že dokážete žít s důsledky svého rozhodnutí – náročnost změn a bezpečnost vaší aplikace.

Problematické změny

Skvěle to uvedl D. Grudl v příspěvku „Mám nejhoršího klienta, stále mění zadání“, který mě zčásti k napsání tohoto příspěvku přiměl. Sebelepší systém je k ničemu, pokud je nějak vyvinut a dále nevylepšován. Sami přijdete na řadu změn až za běhu, se zkušenostmi ze skutečného používání. Čím víc vás to bude bavit a čím víc času tomu budete věnovat, tím více se výsledek bude lišit od původního návrhu. Pokud systém v tomto bodě nebyl navržen s respektováním základních pravidel slušnosti, dříve nebo později narazí, rozšiřování se stane bolestivým a drahým pro vaši peněženku.

DRY princip doslova říká: "Každý kousek informace musí mít svou jedinou, jednoznačnou a autoritativní reprezentaci v systému [Wikipedia].

Pro snadnou rozšiřitelnost musí systém splnit dvě věci: princip DRY (Don't repeat yourself, tedy neopakuj se) a relativně snadná dohledatelnost takto uložené informace. Tyto dvě podmínky kladou jisté požadavky na vnitřní strukturu kódu, a ač to zní jednoduše, je ďábelsky složité jim v praxi co nejvíce dostát – je to otázka praxe a zkušeností. Proto také vznikly celé systémy předpřipraveného kódu – frameworky – do kterých budovaná aplikace „zapadne“ a ony už se díky svému správnému návrhu postarají o dodržení elementárních zásad rozšiřitelnosti a bezpečnosti. Ve světě programovacího jazyka PHP jsou nejznámější frameworky například Zend, CodeIgniter, Prado, Symfony, z českých luhů pak Nette.

Problém je v tom, že tyto frameworky vyžadují investici času programátora k jejich pochopení a částečně vývojáře omezují v tom, co si může dovolit. Jsou proto velmi často ignorovány a na řadu přichází „poctivá ruční práce“ – v tom nejhorším slova smyslu, jaké si dokážete představit.

Příklad z praxe: u jednoho klienta jsme převzali jeho původní intranet a dostali za úkol rozšířit jej o celou novou kartu v administraci. Jaké bylo naše překvapení (pravda, nevelké), když jsme objevili, že pod slovem systém se ve skutečnosti skrývá panoptikum hrůzy, kde se různé nesouvisející části kódu vzájemně střídaly, prolínaly, donekonečna opakovaly a schovávaly se pod snůškou zastaralých postupů. Nezbývalo, než zatnout zuby, posbírat veškerou svoji praxi a empatii ve snaze porozumět původnímu tvůrci a pustit se do „pravé, nefalšované ruční práce“, tentokrát alespoň v rámci možností správně. Jen opravit položky v menu vyžadovalo pečlivé dohledání a přepsání informace v deseti různých místech. Některé prvky (například role uživatelů) byly „tvůrcem“ pouze předepsány, nikde se ale již neřešily, nevyžadovaly. Požadavek klienta, který žádal zobrazování různých informací různým rolím uživatelů, se k jeho překvapení musel řešit složitě a místně. Přitom klient byl kdysi tvůrcem ubezpečen, že vše funguje, jak má.

Ale teď pozitivněji: v Kurzoru si na změny věříme. Některé drobnější díky práci na vlastním frameworku 3OS zvládáme velmi rychle. Proto jsme zavedli technickou podporu formou nevelkého ročního paušálu, která garantuje splnění jakékoliv souvislé programátorské práce do 15-20 minut času programátora, což klienti oceňují. Například e-shop Lahůdkárium jsme postupným rozšiřováním funkčnosti dostali na úroveň systémů z jiné ligy – a za daleko příznivější cenu.

Chce-li si někdo kompenzovat neschopnost svého programového řešení účtováním předražených víceprací a nadáváním na přebujelé požadavky klientů, prosím. Proti nim chápeme kouzlo změny (proto provádíme např. uživatelské testování) a doufáme, že výše uvedení na trhu dlouho nezůstanou.

Nebezpečné chyby

Horší je výskyt chyb, a to nemyslíme zrovna chyby, kdy aplikace spadne nebo prokazatelným způsobem nefunguje tak, jak má. Možná ani netušíte, kolik možných nebezpečí číhá na relativně celému světu otevřené webové aplikace a systémy. XSS, Code injection, SQL injection, Session hijacking, zjištění uložených hesel... Problém začátečníka a programovacího jazyka PHP (zejména tohoto nástroje) je v tom, že si vzájemně dovolí vše a neznalý příliš netuší, co všechno se může stát. Ono to vyžaduje opět znalosti a praxi.

Pro pochopení příkladu: jedná se o útok Cross Site Scripting (XSS), který má za úkol podstrčit na nechráněné místo HTML kód, v tomto případě kód, který nezobrazuje, ale vykoná nějaký příkaz. A pokud se komentáře zobrazí všem, pak i kód se vykoná pro všechny stejně... Přečtete si více o XSS na wikipedii.

Příklad ze života: jeden náš známý programátor realizoval web pro jednorázovou studentskou akci. Web, na který v průběho toho dne mohlo zabrouzdat určitě pár tisíc návštěvníků. Na webu byl prostor pro komentáře, a nás napadlo, co takhle vložit tam místo textu HTML značku SCRIPT a něco v ní vykonat (pro neznalé vysvětlení nalevo)? Světe div se, ono to fungovalo. A protože návštěvníci byli pozorní studenti, velmi se bavící vyskakováním potvrzujícího okénka s naším pozdravem, zanedlouho se našel někdo, kdo rovnou celý web přesměroval na stránky své oblíbené seznamky. No schválně, představte si, že tohle někdo udělá vašemu webu v jeho den D... je konstatování „aspoň jsme při tvorbě webu ušetřili“ ospravedlnitelné?

Možná budete argumentovat, že pro web distributora násad na lopatu není třeba raketová bezpečnost, ale uvědomte si, že i jedno hloupé opomenutí (možná záměr) programátora, že hesla v databázi nebude jednocestně (nevratně) šifrovat znamená, že k heslům v původní podobě má přístup on a každý další, kdo vidí do databáze (např. provozovatel serveru). Jak složité pro něj je toto heslo vyzkoušet třeba u vašeho emailu?

Webové aplikace také často shazuje závislost na konkrétních verzích programů, na kterých běží, a které jsou na serveru často cizího poskytovatele. Když ten změní verzi nějaké komponenty (například databáze), jak na to aplikace zareaguje? A kdo to opraví, je-li původní programátor někde v zahraničí, na vaše emaily nereaguje a poskytovatel odmítá změnit verze zpět – protože je to proti jeho zájmu udržet si hosting aktuální a bezpečný? Světe div se, i to se nám stalo:

Příklad ze života: klient se na nás obrátil s tím, že se mu nedaří přihlásit na žádný z jeho intranetových systémů. Provedli jsme malou analýzu a zjistili, že programátor původního systému použil funkci v databázi, která byla určena pouze pro interní potřeby této databáze a dokumentace na to výslovně upozorňovala. Když pak poskytovatel po roce změnil verzi databáze, začala funkce najednou fungovat jinak – byla přece bez záruky – a šifrování hesel se rozpadlo jako domeček z karet. O nečekaná překvapení tedy u špatně navržených systémů rozhodně není nouze!

Jak tedy na lepší kvalitu kódu?

Prověřovat, prověřovat, prověřovat. Zajímejte se, jak váš dodavatel pracuje, neberte na lehkou váhu audit třetí strany. Jazyk PHP a běžně používané systémy jako MySQL nejsou v principu špatné, jen všem měří stejným metrem a nabízejí mnoho volnosti. Bohužel, ani kvalitní framework v PHP neznamená, že máte vyhráno. Pokud někdo framework neovládá nebo jej nechce využít správně, bude pracovat svým neefektivním stylem stále dál a chyby se budou opět množit, rozšíření komplikovat. Proto se nevyhýbejte ani možnostem jako Ruby on Rails nebo Django, které jsou založené na jiných jazycích. Mají svá interní pravidla a i méně zkušení programátoři v nich staví aplikaci již od základu kvalitně a bez větších chyb.

Dobrou zprávou také je, když váš dodavatel kód udržuje – hlídá si jeho verze a je schopen sledovat a orientovat se ve změnách kódu. K tomu slouží verzovací systémy jako Subversion, Git, Mercurial. Ještě lepší zprávou je, když testuje svůj kód nějakým automatickým postupem. Například pomocí tzv. unit testů zjišťuje vždy, zda právě provedená změna nezavlekla do stávajících funkcí nějakou závadu. Pomocí nástrojů jako Selenium lze dokonce při testech simulovat uživatele webové stránky a kontrolovat si, zda se na webu vše vykoná tak, jak má. Dá se říci, že nástrojů a postupů, které zlepšují výstup programátora, je celá řada, a nemělo by být pouze na něm, aby si vybíral, který z nich použije a který už ne. Zadavatelé, tlačte na své dodavatele, buďte náročnější, nekupujte zajíce v pytli. Buďte více podezíraví k jednotlivcům, kteří vám nabízejí programování aplikací za podezřelých cenových a jiných podmínek.

Pomůžeme vám!

Nepodvedl vás dodavatel? Jak si váš systém stojí z hlediska rozšiřitelnosti a bezpečnosti můžeme zhodnotit většinou už po zběžném nahlédnutí do zdrojových kódů aplikace. Kontaktujte nás a zcela zdarma, nezávazně váš systém prověříme. A pokud je to opravdu zlé, nabídneme vám řešení. Jde přece jen o vaše data a váš úspěch!

Honza Malý
maly@kurzor.net
+420 722 211 443
Honza se specializuje na návrh webů a UI, věnuje se také vývoji.