pondělí 23. září 2013

Snižování rizikovosti softwarových projektů

… aneb díky zpětné vazbě rychleji kupředu

Děláme to dobře? Bude se zákazníkovi a uživatelům výsledek líbit? Máme hodně nebo málo bugů? Stíháme harmonogram projektu? Jaká jsou v projektu největší rizika? Ustojí architektura systému reálnou zátěž? ...

Množství neúspěšných softwarových projektů je pro nás varováním, abychom byli obezřetní a neustále hledali způsoby, jak rizikovost vývoje software snižovat. Důsledkem neúspěšného zvládání rizik mohou být obrovské finanční ztráty při produkování nestabilního software. Za dobrý výsledek se nedá považovat ani software rigidně splňující původní požadavky, avšak uživatelsky nepřátelským způsobem. A v mnoha případech dokonce projekty umírají ještě dříve, než se dostane prvotní verze mezi reálné uživatele.

Jsem přesvědčen, že kouzelnou instancí úspěšných projektů je mimo jiné i kvalitní zpětná vazba. Je nutné, abychom byli schopni zpětnou vazbu získávat v co nejkratší době a nezkreslenou a to navíc po celou dobu trvání projektu. Díky zpětné vazbě lépe držíme správný směr a rychleji řídíme projekt směrem k úspěšnému výsledku. Dále popisuji vybrané techniky, které nám pomohou tuto drahocennou komoditu lépe získávat.

Jednotkové testy (Unit Tests)

Zdrojový kód je živý organismus, který prochází neustálým vývojem a změnami. Má-li být projekt úspěšný, je kvalitně navržený zdrojový kód s minimální chybovostí naprosto esenciálním požadavkem. Psaní jednotkových testů je technikou, která nám dává do rukou prostředek pro získávání zpětné vazby o stavu kódu v řádech desítek sekund.

Zpětná vazba je dvojího typu. Dokážeme ověřit, zda-li kód opravdu dělá to, co od něj očekáváme - na co není napsaný test, to jako by v systému ani neexistovalo. Za druhé, dostáváme důležitou informaci o kvalitě návrhu tříd a potažmo celého systému. Na oba indikátory bychom měli být schopni rychle reagovat a problémy řešit.

Programování bez psaní jednotkových testů je mizerná loterie, ve které se obvykle prohrává. Vede k objevování chyb složitějším způsobem a v pozdějších fázích vývoje. Vkrádá se nejistota a strach zasahovat do existujícího kódu, který není pokrytý testy. Téměř se nerefaktoruje, vznikají duplicity a logickým vyústěním je zvyšování nákladů na celý projekt. Bez testů není možné aplikovat některé z dále popsaných technik.

Podobně jako jednotkové testy, potřebuje náš projekt testy integrační. Jedná se o kategorii testů, které prověřují vzájemnou spolupráci více reálných tříd v požadovaných scénářích.

Průběžná integrace (Continuous Integration)

Podívejme se na práci programátora z perspektivy celého vývojového týmu. Jeho chyby totiž mohou nepříznivě ovlivnit zbytek týmu. Nesoustředěný, spěchající nebo unavený kodér promítne změny na server a odchází domů (v horším případě vypíná telefon a odjíždí na třítýdenní zahraniční dovolenou). Nevšimnul si ale, že aplikace nejde zkompilovat nebo že rozbořil pár jednotkových testů. Jiný člen týmu si vezme změny ze serveru a v ten okamžik má problémy i on. Nezkompiluje, prohodí pár jadrných slov (které ve slovníku spisovné češtiny nenajdeme) a začne hledat pachatele. Nakonec se situace nějak vyřeší, ale zpomalení lidí a někdy celého týmu je vždy nepříjemné a drahé.

Řešením je zavedení techniky průběžné integrace. Jedná se o kontrolní mechanismus, který po každém promítnutí změn na server spustí posloupnost ověřovacích kroků. Běžně se provádí kompilace celého projektu, spouští se jednotkové testy, hlídají se pravidla kladená na formátování kódu, provádí se statická analýza kódu, apod. V řádu několika minut dostává programátor, který změny propagoval na server, zpětnou vazbu o tom, že jeho balík změn je nebo není problematický. V zájmu celého týmu by měl na případný problém okamžitě reagovat a uvést verzi na serveru do korektního stavu. Nebrzdit zbytek týmu musí být nejvyšší prioritou.

Týmy, které nemají rozjetý CI mechanismus, se často dostávají do záseků. Reakce na problémy se prodlužují. Dohledávání příčin je složité, protože není vždy snadné určit, který balík změn problém způsobil. Každá propagace změn na server je provázena lechtivým pocitem v podbřišku. Strach a nejistota dlouhodobě paralyzují práci týmu. Není také zřejmé, zda-li je aktuální serverová verze v dobrém stavu a tedy nasaditelná např. do testovacího prostředí.

Revize (Reviews)

Často nedoceňovanou technikou je vzájemné revidování práce. Revidovat můžeme specifikaci požadavků, návrh řešení, zdrojový kód nebo jiné výstupy vaší práce. Odpůrci argumentují vysokou časovou náročností a tedy malou ROI. Pokud to však myslíme s kvalitou aplikace vážně, je tato technika nepostradatelná. Téměř vždy je pohled na řešený problém očima někoho jiného užitečný. Např. při revizi kódu můžeme připomínkovat použitý algoritmus, řešit čitelnost kódu, objevit chyby nebo jiná potenciálně problematická místa. Revizemi si členové týmu vzájemně předávají zkušenosti, učí se a zvyšují bus-factor (zastupitelnost) vývoje částí aplikace.

