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.

    pondělí 1. října 2012

    Společné vlastnictví kódu

    ... nejvyšší forma týmové spolupráce

    Franta je na dovolené, proto si musí zákazník počkat tři týdny na opravu komponenty.
    Vím, že je kód této třídy ve špatné kvalitě, ale není to můj problém. Obrať se na autora!
    Už teď se mi při pomyšlení na refaktoring Robertova kódu dělá špatně! Tohle po mně vážně nechtěj!
    Jsem specialista na UI a nebudu zasahovat Martinovi do kódování middleware.
    Ludva se otrávil methylalkoholem a oslepl. Bude trvat týdny, než to někdo převezme.

    Pokud se váš vývojový tým dostává do podobných situací, zřejmě by vám pomohlo praktikování společného vlastnictví kódu (Collective Code Ownership). Jedná se o jednu z technik metodiky extrémního programování (XP). Jednoduše by se dalo CCO definovat takto:

    "Všichni sdílí zodpovědnost za kvalitu kódu. Každý může udělat změnu v jakékoli části kódu. Od všech se očekává, že odstraní problémy, na které v kódu narazí."

    Pojďme se podívat, jakou přidanou hodnotu nám společné vlastnictví přináší.

    Vyšší kvalita kódu

    V socialismu se kolektivní vlastnictví příliš neosvědčilo. Ve výsledku všechno patřilo všem a nikomu a stav věcí podle toho vypadal. Vývojový tým je však specifická struktura, která při správném vedení a správných charakterových vlastnostech jejich členů, dosahuje spoluprácí vyšší výkonnosti. Skupinová zodpovědnost vede k tomu, že vývojáři usilují společně o vysokou kvalitu kódu. Špatný kód napsaný kolegou je i můj špatný kód. Kolega by měl pod závazkem společného kódu cítit větší zodpovědnost a snažit se o potřebnou kvalitu. Já bych naopak měl na nekvalitní kód upozornit a nebo jej přímo zlepšit. Třeba refaktoringem nebo vylepšením návrhu.

    Pokud je váš kód zveřejňován a běžně posuzován jinými lidmi, zvyšuje se vaše motivace ke kvalitnější práci. Profesionální vývoj software je o osvojení správných návyků. Nad návyky nepřemýšlíte, děláte je automaticky. Pokud jste junior vývojář, bude pro vás práce v týmu s CCO obrovskou školou. Na druhou stranu někteří senior vývojáři mohou mít problém s tím, že někdo jiný jim vidí do kódu a navíc si ho dovoluje měnit! Považují svůj kód za natolik intimní záležitost, že si ji brání jako poklad. Někdy je to také z důvodu, že jejich kód je nečitelný, tedy špatný a sami to vědí.

    Poznámka: Mezi atributy externí kvality kódu patří bezchybnost, použitelnost, efektivita, spolehlivost, integrita, přizpůsobivost, přesnost a robustnost. Mezi atributy interní kvality kódu patří udržovatelnost, flexibilita, přenositelnost, znovupoužitelnost, čitelnost, testovatelnost, srozumitelnost.

    Vzájemná zastupitelnost

    Tradičním problémem vývojových týmů je koncentrace znalostí pouze u konkrétních lidí. Autor komponenty je jediný, kdo zná její kód a pro ostatní se jedná o černou skříňku. Někomu pocit nepostradatelnosti může dělat dobře, ale pro flexibilitu vývoje je to špatně. Dovolená, nemoc nebo jiná absence zablokuje práce na komponentě na dlouhou dobu. Úplná ztráta člena týmu pak může způsobit katastrofu.

    Společné vlastnictví kódu tyto problémy řeší poměrně efektivně. Dobrá znalost codebase je dovedností každého člena týmu. Oprava chyby, doplnění funkcionality nebo jiný zásah do kódu někým jiným než autorem? Není problém. Ty máš čas, tak to prosím udělej.

    Co vlastně potřebujeme?

    Společné vlastnictví kódu nelze efektivně aplikovat bez dalších podpůrných technik XP. Jinak se výsledek může významně lišit od našeho očekávání.

    Vývojáři si musejí rozumět. Jejich kód musí být vzájemně snadno pochopitelný. Je nutné zavést jednotný kódovací styl (Coding style). Měly by se ctít zásady čistého kódu (Clean Code) a jednoduchého návrhu (Simple Design). Vysoká čitelnost kódu je zásadní požadavek na práci profesionálního vývojáře. V případě CCO je jeho důležitost ještě umocněna.

    Kvalita existujícího kódu je přírůstkově vylepšována postupným refaktoringem (Refactoring). Refaktoring úzce souvisí s pokrytím kódu pomocí testů. XP aplikuje metodiku testy řízeného vývoje (Test-Driven Development). Bez správného pokrytí kódu jednotkovými testy se nedá CCO použít. Vycházíme-li z definice CCO, kdy každý má právo a povinnost kód vylepšit (refaktorovat) a rozšířit, je regresní funkce jednotkových testů nenahraditelná. Pokud by testy nad kódem nebyly, každý by se bál do stávajícího kódu zasáhnout.

    Další úrovní zajištění je technika postupné integrace (Continuous Integration). Po každém promítnutí změny v kódu do společného prostoru je proveden kontrolní serverový integritní build, jehož součástí by mělo být i spuštění jednotkových testů. V případě zanesení problémů je autor změny ihned vyzván k opravě. Touto technikou je zajištěna integrační validita kódu na týmovém serveru.

    Tým by měl používat verzovací systém (Version Control) pro správu zdrojového kódu s podporou vícenásobného checkoutu. Při CCO dochází častěji k situaci, kdy více uživatelů v jednom období edituje lokálně stejný objekt. Systém by měl mít kvalitní nástroj pro následné slučování změn. Doporučuje se u existujícího kódu dělat úpravy menšího rozsahu a tím pádem častěji vracet změny na server.

    Efektivní podpůrnou technikou je párové programování (Pair Programming). Programování ve dvojicích zlepšuje komunikaci, urychluje šíření znalostí v týmu, díky online revizím návrhu a kódu zvyšuje výslednou kvalitu. Většina kombinací [nováček|pokročilý|expert]{2} je ve výsledku efektivní, kromě nováček + nováček - mentor. Páry by se měly měnit a je nutné vytvořit unifikované programové prostředí u všech párovačů. Není nutno párovat po celou dobu práce.

    Rizika

    Nedostatečná znalost problematiky jednoho z členů týmu může způsobit problematický zásah do existujícího kódu. Jako pojistky máme jednotkové testy, které by zároveň měly dokumentovat návrh příslušné části systému. V případě, že znalosti člena týmu jsou špatné, mohlo by zabrat nasazení párového programování.

    Nikdo se nehlásí k zodpovědnosti za daný kód (No Code Ownership). Takového rizika se mohou obávat především projektoví manažeři. Všem zúčastněným musí být zřejmé, že zodpovědnost za každou část leží na celém týmu. Postoje typu "Já mám svůj kód v pořádku a tento mě nezajímá" je potřeba eliminovat.

    Nedodržení souvisejících agilních technik oslabí výhody CCO a možná jej úplně zabije. Je na zodpovědnosti vedoucího týmu, aby zajistil vytvoření a provoz správně nastaveného agilního prostředí.

    Alternativy

    Pokud se codebase striktně rozdělí podle členů týmu a vzájemně si do kódu nezasahují, mluvíme o silném vlastnictví (Strong Code Ownership). Méně striktní je slabé vlastnictví (Weak Code Ownership). Kód je stále rozdělen podle správců jednotlivých komponent, ale jiný člen týmu může po svolení od správce kód změnit.

    Závěrem

    Pro malé a agilně řízené týmy se jeví CCO jako přirozené řešení požadavků na kvalitu a zastupitelnost. U korporátních neagilně řízených týmů by se na propagátora CCO mohli dívat jako na Marťana, můžete to zkusit. :) Pokud pro vás není agilita sprosté slovo, určitě stojí za to se nad dopady CCO zamyslet.

    Rád bych článek doplnil o nějaké praktické postřehy, ale ve firmě se nám zatím nepodařilo vytvořit dostatečné prostředí pro provozování společného vlastnictví kódu. Výhody jsou zřejmé a rádi bychom stávající slabé vlastnictví přetransformovali na společné. Pokud máte vlastní zkušenost, prosím o připojení komentáře. Děkuji.

    Zdroje

    The Art of Agile Development: Collective Code Ownership - můžete si přečíst odpovědi na otázky, které zřejmě vznese každý, kdo o přechodu na CCO uvažuje.

    pátek 24. srpna 2012

    Jednoho produktivního vývojáře prosím!

    Jak velký je rozdíl mezi slabým, průměrným a vynikajícím vývojářem? Kolik průměrných vývojářů zastoupí jednoho excelentního? O kolik člověkodnů dokončíme projekt rychleji přidáním dalšího vývojáře?

    Odpovědi na tyto otázky samozřejmě nelze exaktně vyčíslit. Někdo by dokonce mohl říci, že v IT se nedá nic pořádně odhadovat a tak se o to ani nebude pokoušet. Můžeme se ale na problém výkonnosti vývojářů podívat přes jejich produktivitu a posoudit efekt jednotlivých manažerských zásahů na rychlost práce vývojového týmu.

    Produktivita vývojáře

    Strohá definice říká, že produktivita vývojáře je (ekonomický) ukazatel mezi výsledkem (softwarový produkt) a časem potřebným k jeho dosažení. Podle této definice bychom se měli snažit produkovat software za co nejkratší dobu. Samozřejmě s dodržením akceptačních kritérií na funkční a nefunkční požadavky. Měli bychom také zajistit dostatečnou vniřní kvalitu systému, která nám u dlouhodobých projektů zjednoduší jejich údržbu a následný rozvoj.

    Výslednou produktivitu vývojáře ovlivňuje velké množství faktorů. Patří mezi ně odborné znalosti, zkušenosti z jiných projektů, dovednosti v používání nástrojů, intuice v rozhodování, schopnost správného výběru z mnoha alternativ, soft skills, pracovní prostředí, vhodné nástroje a mnoho dalších.

    Opravdu kvalitní vývojáři jsou mnohem produktivnější než ti průměrní

    Někteří zkušení projektoví manažeři tvrdí, že vynikající vývojář je až o řády produktivnější než průměrný vývojář. Vzhledem k tomu, že vývoj software je vysoce komplexní záležitost, dá se tomuto tvrzení věřit. Co se naprogramuje dnes, stane se základem pro zítra. Pokud tedy pokládá základy určité části systému méně disponovaný vývojář, může být jeho práce nedostatečně kvalitní a ve výsledku neproduktivní. Stavět na takto chatrných základech je pak pro ostatní velice neefektivní. Situace si někdy vynutí velký zásah nebo dokonce kompletní předělání, samozřejmě s výrazným navýšením pracnosti.

    Vývoj software prochází několika fázemi (specifikace požadavků, analýza, návrh, implementace, testování, nasazení do provozu, údržba). Chyby a nerespektování požadavků v jednotlivých fázích mohou mít velké časové a ekonomické dopady. Výborný vývojář používá efektivně postupy a nástroje, které chyby eliminují. Tím tráví méně času řešením následných defektů zanesených do systému v předchozích fázích.

    Přidám lidi, zrychlím projekt

    Tento mýtus IT managmentu je dost rozšířený. Pokud zapojíte další skladníky do nakládky kamionu, jistě se celá akce urychlí (pokud se nepoperou o ještěrku :)). Ale vývoj software není pásová výroba. Tam takové pravidlo neplatí.

    Přidáním vývojáře dojde z krátkodobého hlediska spíše ke zpomalení týmu. Stávající členové totiž musí věnovat určitý čas na zaškolení nováčků a jejich uvedení do problematiky. Pokud navíc přidáte slabého vývojáře, jeho nekvalitní a pomalá práce může snížit efektivitu ostatních. S navýšením počtu členů týmu také roste zátěž manažera v koordinací lidí. Množství komunikačních kanálů roste exponenciálně podle počtu lidí. Podle vzorce n(n-1)/2 určíme, že např. pro tým 12 lidí, bude muset manažer udržovat 66 komunikačních vztahů.

    Někdy je vhodnější slabého člena z týmu odebrat než se snažit přidat dalšího průměrného vývojáře. Výborným vývojářům se uvolní ruce od zátěže s neproduktivním vývojářem a sami pak odvádějí lepší práci. V tomto případě tedy platí, že méně je více.

    Jak tedy urychlit vývoj?

    • Určitě se soustřeďte na personální kvalitu Vašeho týmu. Věnujte více peněz na výběr excelentních členů.
    • Investujte do školení a dalších forem zvyšování produktivity.
    • Nespoléhejte jenom na průměrné vývojáře. Nemůžete na nich stavět projekt, který má být úspěšný. V IT neplatí, že průměrný tým odvede ve výsledku průměrnou práci. Výsledek může být mnohem problémovější.
    • Poskytněte vývojářům kvalitní nástroje, které zefektivní jejich práci.
    • Nezmatkujte a neurychlujte krátkodobě vývoj přidáváním dalších vývojářů. Hledejte důvody, proč je projekt v prodlení a odstraňujte překážky.
    • Zbavte se slabých vývojářů a nebudete je muset hlídat.

    Zdroje

    K napsání příspěvku mě inspirovala úvaha Neala Forda Developer Productivity Mean vs. Median.

    pondělí 30. července 2012

    Tell, Don't Ask

    ... aneb snižujte závislosti mezi třídami

    Jedna z možných definic návrhového principu Tell, Don't Ask (TDA) zní takto:

    "Každé rozhodování zcela závislé na vnitřním stavu objektu by mělo být prováděno uvnitř tohoto objektu."

    Princip hovoří o tom, že bychom měli navrhovat třídy tak, aby se volající strana nemusela dotazovat na záležitosti týkající se vnitřního stavu volané třídy.

    Ukázka porušení TDA

    Mějme zjednodušený autobusový rezervační systém:

    class Bus
    {
        private int numberOfSeats;
        private IList<Passenger> passengers = new List<Passenger>();

        public Bus(int numberOfSeats)
        {
            this.numberOfSeats = numberOfSeats;
        }

        public bool HasFreeSeat
        {
            get
            {
                return numberOfSeats > passengers.Count;
            }
        }

        public void AddPassenger(Passenger passenger)
        {
            passengers.Add(passenger);
        }
    }

    class BusReservation
    {
        public void AddPassengerToBus(Bus bus, Passenger passenger)
        {
            if (bus.HasFreeSeat)
            {
                bus.AddPassenger(passenger);
            }
        }
    }

    Proč je uvedené řešení problematické:

    • Základním principem OOP je zapouzdřenost interních dat objektu a jeho chování. Třída Bus však zbytečně zveřejňuje informaci o volných sedadlech a nutí volající stranu, aby s touto informací pracovala a zohledňovala ji před voláním metody AddPassenger.
    • Třída BusReservation je závislá na třídě Bus na dvou místech. Dotazováním na vlastnost HasFreeSeat a voláním metody AddPassenger. Každá nadbytečná závislost mezi třídami zvyšuje komplexitu návrhu a zhoršuje vlastnosti systému.
    • Třída Bus nutí volající stranu, aby měla znalost o tom, že před zavoláním AddPassenger si musí nejprve sama ověřit splnění kontraktů přidání cestujícího. S tím souvisí i závislost na správném pořadí volání. Samostatné volání HasFreeSeat nedává smysl.
    • Co když se v budoucnu změní podmínky, za kterých je možné přidat cestujícího? Nyní je přidání závislé pouze na volném sedadle, ale nově může přibýt podmínka typu "je autobus pojízdný". Pak bude nutné doplnit test na vlastnost IsMobile na všechna místa volání AddPassenger.
    • Každá nadbytečná závislost zvyšuje komplexitu jednotkových testů. Pokud chceme testovat třídu BusReservation v izolaci, musíme mockovat třídu Bus (nebo lépe rozhraní). V našem problematickém případě musíte přidat chování mocku pro vlastnost HasFreeSeats a metodu AddPassenger.

    Vhodnější řešení

    Odstraníme závislost volající třídy na dotazování se na volné sedadlo. Veškeré testy na proveditelnost akce přidání cestujícího jsou zapouzdřeny uvnitř metody AddPassenger. Pokud některá z podmínek není splněna, je vrácena výjimka, kterou zpracuje volající strana. Volající straně se situace zjednoduší.

    class Bus
    {
        private int numberOfSeats;
        private IList<Passenger> passengers = new List<Passenger>();

        public Bus(int numberOfSeats)
        {
            this.numberOfSeats = numberOfSeats;
        }

        private bool HasFreeSeat
        {
            get
            {
                return numberOfSeats > passengers.Count;
            }
        }

        public void AddPassenger(Passenger passenger)
        {
            bool isFull = !HasFreeSeat;

            if (isFull)
            {
                throw new Exception("Bus is full.");
            }

            passengers.Add(passenger);
        }
    }

    class BusReservation
    {
        public void AddPassengerToBus(Bus bus, Passenger passenger)
        {
            bus.AddPassenger(passenger);
        }
    }

    Vezměte si na pomoc Adapter

    Pokud využíváte rozhraní, které nemůžete měnit (komponenta třetí strany) a které porušuje TDA, můžete si pomoci návrhovým vzorem Adapter (Wrapper). Např. v jazyce C# je za příkazem foreach schován adaptér, který zjednodušuje práci se vším, co zveřejňuje metodu IEnumerator GetEnumerator(). Z IEnumerator pak postupně volá metodu bool MoveNext() a dotazuje se na vlastnost object Current { get; }. Více na stackoverflow.com.

    Závěrem

    Tak jako většina principů a doporučení objektového návrhu, tak i TDA není možné bez rozmyslu aplikovat dogmaticky ve všech situacích. Záleží na zodpovědnosti navrhované třídy, zda-li poskytuje příkazy (commands) k vykonání nějaké akce nebo dotazy (queries) vracející vnitřní stavy objektu. V případě příkazů byste však měli o dodržování principu TDA usilovat.

    pondělí 9. července 2012

    Peníze až na čtvrtém místě

    Richard Florida ve své knize The Rise of the Creative Class zveřejnil zajímavé výsledky výzkumu o motivování lidí. Více jak 20 000 pracovníků z IT mělo z celkem 38 různých faktorů vybrat ty, které je nejvíce ovlivňují a motivují v jejich práci. Top 10 vypadá takto:

    1. Náročnost úkolů a zodpovědnost
    2. Flexibilita
    3. Stabilní pracovní prostředí
    4. Peníze
    5. Profesní rozvoj
    6. Uznání kolegů
    7. Motivující spolupracovníci a nadřízení
    8. Vzušující náplň práce
    9. Firemní kultura
    10. Umístění a komunita

    Pokud na výsledky pohlížíte z perspektivy zaměstnance, snáze pochopíte, v jakém prostředí může vyniknout Váš kreativní potenciál. Máte-li na výběr, hledejte firmu, která nabízí zajištění co nejvíce motivátorů ze seznamu. Pokud ve Vaší stávající firmě není splněna většina věcí ze začátku seznamu, měli byste se vážně zamyslet, zda-li v takové firmě chcete nadále ztrácet svůj čas.

    Průzkum by měl být přínosný také pro zaměstnavatele a vedoucí týmů. Pokud chtějí z lidí dostat maximum a zajistit jejich spokojený pracovní život, měli by realizovat opatření, která napomáhají motivovat. Nerespektování těchto faktů obvykle zabíjí inovaci, zvyšuje fluktaci lidí a v konečném důsledku snižuje úspěšnost firmy.

    Florida nám předkládá potvrzení faktu, že peníze nejsou dostatečným dlouhodobým motivátorem u kreativních lidí. V určité fázi pracovního vývoje totiž můžete zjistit, že přestože vyděláváte slušný balík, nejste spokojeni. Dostali jste se zřejmě na úroveň, kdy základní potřeby včetně finančních jsou uspokojeny, ale potřebujete navíc uspokojit Vaše seberealizační potřeby nejvyšší úrovně (viz. 4. a 5. patro Maslowovy pyramidy potřeb).

    Pokud Vás zajímá problematika podpory kreativity v současné éře inovativní ekonomiky, můžete si přečíst knížku Nepostradatelní od Jan Melvil publishing. Seth Godin na mně působil zpočátku trochu jako otravný provokatér, ale s postupem času jsem na jeho hru přistoupil a začalo se mi to líbit. Doporučuji.

    sobota 19. května 2012

    Produktivní rychlokodér

    ... aneb ovládněte základy Vašeho řemesla

    Je součástí Vaší profese vytváření programového kódu? Píšete kód produktivním způsobem? Znáte a používáte nástroje, které Vám pomáhají produktivitu zvyšovat? Saháte často při psaní kódu na myš?

    Stává se téměř denně, že objevím nějakou novou fintu, kterou se snažím využít pro zlepšení své produktivity. Může se jednat o novou klávesovou zkratku, nový nástroj, novou techniku, zrychlení často se opakujícího postupu, apod. Pokud chceme svoji práci dělat co nejlépe, je potřeba systematicky pracovat na zvyšování naší kodérské produktivity.

    Tento příspěvek se týká aspektů rychlosti vytváření programového kódu. Rád bych shrnul elementární dovednosti, které jsou nutným základem pro práci kodéra. Příklady v textu se týkají platformy Visual Studia, kterou používám. Předpokládám však, že pro jiná IDE existují ekvivalentní nástroje.

    Hbité kodérovy prsty

    Kolika prsty píšete a jak rychle? Díváte se při psaní na klávesnici? Děláte často chyby a musíte se při psaní vracet o odmazávat?

    Někdo nepovažuje rychlost psaní u kodéra za příliš důležitou. Sami však tušíte, že je rozdíl mezi datlováním dvěma prsty a symfonií všech deseti. Rychlost se uvádí v úhozech (keystrokes) za minutu nebo v počtu napsaných slov za minutu (WPM). Změřte si svou rychlost např. na http://10fastfingers.com. Průměr je mezi 50 a 70 wpm. Pokud se dostanete nad 100 wpm, patříte mezi 20% nejrychlejších psavců. Raději nebudu uvádět kolik jsem naměřil sobě. :)

    A jak tuto dovednost zlepšovat? Zkuste se naučit hmatovou metodu, která využívá všech deseti prstů. Pořiďte si ergonomickou klávesnici, která Vám bude vyhovovat.

    Můžete si také přečíst, co si o dovednostech pro psaní textu myslí respektovaný Jeff Atwood v příspěvku We Are Typists First, Programmers Second.

    Učte se klávesové zkratky a nesahejte na myš

    Důležitost konkrétní klávesové zkratky pochopíte v momentě, kdy se ji naučíte. Od tohoto okamžiku se bez ní neobejdete. Zkratka většinou supluje akci, kterou můžete udělat myší nebo posloupností více klávesových akcí. Obě metody jsou obvykle pomalejší než zkratka (od toho je to zkratka :). Základní sadu klávesových zkratek má vaše IDE, další dodají dodatečná rozšíření. Pro Visual Studio platí, že základ je sice ok, ale teprve s rozšířením typu CodeRush nebo ReSharper povýšíte z akumulační vrtačky na pořádnou příklepovku! Investice do kvalitních rozšíření se určitě vyplatí.

    Doporučuji vytisknout cheat sheety s přehledem klávesových zkratek Vašeho IDE a rozšíření. Zdroje pro Visual Studio (Microsoft, DoFactory), CodeRush a ReSharper. Postup učení pak může být takový, že si nejprve přečtete referenční přehled zkratek, abyste dostali do podvědomí, co všechno se dá "zkracovat". Pak se snažíte před každou požadovanou akcí vzpomenout si na příslušnou zkratku. Několikrát požádáte papír o nápovědu a podle konkurenceschopnosti vaší střednědobé paměti si zkratku zapamatujete. Zkratek bývá velké množství a jsou strukturovány do menších oblastí. Zřejmě i zde platí Paretovo pravidlo, že 20% zkratek budete využívat v 80% případů. Naučte se tedy alespoň těch 20%.

    Automatické doplňování a kontextový našeptávač

    Ve VS je k dispozici nástroj IntelliSense. Podle aktuálního kontextu, části zadaného jména a s využitím reflexe, Vám například nabídne rychlé vložení příslušného jména identifikátoru. Předpokládám, že není nikdo, kdo by nabízenou pomoc od IntelliSense odmítal. Ne každý však umí IntelliSense vyvolat explicitně (Ctrl + J), zobrazit si informace o metodě a jejích parametrech (Ctrl + Shift + Spacebar), apod.

    Vkládání bloků kódu

    Psaní kódu není psaní beletrie, ale má charakter kompozice jednoduchých opakujících se bloků kódu do složitějších celků. Nabízí se tedy s těmito bloky pracovat efektivněji. Ve většině IDE je k dispozici podpora code snippetů. Jedná se o předpřipravené kusy kódu s možností definice parametrických částí. Vložení těchto kusů kódu provedete zadáním zkratky snippetu a odesláním řídícího znaku (ve VS tabulátoru). Napište např. foreach a stiskněte tabulátor. Editor v IDE Vám doplní celý blok příkazu foreach s možností změnit názvy parametrizovatelných částí.

    V základu vašeho IDE je k dispozici množina předdefinovaných snippetů. Zajímavé jsou však i snippety, které si vytvoříte sami. Pokud používáte nějakou typickou sekvenci nebo blok kódu, určitě si pro něj vytvořte snippet. VS nemá ideální podporu pro vytváření vlastních snippetů a proto musíte vzít zavděk některými externími editory. Např. Snippy nebo Snippet Editor. Doporučuji vytvořit snippety pro Váš projekt a spravovat je centrálně v repository. Budou je mít k dispozici všichni členové týmu.

    Rozšíření CodeRush nabízí aparát šablon. V daném kontextu je k dispozici zkratka, která odpovídá klíčovému slovu, názvu datového typu nebo nějaké složitější sekvenci. Stačí pak zadat např. t a po stisku mezerníku bude doplněno true. Šablony jsou inteligentní a jajich použití je variabilní a uživatelsky rozšiřitelné.

    Dogenerování chybějícího kódu

    Poměrně často používám klávesovou zkratku Ctrl + ., která podle aktuálního kontextu doplňuje chybějící kód. Umí doplnit using pro relativně odkazovanou třídu, vygenerovat pole nebo vlastnost třídy, vytvořit kostru neexistující metody (při použití metody shora-dolů), provést implementaci rozhraní, apod. Bez této funkce (klávesové zkratky) bych se už neobešel.

    Vylepšování kódu pomocí refaktorizace

    Znalost refaktorizačních technik by měla být v repertoáru každého kodéra. Mezi základní techniky patří přejmenování, vyčlenění kódu do samostatné metody, práce s argumenty metody, apod. Další typy refaktorizací mohou přidat rozšíření. Refaktorizaci použijete v situaci, kdy chcete stávající kód vylepšit (zlepšit čitelnost a udržovatelnost). Pěkné příklady jsou například na sourcemaking.com.

    Generování kódu

    Ke generování větších a složitějších bloků kódu můžete využít podporu T4 šablony. Generovat se dá z logických DSL modelů, z databázových dotazů a dalších kolekcí. Jedná se o efektivní a dobře použitelný nástroj. Můžete mrknout na ukázku.

    Navigace v kódu

    Umět se rychle dostat na určité místo kódu je neméně důležité jako umět kód vytvářet. Čím je projekt rozsáhlejší, tím jsou nároky na navigaci v kódu vyšší. Pokud však ovládáte klávesové zkratky pro přechod k deklaraci, na předchozí místo v kódu, do konkrétní třídy, apod. nebude pro Vás tato činnost problém. Některé techniky, jako například Test Driven Development, vyžadují cyklické provádění stejné posloupnosti akcí. V těchto případech mohou být rozdíly v produktivitě markantní.

    Důležitá je i navigace mezi částmi IDE. Např. přechod do okna s chybami kompilace, do okna s testy, do Solution Exploreru, apod. Na většinu akcí by opět měly být k dispozici klávesové zkratky. Jen se je naučit.

    Jak se dále zlepšovat?

    • Vyzkoušejte párové programování a pečlivě sledujte Vašeho spolukodéra. Snažte se pochytit jeho dobré návyky.
    • Sledujte blogy, které píší o používání Vašich nástrojů a zvyšování produktivity.
    • Pokud máte problém, snažte se jej vyřešit automatizací i za cenu (přiměřeně) vyšších startovních nákladů na naučení.
    • Účastněte se programátorských cvičení typu CodeRetreat.
    • Trénujte. ;)

    čtvrtek 5. dubna 2012

    Programová chyba jako test charakteru

    Někdy je zajímavé sledovat, jak programátoři reagují na nahlášení chyby, za kterou jsou zodpovědní. Málo co odhalí lidský charakter tak, jako chování v relativně krizové situaci. Pokusil jsem se s mírnou nadsázkou popsat typologií programátorů právě podle jejich reakcí na chybu. Možná se poznáte nebo třeba někoho z vašich kolegů. :)

    Já přeci chyby nedělám

    Zastánce této techniky, pan Božský, se snaží za každou cenu zbavit zodpovědnosti za chybu. Případné přiznání chyby by mu narušilo vlastní pocit idealismu, který chová vůči své osobě.

    "Chyba sice nastala v mojí třídě, ale vůbec jsem netušil, že ji budeš používat takto!
    To je cílené chování aplikace dle specifikace."

    Přestože se aplikace chová objektivně špatně a specifikace vůbec neexistuje. Dost času ztrácíte tím, že musíte dotyčného přesvědčit o jeho zodpovědnosti za chybu.

    Hulk

    Nahlásit chybu takovému programátorovi se obvykle trochu bojíte. Víte, že jeho počáteční reakce je dost agresivní. Zbledne, pak zezelená, natlakuje se, začne prskat a hledat nějaký cíl, na který by se mohla svalit část viny za vznik chyby.

    "Sakra, zase to někdo pořádně neotestoval!
    Přeci jsem upozorňoval, že úprava může způsobit problémy!
    No a co, že jsem to dal k otestování těsně před uzavřením iterace!"

    Na hrubý pytel, hrubá záplata :)

    Hlavně nenápadně a zatloukat

    Programátor se doslechne o chybě, rychle ji opraví a tváří se jako by o žádné chybě ani nevěděl.

    "Mně se chybu nedaří navodit. Prosím prověř (testere) chování v aktuální verzi.
    Vidíš, že se to chová správně!"

    Přiznání, že tam chyba opravdu byla, se od něho dobrovolně nedočkáte. Po urgencích se možná přizná, ale pachuť neupřímnosti zůstává.

    Sebemrskačství

    "Hrozně mě ta chyba mrzí! To snad není možné! Jak se to mohlo stát?! Takový jsem si dával pozor!"

    Každá chyba je pro něho stresovou záležitostí. Každé šlápnutí vedle ještě více sráží jeho již tak nízké sebevědomí. Pošlete jej na kurs asertivního chování!

    Alibismus ukrytý v pseudosložitosti

    Zaplavit kolegy hromadou nadbytečných informací, které navodí dojem toho, že prostě chyba v tak komplikované situaci musela zákonitě vzniknout.

    "Databáze je taková a maková, nastavení bylo netypické, plán optimalizace nepředpokládatelný. S tím jsem sice mohl počítat, ale těch možných stavů je tolik, bla bla bla ..."

    Prostě to oprav a neztrácej svůj ani můj čas zbytečným vysvětlováním!

    Jsem z planety pokročilých uživatelů

    "Proč se tohle UI uživatelům nelíbí, vždyť je tam tolik funkcí a všechny jsou pěkně vidět naráz?!
    Spousta informací pěkně rozmístěná po velkém formuláři.
    Barvy jsou dostatečně výrazné, aby upozornily na důležité části UI.
    Proč by to nemohlo zobrazit vždy dialogovou zprávu o úspěšném ukončení zpracování."

    Takový člověk podle sebe a svých subjektivních vjemů chybně předpokládá chování ostatních uživatelů. Pokud nezná nebo nechápe základní pravidla uživatelské použitelnosti (UX), zkuste mu je vysvětlit. Ale ať už nediskutuje a upraví to!

    A jaká by měla být správná reakce?

    Jedná se o velmi zjednodušený postup, ale můžete zkusit třeba:

    1. Zajistěte si kompletní informace o chybě. Potřebujete znát kontext spuštěné aplikace (zákazník, operační systém, typ prohlížeče, apod.), postup navození chyby, popis co je vlastně chybou a jak by se měla aplikace správně chovat. Vše by mělo být součástí hlášení o chybě ve vašem systému na sledování chyb.
    2. Někdo by měl chybu klasifikovat. Určit její závažnost a přiřadit jí prioritu, která ovlivní rychlost její opravy. Měl by také domyslet nápravná opatření, např. opravu dat v databázi, apod.
    3. Chyba je směrovaná na vás. Objektivně rozhodněte, zda-li je problém opravdu na vaší straně nebo ji směrujte na příslušného správce části aplikace, se kterou chyba souvisí. Zkuste omezit počet přehazování chyby mezi řešiteli. Ztrácíte čas váš i ostatních.
    4. V rámci řešení můžete získat další informace o důsledcích chyby (výši škody). Zveřejněte tyto informace pro ostatní zainteresované kolegy. Buďte transaparentní, upřímní a nic nezatloukejte. Zvýšíte tím efektivitu řešení problému.
    5. Odstraňte systémově příčiny problému tak, aby se chyba neopakovala. Přijměte nápravná opatření na související chyby. Napište programový test, který se bude provádět automaticky a upozorní na případné vrácení podobné chyby.
    6. Informujte o vyřešení chyby. Sdělte právě tolik informací, kolik postižená strana potřebuje vědět.

    středa 21. března 2012

    Automatické testování proti databázi

    Proti databázi budete zřejmě spouštět testy pokrývající datovou vrstvu. U vyšších vrstev aplikace, použijete testovací databázi v situacích, kdy není vhodné datovou vrstvu mockovat. Testovací databáze se bude hodit v případě zátěžových a výkonnostních testů.

    Dostupnost testovací databáze

    Testy potřebujete spouštět na pracovních stanicích vývojářů, na buildovacím serveru nebo na jiném počítači, který nemusí být nutně připojen k počítačové síti. Je obvyklé, že databáze se zpřístupní v okamžiku spouštění testů a po jejich provedení se zahodí.

    Není také vhodné, aby více běhových testovacích prostředí přistupovalo na stejnou instanci databáze. Mohly by se vzájemně ovlivňovat v operacích, které nejdou schovat do transakce (např. DDL příkazy).

    Z uvedených důvodů se používají lokální databáze. V odůvodněných případech můžete použít i serverovou instanci databáze, ale toto řešení přináší jistá omezení plynoucí ze společného přístupu více testovacích klientů.

    Rychlost vytvoření lokální databáze

    Jeden z důležitých požadavků kladených na testy je jejich rychlost provádění. A databázové testy patří mezi ty nejpomalejší. Pokud používáte lokální databázi, musíte počítat s časovými režijemi na vytvoření instance databáze.

    Nejrychleji startují paměťové (in-memory) databáze (např. SQLite) a databáze pracující nad datovými soubory. Pokud je vaše datová vrstva nezávislá na konkrétním typu databáze, můžete pro účely testů použít některou z rychlých variant, která neodpovídá produkční databázi. Např. u zákazníků běží vaše aplikace na MS SQL Serveru a na Oracle, ale testujete proti SQLite.

    Jak to funguje u nás

    V naší firmě jsme zvolili testovací databázi stejnou jako produkční a to MS SQL Server. Každý počítač, na kterém chceme spouštět testy, má instalován plnotučný MS SQL Server nebo alespoň MS SQL Server Express (na vývojářských stanicích). Při této variantě je nutné databázi obnovit (příkaz restore) z lokálního .bak souboru. Naše databáze má více jak 1000 tabulek a její obnovení trvá do 10 sekund. Optimalizací je to, že databázi obnovujeme pouze jednou, na začátku spouštění sady testů.

    Soubor s databází je vytvářen ze serverové databázové instance, ke které je omezený přístup. Jsou na ní spouštěny pouze schválené změnové skripty a přímo na ní se netestuje. Soubor je uložen v systému pro správu zdrojových kódů a je synchronizován spolu se zdrojovými produkčními kódy a testy na počítač, kde se testy spouští.

    Vývoj a spouštění testů probíhá nad více vývojovými větvemi. Pro každou větev je k dispozici kompatibilní databázový soubor s příslušnou strukturou.

    Testovací data

    Aby bylo možné validovat výsledek spuštění každého testu, musí být splněny vstupní podmínky. V případě testů proti databázi musí být k dispozici taková testovací data, která předpokládá test. Ideální situací je prázdná databáze před testem. Všechna data jsou pak v inicializaci testu do databáze vložena skriptem. Složitost databázových skriptů se liší podle testovaného problému a složitosti vazeb do podřízených tabulek.

    Vyhněte se přípravě testovacích dat pomocí programových tříd. Může se stát, že test selže ve fázi právě této přípravy testovacích dat. Tím se celý test znehodnotí a chybně indikuje problém, který je zřejmě jinde než v testované části kódu. Navíc zbytečně zvyšujete složitost kódu testů.

    Někdy může být výhodné mít v databázi část dat předvyplněných. Jedná se o data, která mají referenční charakter (jsou stejná na všech instalacích) nebo o data, která využívá většina testů - testovací aplikační uživatelé, testovací osoby, apod. Taková data musí být neměnná a testy s nimi musí počítat.

    SQL skripty generující testovací data ukládejte do repository. Jeden skript může být použit pro celou sadu testů. Dokonce si dovedu představit, že skript, který generuje např. testovací objednávky, bude použit v testech datové vrstvy objednávek i funkcionality WCF služby pro práci s objednávkami.

    Užitečné tipy

    Uzavřete provádění celého testu do transakce, která vždy skončí příkazem rollback. Pro promítnutí změn do databáze použijte příslušnou funkci vašeho perzistentního frameworku. Např. pro (N)Hibernate je to funkce Flush() databázové relace.

    Databázový uživatel, pod kterým spouštíte testy, by měl mít stejná oprávnění jako v produkčním prostředí. Vyhněte se uživatelům s DBA právy a uživateli, který je vlastníkem databázových struktur. Pod takovými uživateli může test projít, ale v produkci dojde k chybě.

    Pokud se chcete vyhnout časově náročné obnově databáze před každým testem, můžete si pomoci "úklidem" databáze. Před nebo po každém testu spustíte skript, který smaže všechna data. V případě, že se vám daří provádět testy v transakci s rollbackem, nebude zřejmě úklid nutný.

    Závěrem

    Vyberte si vhodnou strategii, která bude vyhovovat vašim potřebám. Efektivní vytváření a spouštění testů zvýší vaši produktivitu práce a vnese potřebnou jistotu do udržovatelnosti aplikace.

    neděle 26. února 2012

    Techniky pro prevenci softwarových chyb

    ... aneb chyby se začnou bát vás!

    Chyba, defekt, štěnice, brouk, bug, fail, fault, mistake. Tato slova nám nezní moc libozvučně. Ve své práci vynakládáme nemalé úsilí na jejich deratizaci. V tomto průřezovém článku jsem se zaměřil na několik preventivních technik. Zdravotní pojišťovny ví, že prevence je levnější než léčba. Stejně tak si i zkušení vývojáři uvědomují, že čím dříve se chybu podaří diagnostikovat, tím bude její odstranění levnější. Legrace končí, pokud se chyba dostane až do provozního prostředí.

    Chyby na sebe berou mnoho podob. Může se jednat o pád aplikace na neošetřenou chybu některé z komponent, sémantickou nefunkčnost aplikace (chybný výpočet, nesprávná data) nebo nesplnění nefunkčního požadavku na systém - pomalost, porušení zabezpečení, neškálovatelnost, apod. Chyby mají různou závažnost a některé dokáží způsobit hodně velkou škodu. Na míře chybovosti je závislé vnímání vaší aplikace uživateli. Je to výrazný faktor úspěšnosti celého vašeho snažení.

    Pište čistý kód

    Krysy žijí v kanálech a švábi v místech, kde je nepořádek a neuklízí se. Softwarové chyby to mají podobně. Více se objevují v kódu, který nedodržuje metodiku "čistého kódu". Jaký kód je čistý? Kód, který je čitelný, přehledný, dodržuje kódovací standardy, je správně strukturovaný, používají se v něm vhodné názvy, má správné úrovně abstrakcí v metodách, apod. K technikám čistého kódu se možná dopracujete praxí nebo rychlejším způsobem, přečtením výborné knihy Čistý kód od Roberta C. Martina.

    Čistý kód podporuje efektivnější ladění. Pokud např. dodržujete pravidlo, že každá metoda má právě jeden výstupní bod (příkaz return), je snadnější rozmístit ladící body. Pokud správně strukturujete kód třídy na menší metody a nemícháte více úrovní abstrakce do jedné metody, navigace je rychlejší a případné problémové místo najdete snáze.

    Důsledkem aplikace pravidel čistého kódu je především dobrá čitelnost kódu, která snižuje riziko "ukrytí" zákeřných programových chyb už v prvotní fázi psaní kódu.

    Dobrý objektový návrh

    Chybný objektový návrh dokáže hodně zavařit a čím později si chyby uvědomíte, tím více práce si přiděláte. Dobře navržený systém respektuje pravidla návrhové metodologie SOLID a dalších dobrých návrhových praktik. Rozsáhlejší systémy, které nerespektují dobrý návrh jsou problematicky udržovatelné a vysoce rizikové při jakémkoliv pozdějším zásahu do kódu. Říkáme, že jsou křehké. Zanesení chyby je vysoce pravděpodobné.

    Neobjevujte kolo a naučte se využívat návrhové vzory. Buďte si jistí, že problém, který řešíte, už měly zřejmě stovky vývojářů před vámi. A návrhový vzor je efektivním řešením tohoto typu problému. Jsou popsány desítky vzorů pro vznik objektů, pro zachycení struktury mezi objekty, pro řízení chování, pro implementaci jednotlivých vrstev aplikací (datová, obchodní logika, prezentační, ...) a další.

    Díky dobrému návrhu zoptimalizujete i další preventivní techniky popsané v tomto článku. Například bez Inversion of Control a programování proti rozhraní (ISP) byste psali problematicky jednotkové a integrační testy.

    Naučte se i antivzory (antipatterns), špatné techniky návrhu. Jejich znalost vás již dopředu bude varovat před chybnými kroky, které by vás jinak stály vyšší chybovost, čas a prostředky.

    Refaktorizace kódu

    Rekaftorizace kódu je změna struktury kódu, která nemá vliv na jeho celkovou funkčnost. Znalost refaktorizačních technik patří mezi základní dovednosti vývojáře. Příkladem refaktorizačních technik je přejmenování (proměnné, metody, třídy), vyjmutí části kódu do samostatné metody nebo třídy, změna pořadí argumentů metody, apod. Nezbytností je, aby vaše IDE podporovalo refaktorizační techniky. Nebojte se refaktorovat vždy, když budete mít pocit, že se kód zlepší.

    S využitím refaktorizace dosáhnete čistého kódu a dobrého návrhu. Snížíte složitost částí kódu. Platí pravidlo, že co je složité, je náchylné k vyšší chybovosti. Dobrý vývojář dokáže i složitý problém implementovat přehledně a "jednoduše".

    Hezký popis refaktorizačních technik je k dispozici na serveru SourceMaking.

    Revize kódu (Code Review)

    Promluvili jste si někdy o svém kódu s kolegou? Bavili jste se, proč jste použili zrovna takovou implementaci? Uvědomili jste si při tom, že by problém šlo vyřešit lépe nebo jste dokonce objevili chybu? Výborně! Pak jste použili techniku revize kódu. Když se na váš kód podívá někdo jiný, je to téměř vždy ke prospěchu věci.

    Kdy provádět revizi kódu? Ideální by bylo během nebo těsně po vlastní implementaci. Revize kódu je jedním ze základních aspektů párového programování (Pair Programming). Dvojice společně vyvíjí kód a revize probíhá neustále. Pokud neaplikujete párového programování, můžete nastavit povinnou revizi kódu při umisťování změn na server. Revizi můžete také provádět v rámci celého vývojového týmu na pracovních poradách.

    Jak je revize kódu efektivní? Záleží na úrovni zkušeností vývojáře a "revizora". U začínajících vývojářů budou revize častější a revizorem by měl být zkušený pracovník. Při revizi kódu vytvořeného zkušeným vývojářem nemusí být objeveno mnoho chyb, ale celý proces může posloužit k tomu, že posluchačům budou předány zkušenosti a praktické rady. Technik revizí kódu je více a liší se svojí formálností, obsazením revizního týmu a způsobem evidence nalezených defektů.

    Revize kódu má však i svá rizika. V posuzování práce někoho jiného musíte být opatrní, abyste dotyčnému neublížili před ostatními. Chybně provedená veřejná revize může způsobit konflikty. Měli byste vždy vývojářům, jejichž práce bude revidována, vysvětlit účel a přínosy pro něj i ostatní.

    Statická analýza kódu

    Analýza kódu, která je prováděna bez nutnosti spouštění programu. Jedná se o soubor preventivních technik, které mají odhalit defekty a problémová místa ve vašem systému. Jak se problémová místa poznají? Například podle složitosti. Jak již bylo uvedeno výše, u složitě kódované části aplikace je pravděpodobnější, že vývojář zanesl nebo přehlédl chybu.

    Problémová místa vám pomáhají určit softwarové metriky orientované na kód a na návrh tříd. Uvedu pár příkladů:

    • Cyclomatic Complexity vyjadřuje složitost části programu (např. metody) co do množství větvení a cyklů. Tyto programové konstrukce zvyšují počet možných cest provádění programu. Vysoké číslo indikuje komplikovaně napsané složité metody, které je problematické pokrývat testy. Řešením je metodu rozbít do více menších metod.
    • Line Count vyjadřuje množství řádků kódu v metodách. Dlouhé metody jsou nepřehledné a dělají zřejmě více než jednu věc (pro danou úroveň abstrakce). Použitelnost takových metod je problematická, stejně jako pokrytí testy. Řešením je opět refaktorizace do více metod.
    • Objektové metriky jako Weighted Method Count (celková složitost metod ve třídě), Depth of Inheritance Tree (počet předků třídy) a Coupling Between Objects (provázanost mezi objekty) mohou indikovat problémy v objektovém návrhu.

    Údaje získáné z metrik, by měl vyhodnocovat vedoucí vývojář. Nástroje pro statickou analýzu jsou u komerčních IDE k dispozici ve vyšších edicích. Pokud máte k dispozici nástroje, které metriky zobrazují přímo v kódu, naučte se je vyhodnocovat a vaši práci podle nich přizpůsobovat již během vlastní implementace.

    Mezi techniky statické analýzy patří také validace kódu podle pravidel definovaných pro zdrojový kód. Tato technika zvýší přehlednost a čitelnost kódu. Každý vývojový tým by si měl na začátku projektu zadefinovat kódovací standardy a zvolit nástroj, který bude na dodržování dohlížet. Jak lze využít StyleCop si můžete přečíst v příspěvku Jak psát lepší kód s využitím StyleCopu.

    Volba technologií

    Správnost volby technologií může mít na chybovost zásadní vliv. Rozsáhlejší projekt využívá velké množství technologií a nástrojů. Relační databázový systém, vývojové prostředí, programovací a značkovací jazyky, validační frameworky, perzistentní framework, základ pro služby, prezentační frameworky a komponenty, apod. Vybírejte technologie prověřené a odzkoušené (pozor na poslední releasy), které se dobře používají a mají perspektivu (abyste si je nemuseli vyvíjet v budoucnu sami :). Rozhraní dobrých komponent je snadno použitelné, intuitivní a dobře zdokumentované. Důležitá je také testovatelnost.

    Automatizované testování

    Testování je technika dynamické analýzy kódu. Psaní testů by podle metodologie Test-Driven Development (TDD) mělo předcházet vlastní implementaci. Zkuste si tento přístup zažít a uvidíte, že se vám zalíbí. A pokud ne, vězte, že testy stejně musíte napsat. Jinak se pro vás stane prvotní vývoj a především pozdější zásahy do produkčního kódu noční můrou. Testy jsou indikátory chybových stavů. Vývoj aplikací bez pokrytí testy provozují pouze hazardéři ;)

    První typ testů, který napíšete, budou jednotkové testy (unit test). Základní logika jednotkového testu je jednoduchá. Voláte metodu instance testované třídy s určitými vstupy a validujete výstupy. Pokud výstupy neodpovídají předpokladům, test selže a je nutno hledat chybu v implementaci. Lze prohlásit, že vyšší pokrytí testy lépe pojistí váš kód. Ale je také nutno dodat, že testy se nesmí psát jen z formality, ale musí být správně cílené na problémové situace. O špatných technikách psaní jednotkových testů si můžete přečíst v příspěvku Jak nepsat jednotkové testy.

    Pokud je test napsaný tak, že "vidí" do implementace, mluvíme o white-box testování. Pokud je testovaný kód pro test černou skříňkou, hovoříme o black-box testování. Oba přístupy mají své opodstatnění. Pomocí "bílého" testování snáze pokryjete všechny cesty provádění. "Černé" testování zase zosobňuje naivní přístup klientské strany, který může přinést nečekané způsoby volání.

    Vyšší formou testů jsou integrační a systémové testy. Validují interakci více objektů a funkcionalitu větších celků. Pamatujte, že požadavky na kvalitu kódu testů jsou stejně přísná jako na vlastní testovaný (produkční) kód. Kód testů budete udržovat stejně dlouho jako produkční kód. Zjednodušeně shrnuto, testy by měly běžet krátkou dobu, na libovolném "kompatibilním" počítači, měly by po sobě uklidit a neměly by být na sobě vzájemně závislé.

    Snažte se co nejvíce testů zautomatizovat, určitě se vám práce vyplatí. Bez automatizace nejsou některé typy testů vůbec proveditelné. Těžko se shání několik stovek uživatelů na zátěžové testy, kteří by v jednom čase začali používat a zatěžovat vaši aplikaci :)

    Zautomatizovat se dá i interakce s uživatelským rozhraním vaší aplikace. Volba nástrojů závisí na technologii prezentační vrstvy.

    Ruční testování

    Jedná se o pracnější formu validace funkcionality vaší aplikace, která má však stále svoje opodstatnění. Šikovný tester je vynalézavější než vaše automatizované testy a objeví situace a scénáře, které jste nepředpokládali. Ještě vynalézavější jsou však uživatelé, proto se také uvolňují nefinální beta verze :)

    Automatizace buildů

    Vytvořte a nakonfigurujte buildovací server pro týmový vývoj. Po každém vrácení změn na server spouštějte build průběžné integrace (Continuous Integration), který pohlídá, aby vrácená změna nerozbila integritu projektu. Vývojář získá okamžitou zpětnou vazbu, že jeho změna může zablokovat práci celého týmu.

    Užitečné jsou i buildy pro zajištění kvality. Jsou spouštěny v pravidelných cyklech, například každou noc a jejich úkolem je provádět statickou i dynamickou analýzu kódu. Provádějí se validace kódu, vyhodnocují se metriky, spouští testy. Výsledky se následně vyhodnocují a sjednávají se nápravná opatření.

    Výhodou automatického buildování je i rychlé vytváření průběžných testovacích verzí a jejich nasazení do testovacího prostředí.

    Prototypování

    Někdy je obtížné již v ranných fázích vývoje přesně specifikovat způsob realizace cílových požadavků na systém. Víme sice, co chceme udělat, ale nejsme si jisti, jak bude vypadat například uživatelské rozhraní naší aplikace. Prototyp je funkčně zjednodušený základ (předobraz, demoverze) vyvíjeného systému. Měl by vzniknout relativně rychle a slouží k průběžné revizi požadavků. Prototyp můžete předvést investorovi a získat zpětnou vazbu. Prototyp je vyvíjen v cyklech. V každém cyklu jsou zapracovány získané připomínky.

    Pokud používáte prototypování správně, můžete získat efektivní nástroj pro řízení a směrování projektu. Vyhnete se chybám, které by byly jinak objeveny až později a jejich řešení by bylo nákladné. Pro vývojáře je někdy tvorba prototypu neoblíbenou činností. Může se totiž stát, že celý prototyp se zahodí jako nevhodné řešení a začne se vytvářen nový. Pořád to však méně bolí než složitě předělávat systém v pozdní fázi implementace.

    Revize výstupů v předimplementačních fázích

    Většina vývojových metodik rozděluje vývojový cyklus na fáze specifikace požadavků, analýza, návrh, implementace, testování, nasazení a údržba. V každé fázi vznikne určitý výstup. Například v první fázi specifikace požadavků vytvoříte požadavky na systém. Pokud jsou sestaveny chybně a zjistíte to až v okamžiku předávání software zákazníkovi, vyvstává velký problém. Příslušná část aplikace se musí předělat a rozsah víceprací může být značný. Stejně tak chyby v analýze nebo návrhu vás mohou přijít hodně draho.

    Proto je vhodné podobně jako revidujete implementační kód, revidovat co nejdříve všechny předimplementační výstupy. Taková revize má svůj formalismus a pokud ji uděláte kvalitně, můžete objevit již v ranné fázi závažné chyby. Pokud máte malý vývojový tým, požádejte kolegu, aby si po vás dokumenty s požadavky, analýzou a návrhem přečetl.

    Motivace lidí

    Některé z výše uvedených technik selhávají, pokud je používá člen týmu s nedostatečnou motivací pro dosahování kvality. Revize se dají odbýt, testy se dají napsat jen aby se dosáhlo vyššího pokrytí, při psaní kódu lze ošálit statickou analýzu neúčelnou kompatibilitou s validačními pravidly.

    Členové vašeho týmu musí být motivováni finančně i nefinančně, aby pro ně bylo přirozené a prioritní zajišťovat vysokou kvalitu svojí práce.

    neděle 12. února 2012

    Jak nepsat jednotkové testy

    ... aneb pozor na lháře, křiklouna a místního hrdinu

    Uvádím seznam nejfrekventovanějších antivzorů (špatných technik) pro psaní jednotkových testů. Vyvarujte se jich a Vaše testy budou v dobré kondici ;-)

    • Lhář (The Liar). Jednotkový test, který prochází pro každý testovací případ. Optimismus nás však přejde, pokud se podíváme blíže na implementaci testu a zjistíme, že ve skutečnosti požadovanou vlastnost netestuje.

    • Nadměrná příprava (Excessive Setup). Test, který potřebuje rozsáhlou přípravu ještě před samotným spuštěním testovaného kódu. Stovky řádků a velké množství objektů, které test vyžaduje, způsobí, že je obtížné ověřit testovanou funkcionalitu. Test může selhat z mnoha jiných příčin, než z vlastní chyby v testovaném kódu.

    • Obr (The Giant). Jednotkový test, který pokrývá velké množství testovacích případů a je v rozsahu stovek až tisíců řádků. Přestože validně testuje testovaný kód, jedná se zřejmě o jednotkový test nad božským objektem (God object). Tedy chybný návrh třídy, která v sobě slučuje více zodpovědností.

    • Imitátorna (The Mockery). Používání mock objektů je v mnoha případech dobré a šikovné. V některých případech však mohou vývojáři ztratit kontrolu sami nad sebou a nadměrným používáním mock, fake a stub objektů potlačit vlastní testovanou funkcionalitu. Dochází pak spíše k testování dat, které vracejí jednotlivé mock objekty. Definice mock objektů je navíc velmi křehká a může být snadno rozbita a chybně způsobí selhání testu. To je samo o sobě proti principům TDD. Příliš mnoho závislostí a komplikované vazby na další třídy může indikovat testování božského objektu. V takovém případě by měla být testovaná třída refaktorována nebo by mělo být jedno volání nahrazeno sekvencí více volání metod s menším rozsahem funkcionality. Každé dílčí volání by pak mohlo být otestováno samostatně a není nutné znovu testovat celou sekvenci jako celek.

    • Inspektor (The Inspector). Inspektor je jednotkový test, který ví příliš mnoho o vnitřní struktuře testovaného kódu. Je napsán na míru z důvodu 100% pokrytí kódu. V případě, že je testovaný kód refaktorován a přestože se jeho validita nemění, tzn. měl by procházet, začne test neprocházet. To vynutí současnou změnu i v jednotkovém testu.

    • Velkorysé zbytky (Generous Leftovers). Jeden jednotkový test vytvoří data, která jsou někde persistována (uchována). Jiný test tato data využívá pro svoje vlastní (původnímu testu neznámé) účely. Pokud je takový "test-generátor" spuštěn později nebo pouze částečně, dochází chybně k selhání v testu, který je na něm závislý.

    • Místní hrdina (The Local Hero). Test je napsaný tak, že obsahuje závislosti na prostředí, ve kterém byl vyvinut. V případě, že je spuštěn v těchto podmínkách, pak v pořádku prochází. Pokud se však test spustí v jiném prostředí, selže.

    • Hnidopich (The Nitpicker). Test, který prověřuje kompletní výstup, přestože významná je pouze část vrácené informace. Pokud se změní nevýznamová část vrácené informace, začne test chybně selhávat. Takové testy jsou typické při testování webových aplikací.

    • Tajemný lovec (The Secret Catcher). Na první pohled takový test vypadá, že nic netestuje, neboť nemá žádné asserty. Ovšem v tomto případě platí rčení, že "ďábel je ukryt v detailech". Test předpokládá, že v případě selhání vyvolá testovaný kód výjimku, kterou zachytí a zpracuje testovací framework. Řešením by mohlo být odchycení výjimky do proměnné určitého typu a porovnání na null hodnotu. Nebo můžete použít atribut ExpectedException.

    • Ulejvák (The Dodger). Jednotkový test, který testuje několik méně podstatných aspektů testovaného kódu a vyhýbá se otestování chování zásadního. Obvykle z důvodu vyšší složitosti takového otestování.

    • Křikloun (The Loudmouth). Jednotkový test nebo sada testovacích případů, které posílají na konzoli velké množství testovacích, ladících nebo protokolovacích zpráv, i v případě, že testy procházejí. Jedná se obvykle o pozůstatky ručního ladění. Tyto nevýznamné zprávy znepřehledňují výsledký protokol o výsledku spuštěných testů.

    • Nenasytný lovec (The Greedy Catcher). Jednotkový test, který zachytí výjimku a "polkne" ji včetně trasování zásobníku. Tuto výjimku někdy nahradí informačně méně hodnotnou zprávou. Někdy dokonce chybu pouze zaloguje a test nechá projít.

    • Řadič (The Sequencer). Jednotkový test, jehož procházení je závisle na určitém pořadí assertů, u kterých by na pořadí záležet nemělo.

    • Skrytá závislost (Hidden Dependency). Hodně podobný "Místnímu hrdinovi". Test přepokládá, že před jeho spuštěním jsou připravena data, na kterých je závislý. Pokud tomu tak není, test selže. Vývojář obdrží omezenou informaci o problému a je nucen projít velké množství kódu a zjistit problém se závislými daty. Například starší .dll knihovny mohou být závislé na ini souboru, který řídí jejich chování. Je obvykle složité dopátrat se vlastní příčiny selhání testu a této skryté závisloti.

    • Výčet (The Enumerator). Jednotkový test s testovacími případy, které se jmenují podobně. Např. TestMethod1(), TestMethod2(), ... V tomto případě není možné z názvů testovacích případů určit jejich význam. V případě selhání je vývojář nucen procházet přímo zdrojový kód testu a snažit se pochopit jeho význam.

    • Cizinec (The Stranger). Testovací případ, který nepatří do jednotkového testu. Ve skutečnosti testuje jiný typ objektu, který je využíván a vrácen testovaným objektem.

    • Kazatel operačního systému (The Operating System Evangelist). Jednotkový test, který se opírá o specifické prostředí nebo vlastnosti operačního systému. Příkladem může být assert v testovacím případě, který ověřuje sekvenci znaků pro nový řádek a předpokládá Windows konvenci. Takový test selže při spuštní na Linuxu.

    • Úspěch zaručen (Success Against All Odds). Test, který byl napsán nejdříve tak, aby prošel, místo aby selhal. Naneštěstí pak takový testovací případ prochází i v situacích, kdy by měl selhat.

    • Jízda zadarmo (The Free Ride). Namísto vytvoření nové metody testovacího případu pro otestování další vlastnosti nebo funkcionality, se přidá pouze nový assert k již existujícím.

    • Jedinečný (The One). Kombinace několika vzorů, zejména "Jízdy zadarmo" a "Obra". Test obsahuje jeden testovací případ, který testuje celou sadu funkcionalit testovaného objektu. Obvyklým ukazatelem je to, že testovací metoda se jmenuje stejně jako jednotkový test.

    • Vykukující kocour (The Peeping Tom). Test, který skrze sdílené zdroje vidí na výsledná data jiných testů. Na základě těchto dat může test selhat, přestože testovaný systém je pro testovací případ validní. Toto se běžně stávalo ve FitNesse, kde se používaly statické členské proměnné pro uchování kolekcí, které nebyly korektně vyčištěny po proběhnutí testu. Tento problém se objevoval neočekávaně při některých bězích testů. Vzor známý také jako "Nezvaní hosté" (The Uninvited Guests).

    • Pomalé dloubnutí (The Slow Poke). Jednotkový test, který běží neúnosně pomalu. Když jej vývojář spustí, může si zajít do koupelny nebo zakouřit. V nejhorším případě jej může spustit na konci šichty před odchodem domů.

    • Štastná cesta (Happy Path). Test probíhá pouze po hladké, bezproblémové cestě. Netestuje hraniční hodnoty a výjimky.

    • Podřadní občané (Second Class Citizens). Testovací kód není tak dobře refaktorovaný jako testovaný kód, obsahuje duplicity a je špatně udržovatelný.

    • Spoutaní řetězem (Chain Gang). Dvojice testů, které musí být spuštěné v určitém pořadí. Například jeden test nastaví globální stav systému (globální proměnná, databázová data) a druhý test je na tomto stavu závislý. Např. u databázových testů se může stát, že pokud není provádění uzavřeno ve chráněném bloku a test selže, není po testu korektně uklizeno.

    • Bezejmenný test (The Test With No Name). Test, který byl vytvořen, aby reprodukoval nalezenou chybu a jeho autor nepovažoval za důležité vymyslet mu významové jméno. Namísto posílení (rozšíření) existujícího testu, je vytvořen nový test s názvem TestProChybu123. Po dvou letech, kdy tento test začne selhávat, musíte do systému pro sledování chyb a hledáte Chybu123, abyste pochopili účel tohoto testu.

    • Spáč (The Sleeper). Test, který selže v určitou dobu nebo po určitém datu. Jedná se často o nekorektní kontrolu hraničních hodnot při testování kódu, který pracuje s objekty typu Date nebo Calendar. Problémový může být také běh o půlnoci. Chyba je na straně kódu testu.

    Informační zdroje

    Článek jsem sestavil ze dvou níže uvedených zdrojů a dokořenil jej vlastními vsuvkami. Může se stát, že se mi nepodařilo trefit ideální český ekvivalent pro název některého antivzoru. Navrhněte lepší, rád upravím.

    úterý 7. února 2012

    Pár fíglů od Steva Jobse ...

    ... aneb Jak vybudovat firmu podobnou Apple

    Je potřeba na začátek zdůraznit, že potřebujete garáž! Vážně, garáž je pro začínající projekty hodně důležitá. Bez ní to budete mít opravdu těžké ;) Jo a taky potřebujete někoho podobného Stevu Jobsovi! Troufáte si někdo? Možná by Vám mohlo zvednout šanci na úspěch, pokud byste od mala vyrůstali v Sillicon Valley a potkávali zapálené inženýry v Palo Alto. Pokud jste náhodou adoptovaní, lépe se Vám bude hledat motivace dokázat světu, že původní rodiče udělali chybu, když se Vás vzdali. No tak, nebuďte tak upjatí a zkuste nějaký halucinogen, abyste se trochu odvázali a dokázali dohlédnout do budoucnosti dál než ostatní ...

    Přátelé, musím k Vám být upřímný. Každému to nevyjde. Přesněji, skoro nikomu to nevyjde. Bohužel. Nedá se nic dělat! Pokud Vás však zajímá, jak se vlastně Stevu Jobsovi povedlo vybudovat aktuální technologickou firmu číslo jedna, mohl by Vás tento článek zajímat. Pokud budete pozorní a přemýšliví, určitě se dozvíte něco, co sami s výhodou použijete.

    Obklopte se schopnými lidmi

    "Například Woz byl člověk asi tak padesátkrát lepší než průměrný inženýr. Ten mohl pořádat mítinky ve své hlavě. Mac tým byl pokus sestavit tým ze samých takových lidí, z áčkových hráčů. Lidi říkají, že to spolu nemůžou vydržet, že nebudou schopni spolupracovat, nesnesou se. Ale já zjistil, že áčkoví hráči nemají problém pracovat s jinými áčkovými hráči, ale nedovedou pracovat s hráči céčkovými."

    Pro Jobse bylo osudové setkání se Stevem Wozniakem. Kromě školních legrácek a ptákovin sestrojili "modrou krabičku", kterou byli schopni ovládat miliardovou infrastrukturu telekomunikačního obra AT&T a volat zadarmo po celém světě. Wozniak je také označován za posledního člověka, který dokázal sám sestrojit celý počítač (Apple I). Samozřejmě v garáži!

    Jobs dokázal do svojí firmy nalákat významné manažery a designéry ze slavných firem jako byly Xerox, Intel, Hewlett-Packard, Motorola, Pepsi, apod. Pečlivě vybíral lidi i do nižších technických pozic. Proslulé jsou jeho přijímací pohovory, během kterých dostával zájemce do prekérních situací a sledoval, jak si s ní poradí. Jen si představte sami sebe, pokud by se Vás někdo na přijímacím pohovoru zeptal "V kolika letech jsi přišel o panictví?" nebo "Bral jsi LSD?".

    Vybíral špičkové lidi, kteří nebyli příliš upjatí a dokázali si prosadit svůj názor. Jak sám říká, chtěl se vyhnout "explozi mamlasů" neboli zamoření společnosti průměrnými zaměstnanci.

    Soustřeďte se na inovaci

    "Mám svoji teorii o tom, proč došlo k úpadku ve společnostech jako je IBM nebo Microsoft. Ty společnosti odváděly skvělou práci, inovovaly a získaly v určité oblasti monopol nebo skoro monopol a posléze se pro ně kvalita produktů stala méně důležitou. Společnosti si začaly vážit dobrých obchodníků, protože to jsou ti, kteří mají moc rozhodovat o tržbách, ne inženýři a designéři."

    Apple je dnes považována za nejvíce inovativní firmu. Jobs si může právem připisovat zásluhy v oblastech, ve kterých jeho produkty způsobily revoluci. Macintosh byl první počítač určený pro domácnosti s grafickým uživatelským rozhraním, Pixarovské animáky nastartovaly éru digitální kinematografie, iPod změnil způsob, jakým uživatelé začali konzumovat multimediální obsah, iTunes Store vzkřísil zkomírající hudební průmysl, iPhone byl průkopníkem v dotykových chytrých telefonech, App Store umožnil prodávat malým vývojářům aplikace pro miliony uživatelů, iPad nabídl platformu pro digitální deníky, časopisy, knihy a video. A mnoho dalších.

    Jobs věřil, že dlouhodobě budovat firmu lze pouze v případě, že se bude investovat do inovací. Pro firmu Apple se inovace stala prioritou a součástí celofiremní kultury. Jobs nutil lidi kolem sebe "Myslet jinak". Součástí pravidelných porad byly dlouhé diskuze na téma budoucnosti produktů.

    Spoléhejte na intuici

    "Naším úkolem je číst to, co ještě nebylo napsáno."

    Musíte se pokusit pohlédnout do budoucnosti, abyste dokázali přijít s novátorským produktem. Jobs se nespoléhal na marketingové průzkumy. Tušil, že jeho geniální schopnosti spočívají v tom, že dokáže odhadnout, co bude za několik let hitem. Tento hit pak jednoduše vytvořil. Byl jako stopař, který zavětří odkud vítr vane, chytí stopu a už ji nepustí.

    Dobrá intuice se projevila i při jeho působení ve firmě Pixar. Už to vypadalo, že oddělení animovaných filmů Walta Disneyho nemůže pořádně vydělávat. V těžkých letech investoval velké peníze do krátkých filmů. Celé jeho snažení vyústilo ve vytvoření Příběhu hraček - prvního celovečerního animáku, který vydělal na tu dobu astronomických 362 miliónů $. Další filmy studia Pixar pak obchodní zisk ještě znásobily.

    Vytvořte jednoduchý, ale dokonalý design

    "Náš pokrok spočívá v eliminaci, v odstraňování nadbytečného."

    Design je jedním z nejvýraznější znaků produktů Apple. Jobs byl ovlivněn duchovním učením Zenu, které zvýrazňovalo jednoduchost. Dokázal zjednodušování dovést až na maximální hranici. Výrobky zjednodušoval tím, že odstraňoval tlačítka, software zjednodušoval tím, že eliminoval funkce a rozhraní zase eliminací možností. Astronom Jan Kepler již dříve prohlásil, že příroda miluje jednoduchost a jednotu. Jobs dokázal, že podobně to mají i uživatelé jeho výrobků.

    Jobs dokázal propojit všechna vývojová oddělení, designéry i inženýry v jeden integrovaný fungující celek. V Apple se nejdříve navrhl design, např. počítačová skříň ve tvaru zenové krychle, a podle něho se pak musela přizpůsobit technika. Je jasné, že nejvíc nadávali technici, co že to zase ti designéři vymysleli. Jako jeden chudák inženýr, jehož úkolem bylo vyvinout myš, která by pohybovala kurzorem plynule do všech směrů. Když se vyjádřil, že něco takového nejde, druhý den už v Applu nepracoval.

    Jobs byl designem posedlý a stávalo se, že prototyp výrobku byl mnohokrát přepracováván. Nechtěl dělat kompromisy i za cenu toho, že se oddálil termín uvedení do prodeje. Jako u iPhonu, jehož design byl po devíti měsících vývoje kompletně přepracován. V těžkých dobách firmy Apple se stal právě design zachráncem firmy. Na trhu s počítači, který byl zaplaven levnými šedými krabicemi (rozuměj počítači) firem Dell, Compaq a H-P, si dokázal Apple udržet dostatečný cílový segment tak, aby přežil.

    Už jste si někdy rozbalovali něco od Apple?

    Integrujte hardware, software a služby

    "Lidé nám platí za to, že pro ně integrujeme věci, protože sami nemají čas to řešit. Chcete-li vytvářet skvělé produkty, musíte integrovat, propojovat hardware se softwarem a správou obsahu. Chcete-li proniknout na nové území, tak to musíte udělat sám. Chcete-li, aby Vaše produkty byly otevřené jinému software či hardware, musíte se přinejmenším částečně vzdát své vize."

    Bill Gates svůj operační systém Windows prodal velké spoustě výrobců hardware a tím dosáhl toho, že prakticky ovládl trh s osobními počítači. Věřil, že v otevřenosti je budoucnost. Steve Jobs naopak podporoval princip uzavřeného systému. Díky své touze po dokonalosti nechtěl cizím firmám prodat licenci na svůj operační systém, aby byl provozován na levném a nekvalitním hardware. Tím se jeho počítače typu Macintosh staly nekompatibilní se zbytkem (Windows) světa.

    Jobs se však nenechal odradit od své vize dokonale odladěného systému od jedné společnosti. Postupně vylepšoval všechny aspekty produktů a dokázal nabídnout inovativní technologie a služby, kvůli kterým uživatelé rádi na jeho platformu (do jeho zahrádky) přešli. O správnosti vize svědčí i obchodní vývoj Microsoftu a Apple. V roce 2000 měl Apple pouze dvacetinovou tržní hodnotu oproti Microsoftu, v roce 2010 se obě firmy srovnaly a v roce 2011 již byl Apple o 70% hodnotnější firmou než Microsoft.

    Za Jobsův mistrovský kousek je považováno vytvoření iTunes Store - obchodu s digitální hudbou. Podařilo se mu přesvědčit největší hudební vydavatelství a hudební hvězdy, aby začaly svoji hudbu prodávat uživatelům platformy iPod. V té době panovala skepse, že lidé nebudou mít o takovou placenou službu zájem. Realita však překonala všechna očekávání. Miliontá skladba byla prodána po šesti dnech od zprovoznění služby, 10 miliard skladeb bylo staženo již za sedm let provozu, tedy v roce 2010.

    To co udělal Microsoft v 80-tých letech na poli osobních počítačů, to udělala firma Google s operačním systémem mobilních zařízení. Vyvinula Android, jehož licenci prodala mnoha výrobcům chytrých telefonů. Vlna Android zařízení zaplavila svět. Objevil se levný systém dostupný pro široké masy. Tato zařízení však mají v mnoha případech problémy s kompatibilitou. Je to daň za velké množství permutací verzí Androidu, modelů telefonů a aplikací.

    Nakonec přeci jenom Jobs vpustil externí vývojáře do svého systému. V rámci obchodu s aplikacemi App Store umožnil prodávat aplikace nezávislých vývojářů i zavedených firem. Stanovil však přísnou posuzovací proceduru, kterou musí každá aplikace projít. Chtěl se vyvarovat tomu, aby se platforma iOS zaneřádila viry a nekvalitním obsahem, který by degradoval uživatelský dojem z celého systému. Cítil morální zodpovědnost za obsah jeho služeb a proto do AppStore nikdy nepustil pornografii a bránil se i politickým materiálům.

    Zaměřte se na priority

    "Rozhodnutí, co nedělat, je stejně důležité, jako rozhodnutí, co dělat."

    Když se Jobs nadchl pro nějaký výrobek, dokázal odfiltrovat nepodstatné problémy od těch podstatných. To mu umožnilo soustředit se na řešení těch problémů, které byly pro úspěch rozhodující. Když Jobse vyštípali z Apple a pak jej zase přemluvili, aby se vrátil, vyráběl Apple velké množství různě nekvalitních výrobků. Tržby klesaly a firma se pohybovala ve spirále smrti. První co Jobs udělal, byla revize výrobní produktové řady. Sestavil čtyři kvadranty (Zákaznický a Profesionální) x (Desktop a Přenosný) a v každém kvadrantu ponechal pouze jeden produkt. Stmelil rozklížené vývojové týmy a soustředil energii do vývoje těchto čtyř produktů. Dalším krokem bylo zrušení smlouvy s Hewlett-Packard a opuštění trhu s tiskárnami v roce 1997.

    Důkazem správnosti této strategie je aktuálně vysoká prodejnost mobilních telefonů iPhone. V současnosti je Apple největším výrobcem chytrých telefonů na světě, v podstatě s jedním vícegeneračním modelem. Podíl iPhone na zisku v segmentu chytrých mobilů je kolem 73%.

    Musíte umět zákazníky zpracovat

    "Je důležité přesvědčit lidi o naší velikosti tím, že na ně uděláme pozoruhodný dojem, zvlášť při představení nového produktu."

    Uvádění nových produktů byla Jobsova silná parketa. Pečlivě připravený scénář a schopnost vygradovat atmosféru způsobovala téměř davové šílenství. Dokázal také zapůsobit na vlivné reportéry prestižních magazínů, kteří za získání exkluzivity udělali Jobsovi pořádnou reklamu a správně zahřáli nedočkavé uživatele.

    Jobs spoléhal na sílu médií a investoval do reklamy obrovské sumy. Na každé reklamní kampani se aktivně spolupodílel a projevoval i zde svoji touhu po perfekcionismu. Díky tomu mohli vytvořit reklamní spot na uvedení Macintoshe, který se vysílal během finále Super Bowlu - v nejdrahším reklamním čase. Reklama s běžící kladivářkou pak byla jedním magazínem vyhlášena za nejlepší reklamní spot všech dob. Ve svých reklamách si také Jobs drze troufnul spojit svoje produkty s největšími osobnostmi lidských dějin (Einstein, Gándhí, Picasso).

    Při prezentaci svých produktů se zaměřoval na svůj obchodní cíl - na uživatele a na jejich kreativitu a zkušenost s produktem. Na této myšlence byla vybudována síť kamenných obchodů Apple Stores. Jobs věřil, že obchod je nejmocnější fyzickou prezentací značky. Každý z obchodů Apple Store je architektonické umělecké dílo, navržené podle Jobsových představ o minimalistickém designu tvořeném obvykle skleněnými prvky.

    Musíte být upřímní ke svým kolegům (podřízeným)

    "To je moje práce říkat na rovinu, když je něco na hovno, a ne to lakovat na růžovo."

    Pokud chcete stvořit něco fenomenálního, musíte po sobě i po ostatních vyžadovat maximální nasazení. Jobs dokázal lidi ve svém okolí namotivovat tak, že překonávali svoje limity. Byl na ně zároveň velice tvrdý. Pod jeho vedením panovala nulová tolerance k nevýkonnosti. Fénování zaměstnanců patřilo k běžným komunikačním technikám. U Jobse nefungoval filtr mezi mozkem a jazykem, který by zjemňoval ostré výpady proti kolegům. Když se však s odstupem času zeptáte členů vývojového týmu Mac na spolupráci s Jobsem, dostanete odpověď, která vás může překvapit. Období spolupráce s Jobsem pro ně bylo nejúžasnější etapou jejich profesního života.

    Zdvořilí a vlídní vůdcové, kteří mají starost, aby se někoho nedotkli, většinou nedovedou tak účinně prosazovat změny.

    Pár vět na závěr

    Život Steva Jobse je samozřejmě plný chybných rozhodnutí a špatných investic. Nezdary zažívá mnoho lidí, kteří se rozhodnou riskovat a vzít zodpovědnost do vlastních rukou. Je to normální. Ve výsledku však Jobs obstál takovým způsobem, že vytáhl garážovou firmu do čela smečky technologických gigantů.

    Myšlenky a citace uváděné v tomto článku pocházejí ze životopisné knihy Steve Jobs od Waltera Isaacsona. Musím přiznat, že kniha na mě udělala velký dojem a donutila mě přemýšlet nad některými věcmi v nových souvislostech. Téměř 700 stran je nabitých zajímavostmi z doby, kdy se rodily velké věci. Z doby, kdy proti sobě stáli dva velikáni počítačového věku narození v roce 1955, oba bez dokončeného vysokoškolského studia - (otevřený) Bill Gates a (uzavřený) Steve Jobs.

    Pokud máte čas, určitě si ji přečtěte, ať už jste nebo nejste fanouškem Jobse. Nebo už jste ji četli? Líbila se Vám?

    Budu rád, pokud zanecháte komentář. Povzbudíte tím autora do dalšího psaní ;-) Nebo možná odradíte ;-)