Jaká jsou úskalí Quick-and-Dirty-Programming a jak se jim vyhnout? Část 2.

V předešlém článku jsme uvedli metodu Quick and Dirty Programming. Jak bylo trefně poznamenáno v komentáři od kolegy u předešlého článku, tak není až tak relevantní otázka, kdo se s ní potkal, ale naopak, spíše ať se přihlásí ten, kdo se s touto metodou nikdy nesetkal.

Kde hledat hlavní příčiny tolerance k nečistému kódu a kde je podstata tak časté preference této metody tvorby SW?

Samozřejmě v jednoduchém pohledu zde hraje roli tlak na termíny. Opravdu se může stát, že v projektu nastane situace, kdy termín doslova opravdu „hoří“ a zakázka při nedodržení deadline pak už vůbec nebude obchodně realizována. Jenže to bývá jen opravdu „někdy“ a je to důsledek jiných chyb v postupech v řízení projektu.

Spousta tlaků na termín však nastává v principu ze zavedení filosofie ve firmě už na počátku projektu: Při počátečních odhadech se dopředu počítá s metodou Quick and Dirty Programming jako se standardem. Zavádí se postup „chceme dělat hlavně a bezpodmínečně rychle a čistota kódu nás nezajímá“ – a tomu se podřizují další kroky. Ale to je již principiálně jiná situace, to už není nějaká krize: Zvažuje se totiž dopředu (nikoliv v kritické situaci), že tato metoda bude nasazena. Někdy to nastane vědomě, někdy nevědomky (nevědomky tehdy, když se o rozdílu tvořte kód kvalitně a nebo špinavě vůbec neví a neuvažuje se o něm).

Jednou z hlavních příčin zavedení metody Quick and Dirty Programming  je „optimisticky pojatá psychologická vize“ růžových optimistů vycházející z předpokladu, že katastrofa nikdy nenastane.

Uveďme si klasický příklad z teorie her:

Máte na výběr ze dvou možných hazardních her (podotknu, že obě dvě jsou pro vás dost nevýhodné). Důležité je, že budete tuto hru hrát nyní a pouze jednou, jen si musíte z těchto dvou strategií vybrat. O příštích hrách vůbec nevíte, zda a kdy se uskuteční. Dvě varianty dané hry jsou tyto:

První možná varianta: Na konci hry určitě přijdete o 500 Kč.

Druhá možná varianta: Bude se házet mincí (která není falešná) a pokud padne orel, přijdete o 1 000 Kč, pokud padne panna, tak nepřijdete o nic.

Kterou hru si vyberete?

Matematik vám řekne, že z hlediska teorie her je to jedno. V obou případech totiž statisticky vzato „v průměru“ přijdete o 500 Kč. Jenže první hra je psychologicky více deprimující a „beznadějná“. Spousta vizionářů (růžových optimistů) se raději přikloní k druhé variantě, protože „tam je aspoň trochu naděje, že se to nestane“. Dokonce, i kdyby byla druhá varianta trochu ztrátovější, stejně ji zvolí. Ale to už je psychologie a nikoliv matematika.

Právě v podstatě tohoto příkladu můžeme spatřit jeden z důvodů preference nečisté metody tvorby SW. Je to psychologicky optimistická vize: Problémy se odloží za cenu možného projevení později… a ty snad ani nenastanou, to je přece budoucnost.

Problém je v tom, že uvedený příklad je pouze matematický a jednoduchý příklad, který zohledňuje pouze „okamžitý korunový zisk resp. ztrátu“ v dané hře (v tomto příkladu pro názornost byl zvolen nerozhodný výsledek). Jenže v budoucnu se určitě projeví ještě další vedlejší efekty související s rozdílem mezi oběma strategiemi:

1. U druhé „riskantní“ hry, která v našem příkladu preferuje rychlé a nečisté programování, vzniká tzv. „technologický dluh systému“. Tento dluh bohužel neroste lineárně, ale spíše exponencionálně . Stará dobrá poučka návrhu SW říká: „Každá nečistota plodí další nečistoty“. Důsledkem toho nakonec může být stav, kdy „nečistý systém“ je nejenže hodně chybový, neflexibilní ale hlavně se z něj časem stává netransparentní molochální slepenec a práce na něm přechází v dost nepříjemnou detektivku.

2. Systém navržený Quick and Dirty postupem je chybový a špatně se testuje. Nutno podotknout, že zde se dá tento efekt tak trochu zmenšit jakýmsi částečným přechodem k variantě první hry s menšími náklady a to zavedením povinného Unit testování. Musí se však pro tuto činnost vyhradit odpovídající prostor a čas, protože i Unit testy něco stojí. Tyto nutné náklady na Unit testování jsou skvělým příkladem oné „stálé ztráty“ v první hře (ale jedná se o nutné náklady, které se jako takové určitě vyplatí).