Kdy a v jakém rozsahu je vhodné provádět revize? Vždy, když je dokončen úkol menšího rozsahu. Ideálně práce, která se vejde do jednoho dne. V méně zkušených týmech mohou být revize delší - objeví se více připomínek. Např. v našem týmu je poměr času strávený prací a její revizí asi 10 : 1. Poměr kolísá v závislosti na složitosti úkolu a aktuální míře “hnidopišství” revizora. Preferujeme spíše méně formální revize, buď za účasti programátora (při složitějších věcech, kde je vhodný vysvětlující komentář) nebo bez něj.

Párové programování (Pair Programming)

Některé věci se lépe dělají ve dvou - třeba programování. Práce v páru je kontinuální diskuze nad problémem a zvoleným řešením. Zpětná vazba je okamžitá. Dochází k vzájemnému revidování a téměř s určitostí bude výsledek společné práce vždy kvalitnější než při individuálním přístupu. Revidování je elementární činností této techniky a platí pro něj všechna pozitiva popsaná výše.

Ne všechny týmy mají vhodné prostředí pro aplikování této techniky. Efektivita je přímo úměrná “sociální kompatibilitě” členů týmu. Někdo je natolik introverdní, že práce ve dvojici jej stresuje a nedokáže ze sebe dostat to nejlepší. Také ne každý úkol je vhodné dělat ve dvojici. Obecně se dá říci, že čím je úkol složitější, tím je párování užitečnější.

Zákazník na pracovišti (On Site Customer)

Zákazník přesně ví co chce, co nejpodrobněji nadefinuje požadavky na systém, udělá se analýza, pak estimace, podepíše se smlouva. Vývojový tým dostane zadání, několik měsíců na něm dělá bez asistence zákazníka a poté, jako mávnutím kouzelného proutku, představí zadavateli funkční a skvělé řešení. … Tak a teď tu o Červené karkulce.

Dobrá tedy, domluvíme raději pravidelné týdenní pracovní porady se zástupcem zadavatele. Lepší, ale stále to není ono. Co takhle mít schopného člověka od zákazníka k dispozici kdykoliv? Mít možnost mu zavolat nebo se s ním sejít ihned, jak si to situace vyžádá? Mnohem lepší. Nebo raději, kdyby fyzicky seděl s týmem v jedné místnosti? Ideální.

Zákazník nám platí a pouze na jeho hodnocení záleží, zda-li bude náš projekt úspěšný. Na začátku vývoje obvykle nemáme dostatečně jasnou představu o tom, jak by měl výsledek vypadat. A i když máme, tak se v průběhu určitě změní. To je zákon softwarového vývoje. Zafixovat požadavky na začátku a dogmaticky trvat na jejich dodržování je možná dobré s ohledem na dodržení podmínek smlouvy, ale málokdy pro výslednou kvalitu. Nebraňme se změnám zadání, buďme na ně připravení. Je naprosto legální, že požadavky se v čase vyvíjí podle toho, jak se tým i zadavatel učí rozumět problémové doméně. Zapojme zákazníka co nejvíce do vývojového procesu a budou z toho profitovat obě strany.

U některých typů projektů, kdy nemáme skutečného zákazníka, je také vhodné zadefinovat interního zákazníka, který bude vystupovat v podobné roli jako skutečný zákazník. Bude zastupovat uživatele vyvíjené aplikace a bude zodpovědný za akceptaci výsledku. Měl by nám být nápomocen při diskuzích a připomínkování a neměl by být z našeho vývojového týmu.

Akceptační testování

Akceptační testování je nezbytný proces pro ověření toho, že aplikace dostála závazkům vyplývajících z požadavků. Akceptační testy tvoří zároveň aktuální dokumentaci k systému. Ideální akceptační testy jsou automatizované, tedy kdykoliv snadno spustitelné. Pokud má aplikace GUI, pak zřejmě bude nutné akceptační testy provádět také ručně. Akceptační testy měl psát zástupce zákazníka ve spolupráci s členy QA týmu. Ne programátor.

Správně napsané akceptační testy dodají kvalitní zpětnou vazbu o použitelnosti a stabilitě aplikace. Procházení jednotlivých testovacích případů je také měřítkem celkového postupu projektu. Získáváme informaci o tom, kolik práce je hotovo a kolik ještě zbývá. Ale znáte to, Paretův princip náš optimismus ve finále stejně zchladí. :)

Malé verze (Small Releases)

Hodně projektů se prodražilo a mnohé úplně zkrachovaly, protože se dostaly do obrovských problémů s vydáním první funkční verze. Na první pohled vypadá snaha uvolnit “superverzi” aplikace jako dobrý nápad. Projektový tým chce vydat aplikaci až v okamžiku, kdy bude splňovat všechny must-have požadavky a ty budou navíc propracovány do nejmenších detailů. Ale my to takhle určitě nedělejme.

Vývoj software je jako většina profesí především o emocích, motivaci, komunikaci, důvěře a dalších netechnických záležitostech. Lidem se mnohem lépe plní rozsáhlejší úkoly, pokud jsou rozděleny na více menších. A navíc každý úkol by měl být zakončen dosažením cíle. Naším prvořadým cílem je vydat aplikaci a dostat ji k uživatelům. Teprve v tomto okamžiku má naše práce nějakou reálnou hodnotu. Do té doby nemáme nic.

Uživatelé ocení, pokud jim brzy dodáme verzi aplikace, která jim přináší nějaký užitek. Navíc rychle získáme zpětnou vazbu z reálného provozu, která je pro nás nejcennější. Vydávejme verze tak často, jak je potřeba. Funkcionalita nemusí být dotažena k dokonalosti, ale nesmíme vypouštět bugy. Pro časté automatizované uvolňování verzí je nutné mít vybudovánu kvalitní infrastrukturu pro Continuous Delivery. Jde o automatizaci vytváření verze, spouštění validačních mechanismů, nasazování do testovací prostředí a ve finále také do produkce. Obsahuje některé procesy známé z Continuous Integration.

Prototypování (Prototyping)

Softwarové projekty jsou plné rizikových míst. Rizikem se může stát například použití nové technologie, návrh architektury, problematický framework, komunikace s novým fyzickým zařízením, napojení na špatně zdokumentovanou službu, apod. Zkušenosti vývojářů se projeví právě ve schopnosti dopředu tato rizika vytipovat a prověřit. Nejrizikovější části projektu řešme co nejdříve. Jako vhodná metoda pro validaci rizik se obvykle jeví prototypování.

Prototyp je zjednodušená a tedy levná varianta aplikace nebo její části, která nám pomůže prověřit potenciální riziko. Při vytváření prototypu není nutné trvat na vysoké interní kvalitě. Důležitá je především rychlost vytvoření a získání zpětné vazby o problému. Po ověření problému život prototypu končí. Produkční kód se začne budovat znovu, tentokrát v produkční kvalitě.

Často se prototypuje uživatelské rozhraní. V takovém případě nejde ani tak o prověřování rizika, zda-li něco nepůjde, ale spíše o ujasnění představy o výsledném produktu. Levně můžeme připravit více variant řešení.

Minimální tržní produkt (Minimum Viable Product)

Jak už bylo popsáno výše, měli bychom se vyhnout snaze dodat veškerou zamýšlenou funkcionalitu najednou. Vývoj by byl zdlouhavý a zpětnou vazbu z reálného provozu bychom získali příliš pozdě. Technika Minimum Viable Product nabádá k tomu, abychom zadefinovali minimální rozsah funkcionality, který reprezentuje vizi vašeho produktu, tu rychle vyvinuli a nasadili do provozu. Získáme tak ohlasy od skutečných uživatelů z reálného provozu. Začneme se rychle učit, jak na produkt uživatelé reagují, jaké by se hodily další funkce a které funkce jsou nevyužívané a tedy nadbytečné. Ideální použití je v situaci, kdy je uživatelská spokojenost skutečně naším prvořadým cílem. To znamená vždycky. Státní IT projekty se nepočítají. ;)

Další členové rodiny technik pro získávání zpětné vazby od skutečných uživatelů jsou Win-loss Analytics, Beta Programs, Focus Groups nebo Market Interviews.

Iterace (Iterations)

Rozdělit řešení rozsáhlého projektu na menší části s jasně definovanými akceptačními kritérii je základem úspěchu softwarového projektu. Zapomeňte na smrtící vodopád a naučme se organizovat práci do iterací. Iterace dostanou náš tým do potřebného pracovního rytmu a získáme důležitou zpětnou vazbu o jeho rychlosti a možnostech. Každá iterace (doporučená délka 1-3 týdny) začíná plánováním úkolů včetně estimace, pokračuje realizací a končí předvedením výsledků a retrospektivou.

První iterace mohou být o sesbírání potřebných informací, vytváření vývojové infrastruktury, zavádění agilních technik, prototypování, vytvoření základních projektových artefaktů, apod. V dalších fázích už řešíme konkrétní požadavky a začínáme produkovat první validní výstupy. Jako první si zvolme nejprioritnější nebo nejrizikovější požadavky, které nás donutí implementovat vertikálně skrze všechny vrstvy aplikace. Učíme se tak co nejrychleji rozumět všem aspektům realizace naší aplikace.

Komunikace v týmu (Team Communication)

Jejda, ty děláš na stejném úkolu jako já!
Vy jste poslední dny dělali tenhle úkol?! Ten má ale aktuálně nízkou prioritu!
Na pár dnů jsem se zasekl s tímhle. -- Proč neřekneš, zrovna tohle jsem nedávno řešil!

Dochází k podobným zmatkům i u vás. Nevíte přesně, kdo na čem aktuálně dělá? Pak je nezbytné zlepšit komunikaci v týmu. Je na zodpovědnosti vedoucího týmu, aby zajistil optimální komunikační prostředí a vzájemnou informovanost všech členů.