3. Ztráta dobrého jména firmy. Vzhledem k tomu, že kvalita systému postupně a někdy i rychle klesá, zákazníci vyjadřují svou nespokojenost a někdy může dojít až ke katastrofickému jevu, kdy se systém stane natolik neudržitelným, že se zpočátku nadějný větší projekt prostě odhouká (viz například komentář u předešlého článku).

4. Není nad to, pokud na projektu pracují zapálení a nadšení vývojáři chtějící odvádět kvalitní práci. Zavedení filosofie tvorby Quick and Dirty je opravdu velmi dobrým zabijákem entusiasmu a profesního nadšení pro tvorbu SW. Neumím si představit horší příkaz, než „dělejte to rychle a špatně“. I když takto to nikdy od vedení nezazní, ale podstatou této filosofie to je. Pouze programátor cynik může psát vědomě nečistý kód bez skřípání zubů. Navíc (a to není zanedbatelné) v takovémto prostředí se vývojáři nestanou nikdy špičkovými profesionály, protože nebudou profesně růst (na to totiž není čas). Prioritou v metodě „rychle a nečistě“ je nějak „zbastlit“ systém a nikoliv se vzdělávat a odvádět kvalitní práci. Osobně toto považuji za nejhorší důsledek, protože záporné projevy se stávají principální a nevratné. Postup Quick and Dirty se stává zažitým obvyklým standardem…

Co s tím?

Samozřejmě nastává otázka, jak u takového vlaku přehodit výhybku. Bylo by příliš naivní se domnívat, že ve firmě někdy nastane ideální situace, kdy se bude tvořit pouze a jenom čistý kód. Ten nebude nikdy  stoprocentní Ale pokud je ve firmě zavedena filosofie Quick and Dirty obecně jako standard, musí se něco změnit. O tom bude další pokračování seriálu.

Poznámka nakonec: Přiznám se, že jsem kdysi vkládal velké naděje do postupu tvorby pomocí SCRUM resp. jiných agilních technik. Domníval jsem se (kdysi a mylně), že určitá míra „svobody“ tvorby napomůže v týmu lépe tvořit čistý kód. Jenže už první zkušenosti z projektů mi ukázaly, že tomu tak není. Dokonce naopak, u mnoha projektů tvořených pomocí SCRUM jsem se tak setkal s opravdu ukázkovými příklady programátorských paskvilů. Zmíněná „svoboda tvorby“ se mnohdy projevila dost častým ignorováním návrhu čistého kódu včetně opomíjení kvalitní počáteční analýzy. Díky tomu ve firmě mnohdy nastal zpětný pád do chaotické metody tvorby SW.

Navíc jsem u agilních technik (SCRUMu) vypozoroval jednu dost zajímavou paradoxní skutečnost.

zdroj obrázku
https://blogs.deusto.es/master-informatica/kanban-agile-planning-with-burn-down-chart/

Hovoří se sice o “svobodě”, ale technika plánování pomocí Burndown Charts se může vůči programátorům chovat jako opravdu velmi kvalitně upletený bič a může na vývojáře vytvořit tak silný tlak , že se nakonec díky tomuto tlaku uchýlí k technice Quick and Dirty.

Pokračování následuje.

Nepřehlédněte k tématu





Categories

About the Author:

správce a majitel Serveru objektových technologíí http://www.objects.cz