Využívejme techniky společných plánovacích schůzek, díky kterým všichni vědí, co se bude dělat a co je prioritní. Zabudujme do svého pracovního dne krátké týmové stand-up rychloporady. Jedná se o efektivní způsob, jak se vzájemně informovat o aktuálně řešených úkolech a problémech. Nezapomínejme na společné retrospektivy, kde se dozvídáme o úspěšnosti plnění našich plánů. Na retrospektivách je také prostor pro diskuzi nad pracovními postupy, které používáme. Nebojme se zahodit postupy, které nefungují a pouze nám přinášejí zbytečnou zátěž.

Postupnými malými změnami v našich pracovních postupech můžeme ve výsledku dosáhnout velkého zlepšení. A o to nám přeci jde. Vím to, protože jste tento článek dočetli až sem. ;)

sobota 14. září 2013

Život s debuggerem

… aneb debugování jako indikátor problémových postupů

Byl pátek třináctého, navíc 256. den v roce - svátek programátorů a já jej oslavil téměř 10-tihodinovou programovací šichtou. Po celý den jsem se pokoušel striktně dodržovat TDD přístup. Padající test, nejmenší nutná implementace, zelenáč. A takhle pořád dokola. Jako když rytmicky dýcháte - nádech a výdech. Práce šla od ruky a unit testy rodily produkční kód pěkně podle plánu. Za celý den jsem použil debugger snad jen dvakrát. V kontextu událostí jsem si utvítnul trochu provokativní tvít:

Akce rodí reakci a ta také přišla. Twitter je plný šikovných lidí se spoustou zkušeností z praxe a já jsem za jejich reakce moc rád. Zároveň je Twitter omezený na 140 znaků a to se pak těžko argumentuje. Dejte mi šanci utvítnutou myšlenku trochu vysvětlit formou tohoto příspěvku.

Dopředu je potřeba přiznat, že bych se bez možnosti debuggování aplikace určitě neobešel. Na druhou stranu pozoruju, že s postupným profesním vývojem se u mě nutnost používání tohoto nástroje postupně snižuje. Snažím se hledat postupy, které vnášejí do vývoje aplikace větší jistotu a menší chybovost.

Unit testy a TDD

K jedné z největších revolucí v mých pracovních návycích došlo v okamžiku, kdy jsem začal psát unit testy. Potenciál unit testů využijeme naplno až v kombinaci s TDD nebo nějakou jinou test-first technikou. Ta nás nutí přemýšlet dopředu o struktuře a funkcionalitě kódu. Rozkládat komplexnost řešení na malé samostatné scénáře použití. Jedním z klíčových aspektů je postupná, iterativně přidávaná funkcionalita. I při budování rozsáhlé aplikace metodou malých přírůstků je pravděpodobné, že budete mít stav věcí pod neustálou kontrolou. Určitě mnohem více, než když nakódujete desítky řádek kódu a pak se je snažíte najednou otestovat a integrovat.

Krůčky jsou tak elementární, že téměř ani není nutné spouštěný test debugovat. Třídy jsou testovány v izolaci a pokud navíc dodržujeme např. SOLID, rozpadá se nám funkcionalita do malých tříd s jasně definovanými zodpovědnostmi. Takové třídy se pak dobře testují. Práce bez debuggeru je mnohem rychlejší.

Integrační testování

Jistota z unit testů se přenáší do integračních testů, které jsou cílené na ověření spolupráce mezi více reálnými třídami. V případě dobře navržených rozhraní a podpory IoC kontejneru je celý proces integrace, opět po postupných krůčcích, transparentní a méně náchylný k chybám. Máme odzkoušené jednotlivé třídy? Pak zřejmě bude fungovat i jejich kompozice.

Při integraci se do akce dostávají také frameworky třetích stran. Míra nutnosti použití debuggeru pak bude zřejmě odvislá od naší znalosti jejich API a také od toho, jak dobře použitelné tyto frameworky jsou. Nerozumím používanému frameworku? Asi si hodně užiju debugování.

Čistý, přehledný a jednoduchý kód

Programátor dospívá v okamžiku, kdy se mu přestává líbit složitý kód a začíná hledat prostředky zajišťující jednoduchost. Skrze kód komunikujeme s počítačem a s ostatními členy týmu. A je to podobné jako jiné formy komunikace. V případě, že něčemu skutečně rozumíme, umíme to vyjádřit jednoduše a jasně. Dobré komunikační dovednosti posouvají programátora na vyšší úroveň a zvyšují jeho hodnotu pro týmovou spolupráci.

Pokud nezměníme firmu nebo náš projekt nekrachne, pak nás vlastní kód bude pronásledovat ještě dlouhé roky. Určitě znáte ten pocit, kdy se po delší době vrátíte ke staršímu kódu a nerozumíte mu. Dokonce se k němu někdy nechceme ani znát. To jsem opravdu napsal já? No nic, nezbývá než refaktorovat.

Že se nám podařilo napsat nesrozumitelný kód poznáme podle toho, že jsme nuceni často spouštět debugger a krokovat, abychom pochopili sémantiku kódu.

Rychlost nebo kvalita

Vždy preferujme dobrý návrh a udržovatelnost kódu nad rychlostí jeho vytváření. U dlouhodobých projektů se nám to vrátí mnohonásobně.

Někde na fóru jsem četl myšlenku:

Jednou z nejdůležitějších dovedností programátora je schopnost psát jednoduché kousky kódu správně napoprvé, bez nutnosti používat debugger.

Tato myšlenka nám dává návod, jak být současně rychlí. Naučit se malé elementární programátorské problémy řešit napoprvé správně a kompozicí z nich budovat složitější. Získat jistotu v základech naší práce - v algoritmizaci.

Diagnostika

Dobře zvolená diagnostika aplikace nám může ušetřit časově náročné ladění aplikace skrze debugger. Logování chování aplikace a především podrobný kontext chyby je neocenitelným pomocníkem pro rychlou navigaci k problémovému místu. Nespoléhejme se na důvěryhodnost hlášení od uživatelů, zajistěme si automatizovaně dostatek informací k problémům sami.

Techniky na detekci a předcházení chybám

Debugger je deratizérský nástroj určený pro odchyt otravných, obvykle v pátek odpoledne se objevujících, bugů. Ještě před použitím vlastního ladění nebo ihned poté co jsme chybu přes debugger detekovali, můžeme zkusit chybu izolovat. Na chybový scénář napíšeme jednotkový nebo integrační test. Fixnutí bugu tak odpovídá stavu, kdy nám začne procházet nově napsaný test.

Mnohem levnější, než nahánět bugy nahlášené od testerů a uživatelů, je bugům aktivně předcházet. Výše popsané techniky můžeme doplnit o revize kódu nebo přímo programovat v páru a tím code review dělat v reálném čase. Důležité je samozřejmě používat jednotné kódovací standardy a jmenné konvence, které urychlují orientaci a porozumění kódu všem členům týmu a snižují riziko špatného použití. Využívejme nástroje na statickou analýzu kódu, které umí najít spoustu potenciálně rizikových míst. Neignorujme kompilační warningy. Jsou to tiše tikající časované bomby, které se mohou změnit v nepříjemné chyby. Praktikujme společné vlastnictví kódu, které pomáhá šířit znalosti v týmu a kontinuálně vylepšuje code base. Využívejme průběžnou integraci na buildovacím serveru. Zlepšujme komunikaci na všech úrovních struktury projektového týmu.

Závěrem

Debugger jako nástroj má samozřejmě své opodstatnění. Ve vlastním zájmu bychom se ho měli naučit ovládat efektivně a znát všechny jeho možnosti. Zároveň je však třeba si uvědomit, že jeho časté nadužívání může indikovat zásadnější problémy v našich postupech a dovednostech. Vystupme občas z pracovního stereotypu a přemýšlejme nad tím, jak naši práci zefektivnit tak, abychom debugger - nástroj poslední záchrany - nemuseli používat příliš často.

neděle 9. prosince 2012

1. Vsetínský Code Retreat

... aneb Trávit celou sobotu psaním kódu, který každou hodinu stejně zahodíte? Jste blázni! :)

Podobné reakce manželek, přítelkyň a okolí zaznamenali účastníci 1. Vsetínského Code Retreatu, když se snažili doma vysvětlit proč jedou na celou sobotu někam na Vsetín. Popsat základní koncept celosvětově populární akce Code Retreat není totiž úplně jednoduché. Ani programátorům, natož "nevyvolenému" zbytku populace. Sami účastníci možná také úplně netušili, do čeho se to vlastně pouštějí. Přál bych vám však vidět nadšení, které v průběhu akce narůstalo rychlým tempem. Na konci již nikdo nepochyboval, že investovat celou sobotu do akce tohoto typu, byl výborný nápad.

Vsetínský Code Retreat byl jednou ze stovky akcí, které proběhly během soboty 8.12.2012 po celém světě v rámci Global Day of Code Retreat. K již tradiční pražské akci se letos premiérově přidal právě Vsetín. A jaké to u nás vlastně bylo?

Socializing

Úspěšnost akcí tohoto typu je velmi závislá na přístupu jednotlivých účastníků. Na jejich ochotě experimentovat, uvolnit se, spřátelit se s ostatními a podporovat pozitivní atmosféru. Za proaktivní přístup jsou po právu odměněni novými zážitky, zkušenostmi a změnou paradigmat programátorské profese. Koncept CR je postaven tak, aby maximálně podporoval sociální rozměr akce. Úvodní seznámení, střídání partnerů během párovém programování, oběd a afterparty, přispívají k tomu, že mezi lidmi vznikají trvalejší přátelství. Je to i jeden z důvodů, proč lidé jezdí na své třetí a čtvrté Code Retreaty, proč vstávají ve tři hodiny ráno a jedou přes celou republiku v -10°C.

Na Vsetín přijeli kluci z Brna, Uherského Brodu, Frenštátu a dokonce i jeden Pražák! Viděl bych to jako začátek pěkné tradice, kdy z hlavního města budou jezdit programátoři k nám na vesnici. ;) Pro všechny kódující účastníky to byla premiérová účast na CR. Pro mě zase premiéra v roli facilitátora.

Languages

Akce není omezena na konkrétní programovací jazyk ani platformu. Tato pestrost je dokonce silnou stránkou konceptu CR. Programátoři se díky párování seznámí s jazyky, ke kterým se do té doby báli už jenom přiblížit. Ztratí zbytečné zábrany a předsudky. A naopak získají chuť vyzkoušet nový jazyk a tím si rozšířit znalosti a technologický přehled. Pozorovat kolegu, který hbitě píše kód v "exotickém" jazyce, je velmi inspirující.