5 Comments
  1. Karel Král

    Článek výborně popisuje situaci právě v naší firmě. A to je taky důvod, proč se kvalitní vývojáři rozhodují k odchodu. Protože je touto metodou dlouhodobě nebaví vyvíjet.

  2. Jiří Matějček

    Děkuji za zkušenosti s agilními technikami. Málokdo umí rozlišit agilní od “libovolný”. I agilita má mít daná pravidla.
    Co se týká čistoty kodu, zase na druhou stranu, máme tu kolegu, který myslí až příliš na všechno dopředu, co by se mohlo stát, co by kdo mohl chtít, co by se mohlo změnit. Počítá snad i s tím, že zítra slunce nemusí vyjít :). Ovšem je to na základě jeho dlouholetých zkušeností, co se kdy v systémech změnilo, a co to způsobilo. Důsledkem toho jsou zase velmi složité struktury s mnoha stupni volnosti, s metaatributy, vazebními tabulkami, a každý údaj má “pro jistotu” validitu od-do. Když se pak do toho píšou selecty, tak než se vše projoinuje a owheruje, je to na tři stránky minimálně. Takže je potřeba hledat kompromis, najít zlatý řez. Mnohdy to trvá několik hodin, než se na řešení shodneme, ale nedá se říct “tento návrh je špatně” a “tento je dobře”. To ukáže až ta budoucnost. Přijde mi ovšem fajn mít v týmu zástuce obou filozofií 🙂

    • Díky za tuto poznámku ohledně vašeho kolegy. Pokud je to tak, jak píšete, tak jeho filosofie nepatří k zastáncům čistého kódu, ale naopak. Ono totiž „přepísknout“ flexibilitu znamená v důsledku špatný nečitelný a zbytečně složitý kód.
      Jako klasický příklad bych uvedl přehnaný „posun meta“ (o „posunu meta“ viz kniha Analytické modelování na našich stránkách), kdy se nakonec místo původního systému vyvíjí jakýsi „meta systém“, který umí zdánlivě všechno, ale ve skutečnosti neumí nic.
      Pamatuji, jak se v jedné firmě objevila myšlenka vyvinout univerzální bankovní systém, kde by různé bankovní produkty (úvěr, termínovaný vklad, vedení účtu atd.) vznikaly pouze a jenom konfigurací hodnot u jednoho „univerzálního produktu“. I když obchodní oddělení bylo z této myšlenky enormně nadšené, tak se záhy zjistilo (naštěstí brzy), že ta myšlenka je sice pěkná, ale že je cestou do pekel a projekt se odhoukal hned na začátku.
      Osobně preferuji řešení, které je analyticky přesné, ale využívá Generalizaci (alias Inheritanci v OOP) a polymorfismu včetně dobrého nasazení vzorů Design Patterns , zejména principu Open Closed. Tím se při přesném plnění požadavků současně získává požadovaná flexibilita. Takže například v našem příkladu by se sice v modelu bankovního systému objevila třída Bankovní produkt, avšak jako abstraktní třída s různými konkrétními potomky (navíc by vzniklo několik propojených stromů dědičnosti, viz “Bridging” v uvedené knize).
      Zmíněný „posun meta“ se hodí pouze tam, kde se v analýze najde množina instancí téhož charakteru, které analyticky konkrétně neoslovujeme svým významem, ale jejich význam můžete přiřadit odkazem do číselníku jako „význam resp. typ “ (například “osoba má adresy různého typu adres”).
      Jinou otázkou je, zda nasazovat mechanismy z Design Patterns „předvídavě“, tj. pouze s jedním potomkem v Generalizaci anebo až tehdy, kdy je skutečně třeba, kdy se najde druhý potomek v Generalizaci (v našem příkladu v předešlém článku viz např. Kočka a Pes).
      V tomto ohledu jsem spíše realistický pesimista a zastánce myšlenky, že dokud se neobjeví v požadavcích výskyt možné flexibility, tak bychom ji neměli zbytečně zavádět. Pokud se „tuší“, že by tam mohla být (ale v požadavcích není), navrhuji dát tuto možnost do dokumentace, upozornit na ni a tím se připravit na budoucí změnu. Samozřejmě zde přitom hraje velmi velkou roli dobře vedená konzultace s budoucím uživatelem – Product Ownerem.
      Pokud se přežene nasazení flexibility pomocí Design Patterns (tj. pomocí polymorfismu), tak vzniká podobná situace, jako kdybychom navrhli v budově stěny s velmi mnoha dveřmi, které nikdo nikdy neotevře a jsou zbytečné. Takové stěny se stávají velmi nepřehlednými, zbytečně složitými a pracně tvořenými. Můžeme ale v případě „tušení“ dveře na stěnu namalovat (tj. nebourat) a upozornit tak, “pozor, tady by se mohly dveře v budoucnu vyskytnout”.
      Této problematice včetně praktických cvičení se hodně věnujeme na školení Čistý kód a Design Patterns ( http://www.objects.cz/wp/pro-firmy/1-inhouse/design-patterns-inhouse/ )

    • ještě poznámka k agilním technikám, konkrétně ke SCRUMU.
      Mnoho výše postavených vedoucích v SW firmách vůbec neví, “vo co gou” a vidí ve SCRUMU řešení všech potíží včetně tvorby nečistého kódu. Vytvářejí tlak na zavádění SCRUMU “jen aby byl” s velmi podivnými důsledky.
      Ve SCRUMu (obecně v agilních technikách) vidím hlavní plus ve velmi rychlé zpětné vazbě a to jak vůči budoucímu uživateli (Product Ownerovi) a to i ve zpětné vazbě v týmu ve schůzkách různého typu (jak se to dělalo apod.).
      Jenže sám SCRUM problém s Quick and Dirty programováním neřeší.
      Některé firmy dokonce jedou “chaotickou” metodou vývoje a ospravedlňují to agilností.
      Agilnost není chaos.

0 Pings & Trackbacks

Leave a Reply