Na Vsetíně se kódovalo v jazycích C#, Java, JavaScript, Python, PHP, CoffeeScript, F#. Ohlášený experiment napsat část Game Of Life pomocí uložených databázových procedur MS SQL Serveru se nakonec nekonal. :)

Sessions

Kódovacích bloků je celkem šest (tři dopoledne, tři odpoledne), trvají 45 minut, vždy se začíná od prázdného projektu, řeší se Game of Life a každý blok je specifický výběrem aktivit a rozvíjí jiný druh dovedností. Pro vsetínský CR jsem aktivity namíchal takto:

Session #1

Game of Life Basics
Navigator - Driver

První blok byl určen k seznámení s pravidly Game of Life. Programátoři si zvykali na párové programování, kdy jeden z dvojice psal kód (driver) a druhý spolupracoval na analýze a návrhu řešení a dělal průběžné review (navigator). Bezprostřední reakce při následné krátké retrospektivě byly velmi pozitivní. Partneři vzájemně konfrontovali své styly nahlížení na problém a návrhy řešení. Někteří si poprvé přičichli k neznámému jazyku. Tak jako později pokaždé, na konci bloku se veškerý kód zahodil. Mám však tajné informace, že někteří si kód uložili do archivu, aby se s ním mohli pochlubit doma svým přítelkyním. :)

Session #2

Simple Design
Baby Steps
English

Před druhým blokem byly účastníkům připomenuta 4 pravidla jednoduchého návrhu. Byli také seznámeni s konceptem testy řízeného návrhu, který byl ztěžejní po zbytek dne. Aktivita Baby Steps nutí psát testy a implementaci po nejmenších nutných krůčcích definovaných metodikou TDD.

Programový kód musel být kompletně anglicky, bez českých elementů.

Pro někoho byl požadavek na test-first přístup nový a nezvyklý. Častým problémem, který jsme pak rozebrali v následné retrospektivě, byly názvy testů. Objevovaly se názvy testovacích metod, ze kterých nebyl zřejmý účel testu. TDD metodika chápe psaní testů jako akt návrhu. Je tedy nutné si uvědomit, že dobrým názvem vše začíná. Každý test řeší obecně tři základní věci: 1. operaci, která se testuje, 2. kontext před provedením operace, 3. očekávaný výsledek (testovaný stav po operaci). Tyto informace by měly být zakódovány do dobrého názvu testu. V další části dne se ukázalo, že vymyslet správný název testu je poměrně náročná záležitost.

Session #3

Paper Only (10 min)
No Mouse (No Touchpad)

Programátoři byli přinuceni prvních 10 minut pracovat pouze s papírem. Promýšlení návrhu bez hurá stylu okamžitého kódování, se stalo velmi oblíbeným. Papír byl tak nezbytnou pomůckou po zbytek dne.

Pro někoho se stala extrémně náročnou aktivita No Mouse. Časté sahání na myš je pro programátora kontraproduktivní. Většina IDE má velmi dobrou podporu pro ovládání z klávesnice. Mnoho programátorů však neumí dostatečně efektivně této podpory využívat. Jeden z výrazných přínosů párového programování je právě v tom, že se učíte od drivera jeho efektivní postupy v ovládání z klávesnice. Objevujete nové možnosti a finty, které zařazujete do vašeho profesního portfolia. Na konci bloku jsme diskutovali o výhodách znalosti code snippetů, šablon, klávesových zkratek, různých doplňků do IDE a nástrojů obecně. Naše produktivita roste v závislosti na tom, jak dobře se naučíme ovládat nástroje, které ke své práci používáme.

Session #4

Ping Pong
Mute

Během prvního odpoledního bloku se hrál pingpong s vypnutým zvukem. Jeden z dvojice psal failující test, druhý musel dopsat procházející implementaci. A protože se nesmělo mluvit, jedinou komunikací byly prostředky kódu a především názvy metod, proměnných a pojmenovaných konstant. Programátoři si uvědomili důležitost expresivity kódu. A nakonec jsme se shodli, že tento blok byl jeden z nejzajímavějších v rámci celé akce.

Session #5

Only 4 Lines per Method
No Conditional Statements
No Naked Primitives

Začalo přituhovat a ukázalo se, že tento blok byl hodně náročný. Psát krátké metody není zas takový problém. Je nutné si pouze uvědomit, že krátké bloky kódu jsou mnohem čitelnější a udržovatelnější. S využitím refaktorizačních technik je navíc strukturování kódu efektivní.

Problémem ale bylo omezení na nepoužívání rozhodovacích příkazů. Vynechat switch nás nutí více přemýšlet o polymorfismu. Nepoužívat if je však hardcore technika. V této aktivitě nebyly dvojice příliš úspěšné. Každý však ocenil, že No Ifs vás přinutí se na četnost rozhodovacích bloků v kódu podívat jiným pohledem. Pro zájemce přikládám link na GitHub s řešením GoF v Javě bez ifů.

Nepoužívání holých primitiv (např. int, bool) v rozhraní tříd bylo také inspirativní. Použití výčtového typu namísto boolean hodnot zlepšuje čitelnost kódu. Obecně byla tato aktivita zaměřena na vhodnější používání abstrakcí namísto zveřejňování implementačních detailů.

Session #6

Changing Requirements
Configurable Rules
Cell Age

Poslední blok byl již více odpočinkový. Účastníci se párovali tak, aby si ještě vyzkoušeli neznámé jazyky. Dvojice zkoušely implementaci dalších pravidel. Přibylo pamatování věku živé buňky (počet iterací, které přežila) a vznikaly experimenty jako "superdůchodce" (pokud buňka přežila alespoň tři iterace, byla nezničitelná).

Closing Circle

Závěrečná retrospektiva byla pro mě osobně nejinspirativnější částí celé akce. Každý z účastníků měl za úkol shrnout, co se během akce naučil, co ho překvapilo a co využije ve své praxi. Bylo velmi zajímavé poslouchat, co si kdo z akce odnášel, co jej inspirovalo a kde objevil své slabší stránky. Atmosféra akce a složení lidí (kamarádů) přispělo k tomu, že výpovědi byly velice upřímné a tudíž zajímavé. Bylo více než zřejmé, že se všem akce líbila. Věřím, že se s většinou lidí setkám i příště a že budou myšlenky Code Retreat sami dále propagovat.

Acknowledgement

Rád bych na tomto místě poděkoval těm, kteří mně pomohli s organizací akce:

  • Firmě Magion system, a.s., která akci podpořila finančně.
  • Alešovi Roubíčkovi za nakopnutí k uspořádání Code Retreatu, za pomoc s propagací a za poskytnutí organizačního know-how.
  • Panu Romanu Mlýnkovi z Agentury pro ekonomický rozvoj Vsetínska, o. p. s., díky jehož ochotě a pomoci s přípravou vše proběhlo technicky hladce.
  • Links

    pátek 23. listopadu 2012

    DevFest Story

    V sobotu 10. listopadu 2012 proběhla v Praze zajímavá vývojářská konference DevFest. Asi měsíc před tím mě oslovil Pavel Vybíral z pořádající agentury a nabídl mi možnost na konferenci přednášet. Vystoupit na nějaké menší konferenci mě vždy lákalo. Že to ale bude akce s tak velkou účastí ajťáku mi začalo docházet až poté, co jsem účast přislíbil. ;)

    Ve volbě tématu jsem měl od pořadatelů poměrně volnou ruku. "Vyberte něco z toho, o čem blogujete a twítujete". Na Twitteru se snažím psát vývojářské rady a tipy (jak kdysi řekl v nadsázce Dan Kolman "moudra"), které sbírám během své praxe a při čtení všemožných ajťáckých i neajťáckých materiálů. Blog se mi profiluje od původně čistě kodérských problematik směrem k peopleware a týmové spolupráci. Po 10 letech kódování a postupného objevování praktik dobrého návrhu a psaní čitelného kódu je pro mě zamýšlení se nad lidskými aspekty vývoje software příjemnou změnou.

    S ohledem na vysokou návštěvnost a pozitivní zpětnou vazbu k blogpostu Duševně upřímný programátor, jsem se rozhodl přednášku zaměřit na charakterové vlastnosti, které profilují dobrého vývojáře. Pokusil jsem se také vysvětlit základy v přístupu k naší profesi. Vývojář by si měl uvědomit, že jeho nejdůležitější dovedností je schopnost rozkládat a zjednodušovat řešený problém. Osvojovat si techniky řízení složitosti, které mají úzkou vazbu na techniky pro zajištění kvality. Trénovat dovednosti pro psaní kódu podobně jako trénují sportovci. Být hladový po informacích o technologickém vývoji. Přemýšlet nad efektivností používaných pracovních postupů. A také dbát na svoje zdraví a zajistit si tak dlouhodobou použitelnost. Přednáška tak byla určená pro všechny vývojáře, nezávisle na vývojové platformě.

    K dispozici jsou slajdy přednášky na Slideshare a video na YouTube.

    Upozornění: Přednáška obsahuje sex! Pouze pro vývojáře staří 18 let! :)

    Něco ze zákulisí

    Připravovat se na přednášku v bytě se třemi dětmi je slušný víceboj. Ještě větší adrenalin je pak vlastní vystoupení. Hodně jsem bojoval s nervozitou a asi to je na videu znát. Nějakou dobu mně trvalo, než jsem se uvolnil. Možná si ještě vzpomenete, jak jste se při vašem prvním vystoupení před tolika lidmi cítili vy. ;) Každopádně jsem za tuto zkušenost moc rád.

    Dopředu jsem se těšil, že se osobně setkám s lidmi, které znám zatím pouze z Twitteru. Respektované prezentátory Dana Steigerwalda a Jirku Knesla, "virtuální kamarády" Augiho, Tomáše Pastorka, Honzu Novotného, Ondru Mirtese a další. Ty první jsem nezastihl a ty druhé zase nepoznal podle profilovek. :) Snad někdy příště. Nakonec jsem byl na celé akci jenom pár hodin, protože na mě padla megaúnava z nevyspání a z náročného dopoledního cestování.

    Velký dík patří organizátorům za přípravu atraktivního programu a zvládnutí celé akce!

    čtvrtek 4. října 2012

    Duševně upřímný programátor

    Rád hledám charakteristiky, které popisují dobrého programátora nezávisle na konkrétních technologiích a programovacích jazycích. V knize Code Complete od Steva McConnella jsem narazil na skvělou pasáž, která se věnuje povahovým vlastnostem dobrého vývojáře. Rád bych se zastavil u jedné z nich. U duševní upřímnosti. Musím uznat, že jsem si během své vývojářské praxe prošel většinou nešvarů pramenících z jejího nedostatku. Některé odstraňuji dokonce doteď. :)

    Nebuďte falešný expert

    Pokud máte dostatek duševní upřímnosti, nesnažíte se působit jako expert, pokud jím v dané oblasti nejste. Jedná se o jakousi intelektuální skromnost, díky které se budete lépe rozvíjet. Je vhodnější přiznat, že s danou technologií nemáte dostatek zkušeností, že danou část frameworku neznáte, že si nejste jistí určitou definicí. Pokud přistupujete k problému s vědomím, že umíte spíše méně, je pro vás přirozenější naslouchat ostatním a tím se více učit.

    Zkuste si kvantifikovat při každé otázce, jakou úroveň jistoty v ní máte. Pozor, pokud často dosahujete ve svých očích 100%, zbystřete. Může se jednat o narcismus! :)

    Přiznejte se k chybě

    Duševně upřímný programátor se k chybě přizná rychle a rozhodně. Postaví se k ní chlapsky (programátorky prominou) čelem. Kroutit se a obhajovat chybu je zbabělé. Někdo si dokonce myslí, že když chybu nepřizná, okolí si bude myslet, že není jeho. :) Nefér přístup k řešení chyby může dojít až tak daleko, že dotyčný získá pověst pyšného a přezíravého programátora. A takové pověsti je pak těžké se zbavit.

    Udělat chybu není ostuda. Pokud však není způsobena nedůsledností. Každopádně je nutné se vždy z chyby poučit a přijmout opatření, aby se neopakovala.

    Neignorujte varování

    Oblíbeným sportem je ignorování warningů při sestavování aplikace. Přehlížíme varování, která mohou způsobit v budoucnu velké problémy. Častokrát hledáme přičiny problémů v aplikaci a přehlížíme, že nám překladač mává signalizačními tyčemi přímo před očima. Nedostatek duševní upřímnosti se zde projevuje naší bohorovností v přehlížení varování. "To neděláš dobře s těmi sirkami, Jaromíre!" :)

    Snažte se dobře porozumět svému programu

    "Zkusím si spustit program, abych vůbec pochopil, jak to tam dělám." A metodou pokusů a omylů a s využitím debuggeru zjišťujeme, jak náš vlastní program pracuje. Prostě mu nerozumíme. Přičin může být mnoho - nečitelný kód s vysokým stupněm složitosti, chybějící jednotkové testy s dokumentační funkcí, výpadky paměti, apod.

    Pokud si připustíte, že programu nerozumíte a je potřeba zahájit nápravná opatření, jste na dobré cestě. Pusťte se do vylepšení návrhu, zlepšení čitelnosti, pokrytí testy. Prostě zvyšujte jednotlivá kritéria vnitřní kvality kódu. Jedině s tímto přístupem napíšete příští kód v lepší kvalitě již napoprvé.

    Informujte reálně o aktuálním stavu

    Nestíháte, ale nechcete to přiznat? Říkáte vedoucímu raději to, co by chtěl slyšet, místo objektivní skutečnosti? Pak dostáváte do problémů nejen sebe, ale právě i vedoucího. Jeho zodpovědností je řídit projekt a pokud je informován špatně, dělá špatná rozhodnutí. Pokud byste včas přiznali, že máte problémy, například že vám z objektivních příčin klesá produktivita, dobrý projekťák se vám vždy bude snažit pomoci.

    Většina agilních vývojových metodologií napomáhá tomu, aby se informace o problémech a překážkách v postupu projektu dostaly co nejefektivněji od členů týmu k vedoucímu. Informujte o problémech na denních scrum schůzkách nebo i dříve. Buďte aktivní v řešení vyvstalých problémů. Vaše upřímnost bude oceněna a získáte v očích ostatních větší kredit.

    Dávejte realistické časové odhady a buďte neústupní

    Představte si, že jste požádáni o odhad pracnosti nové funkcionality. Pohovoříte s kolegy, sečtete jednotlivé odhady a dodáte celkové číslo. Vedení se vyleká a přitlačí vás, abyste udělali "lepší" a hlavně nižší odhad. Pokud půjdete přes svoje přesvědčení a magicky snížíte odhad, aniž byste definovali jaké ústupky musíte udělat, je to zle. Lžete opět sami sobě a necháváte se přitlačit do kouta. V případě realizace byste se zřejmě dostali do časového presu, následného stresu a včasné dokončení projektu může být ohroženo.

    Trvat na svém se musí každý vývojář naučit. Málokdo to umí už od začátku. S postupným získáváním praxe se přesnost odhadů zlepšuje. Vysvětlete vedení, že fyzikální zákony (konkrétně časové) ještě měnit nedokážete a případné kompromisy by byly podobně špatné. Pokud je projekt pro vaši firmu zajímavý, můžete dát zákazníkovi samozřejmě nižší cenu, aby do projektu šel. Ale interně si v týmu nic nenalhávejte. Neupřímnost ničí pracovní vztahy.