Dejte někomu
program a frustrujete ho na den. Naučte ho programovat a frustrujete
ho na celý život. – David Leinweber
V r. 2012 jsem
shrnul pár postřehů o softwarovém vývoji a zároveň slíbil, že
se nedopustím pokračování. Protože sliby se mají porušovat a
protože se mi nashromáždilo několik dalších poznámek, o něž
se chci podělit, zde je další dávka.
Architektura
Dali byste si do
svého CV “Junior SW Architect”? Přijali byste takového člověka
do firmy? Asi sotva. Slovo Architekt evokuje někoho
seriózního, někoho staršího. A je to odůvodněný požadavek –
architekt má (měl by mít) v první řadě zkušenosti s nejméně
několika komplexními projekty. Měl by mít vizi, přehled o celku,
měl by umět konzervativně tlumit naivní nadšení juniorních
vývojářů na jedné straně a naopak argumentovat ve prospěch
zdánlivě nerozumných rozhodnutí, pokud jsou dlouhodobě užitečná.
Pokud slyší „získáme tím to a to“, měl by vždy dodat „a
tímto za to zaplatíme“. Měl by… jistě umíte pokračovat.
Pokud se jen trochu
orientujete v zásadách moderního vývoje software, nemohl vám
uniknout rezervovaný názor agilních věrozvěstů na softwarovou
architekturu a částečně i určitý despekt k SW architektům jako
takovým. Je to odůvodněné – tato nedůvěra pramení z doby,
kdy se plánovalo stylem
waterfall. Architekt býval mudrc v bílém plášti, který
vše na základě zadání vyprojektoval v průběhu jediného
geniálního tvůrčího aktu, předal vývojářům nějaký plán
(v dávné minulosti štos vývojových diagramů, dnes nejspíš
nějaká UML schemata), nemyslící poslušní vývojáři plán
uchopili a realizovali, nemyslící poslušní testeři otestovali, a
pak se to nasadilo.
Dnes jsme dál.
Základním předpokladem agile je, že jakákoliv změna musí
zůstat levná po dobu celého vývoje (tedy po dobu života
projektu, vč. fáze údržby). O architektuře se nemluví, vzniká
jaksi za pochodu. Architektura není něco, co můžete naúčtovat
zákazníkovi, architektura není feature. Není to něco, co
by si product management objednal, tak proč bychom to vůbec měli
řešit? V předchozím postu jsem toto téma jen nadhodil:
Důvěra v projekt vzniká agilními iteracemi. Že je tato
inkrementální cesta "mnoha sprinty k cíli" často
pomalejší než trasa pro poctivé maratonce, pak nakonec nikoho
nezajímá.
Ano, určitě dnes
nepotřebujete mudrce v bílém plášti. Nepotřebujete knížecí
rady někoho z venku. A zvláště nepotřebujete architekta,
jenž se odmítá dotknout zdrojového kódu a nechce se ušpinit
konkrétními problémy, tzv. „implementačními detaily“
všedních dní.
To ale neznamená,
že nepotřebujete člověka, jenž má architektonické cítění.
Někoho, kdo má zkušenostmi vypěstovaný cit pro rovnováhu mezi
krátkodobými a dlouhodobými cíli, mezi celkem a detailem. Musí
to být někdo uvnitř týmu se znalostmi o projektu, ale i s
dobrým přehledem o nových technologiích. V ideálním případě
je to člověk, jenž stojí u zrodu projektu a má představu o jeho
organickém růstu. Je to mediátor, jenž se na každý technický
spor dokáže podívat z pohledu obou stran konfliktu a dovede
nezaujatě posoudit pro a proti každého řešení. Také je
kompetentní, co se týče technologického dluhu. Dává pozor, aby
tento příliš nenarostl a neprodražoval změny, naopak si
uvědomuje, že rychlý postup občas vyžaduje jeho krátkodobý nárůst
(pilotní experimenty). Umí včas naplánovat fázi refaktorování
a rozpustit technologické úkoly v rámci normální agilní
iterace, aby okolí nenabylo dojmu, že se příliš
snížila velocita
projektu. Protože
kvůli tajm tu market jsme přešli na skram, ale proč to
nakódili tak zabagovaný, že to musej teď furt jen
fixovat?
Jistě vás napadne,
že zatímco instantních manažerů s agilními
certifikáty je všude plno, jejich protihráč –
architekt-programátor-superhrdina – se nedá sehnat, a pokud ano,
nedá se zaplatit.
Pravidla
Co když si ale roli
architekta rozdělí několik členů týmu? Co když je
architektonické rozhodnutí záměrně konsensuální?
Zkuste s touto
představou chvíli pracovat: Architektura není dílo jednotlivce,
jde o kolektivní proces. Místo ustavení jediného osvíceného
diktátora zodpovědného za dlouhodobou technickou strategii
posílíte svědomí všech vývojářů tak, aby ke špatným
rozhodnutím pokud možno nedocházelo. Myslíte, že je to nemožné?
Dejte dvěma programátorům stejné zadání a jako odpověd získáte
šest navzájem odlišných způsobů, jak ho lze implementovat. Tak
jak by mohlo docházet ke shodě v architektuře?
Trik je v tom, že
sice při vývoji software skoro vždy existuje více cest, jak
dosáhnout jednoho cíle, vývojáři se ale dokážou snadno
shodnout v jejich hodnocení („když použiji tuto knihovnu,
znamená to...“, „když přejdeme na toto API, musíme řešit...“,
atd.). Důležité je, aby za zásadnější rozhodnutí (např. o
závislosti na konkrétní technologii třetí strany) nebyl
zodpovědný jediný člověk. Aby nedocházelo k prosazení
individuální vůle na úkor skřípání zubů ostatních.
Samozřejmě, že čím více lidí se podílí na rozhodovacích
procesech, tím je větší riziko paralýzy analýzou.
Rozhodnutí prodiskutované v okruhu několika zainteresovaných je
ale vždy žádoucí a v dobrém týmu je tento postup zpravidla
efektivní.
S rostoucím počtem
členů týmu začne být zjevné, že některá rozhodnutí mají
obecnou platnost. Není třeba stále opakovat malé debaty, pokud
existuje pozitivní zkušenost s důsledky jejich závěrů. Začne
vznikat sada zvyků (best practices),
ať už v psané nebo neformální podobě. Tato sada mívá většinou
povahu detailních pokynů z agilní praxe – např. jednotný
způsob formátování kódu (coding standards),
pravidla revize kódu (peer review), automatizace, atd.
Často ale tímto
postupem organicky vznikají i vysokoúrovňová pravidla s dopady na
architekturu řešení. Zde je nutné zdůraznit jednu důležitou
věc: Architektonické pravidlo není – na rozdíl od agilních
dogmat – nějaké jedno pevné schema, spíš jde o návod k tvorbě
schemat, mají-li být životaschopná. Nejde tedy o stav, ale o
proces. Architektura je tak flexibilní, což se cení, protože
schopnost konat rychlé změny je jedním ze základních principů.
Když se časem
ukáže, že se nějaký postup přežil, mělo by být samozřejmé
ho po dohodě revidovat. Podobně, jako nikomu nepřijde divné mazat
řádky nepotřebného kódu, mělo by být snané zrušit
rozhodnutí, když se ukáže, že už nevyhovuje novým podmínkám.
Pravidla musí být
jednoduchá, aby fungovala a nesmí jich nikdy být
mnoho. Jejich jednoduchost a nízký počet dovolí, aby byla snadno
bez velkého přemýšlení dodržována. Komplikované a od reality
odtržené zásady jsou běžně obcházeny, realita je vždy
složitější než znění sebedelšího zákona. Libovolný proces
je snadno dodržován, pokud tvůrčímu člověku pomáhá a
zbytečně ho neomezuje.
Na architekturu a
agilní pravidla se můžeme dívat jako na jakési metaprogramování
programátorů. Pokud dobrý programátor produkuje dobrý software,
pak dobrá architektura a rozumné zásady produkují dobré
programátory. Abych nebyl špatně pochopen – nejde o
technokratický styl řízení lidí, ono „produkovat programátory“
znamená především je naučit, jak se co nejlépe mohou sami
zorganizovat v rámci týmu, aby si navzájem nepřekáželi. A
protože vývojáři jsou většinou otevřeni novému, vnímají
tyto procesy jako novou zajímavou společenskou hru, jejíž
pravidla si musí osvojit a mohou se zároveň spolupodílet na
jejich tvorbě.
Důležité je stále
mít na paměti, že příliš byrokracie brzdí, zvlášť v malých
týmech. Programátor se chce plně soustředit na svůj problém,
cokoliv mimo něj ho zdržuje. A obrovskou brzdou je pocit nesouladu, pocit zbytečné nebo rutinní práce,
nedůvěra v cíl snažení. Konsensus v zásadních otázkách
naopak vnímá vývojář jako něco přirozeného.
Elegance
Tím se dostávám k
poslední oblasti, osobnosti a emocím programátora. Mohlo by se
zdát, že v dnešním SW vývoji emoce nemají své místo. Vývojář
jako disciplinovaný profesionál má zdánlivě činit objektivní
kroky od dobrého zadání k dokonalé implementaci. Domnívám se,
že tomu tak ale není a že individuální preference a intuice
programátora se do výsledného software promítají na každém
kroku, téměř na každém řádku zdrojového kódu. Jsme odlišní
v tom, jaké programovací jazyky upřednostňujeme, lišíme se v
tom, co považujeme za jednoduché a co naopak za složité, jinak
důvěřujeme novým postupům a technologiím, máme odlišnou
potřebu psát komentáře, neshodujeme se často v tom, co znamená
dostatečné pokrytí testy, atd.
Věcí, které může
osobnost a zkušenosti vývojáře ovlivnit, je příliš mnoho na
to, aby se dalo od emocí a intuicí snadno abstrahovat.
Opět zde platí, že
přestože se dva programátoři jen málokdy shodnou v tom, jaký
kód je dobrý, často se shodují v názoru na to, že nějaký kód
je špatný. Znakem špatného kódu je jeho nepřehlednost,
nekonzistence, množství podmínek, příliš mnoho varovných
komentářů (beware, fixme, ugly…). Špatné řešení
jednoduše vzbuzuje pocit, že zdrojový kód je obtížně
udržovatelný a přerostl autorovi přes hlavu, že se v něm
dopustí chyby každý, kdo se pokusí o jeho úpravu. Pocit, že
nejlepší by bylo to celé přepsat.
Technologický dluh
je v podstatě hromadění ošklivého. Vzniká
plíživě – jsou to denodenní malá rozhodnutí, nevinně
vypadající kompromisy, nánosy prachu rostoucí ve zdrojovém kódu,
které se v nejméně vhodnou chvíli jako lavina utrhnou a zavalí
všechny zúčastněné. Aby zůstal dluh pod kontrolou, je nutné
čas od času uklízet, zjednodušovat kód, zpřehledňovat a
opravovat drobné defekty. Pokud se z této činnosti stane
dlouhodobý návyk, dovoluje to projektu růst organickou cestou, od
jednoduchého ke složitějšímu, při udržení konstantní
kvality. Pořádek (čistota kódu) umožňuje lepší spolupráci.
Když se naopak
stane nepořádek normou, všichni se naučí tolerovat malé
nedostatky, ignorovat varování, vypínat automatické testy.
Kvalita software postupně upadá, takže je časem snadné
přehlédnout nějakou fatální chybu.
Dalším těžko
sdělitelným pocitem je elegance kódu. Co je a co není
elegantní, je značně subjektivní záležitost. Např. ve volbě programovacích
jazyků panuje mezi programátory téměř dokonalá neshoda: Ruby mi
připadá v mnoha ohledech elegantnější a ergonomičtější než
Python, přestože jsou oba jazyky podobné. Naučil jsem se ale
respektovat, že je mnoho lidí s opačným názorem, o čemž
vypovídá nezpochybnitelné vítězství Pythonu ve světě
strojového učení. Ve vlastním kódu se snažím nevynalézat kolo
a rád se opřu o cizí řešení, na druhou stranu rozumím tomu,
když si kolega napíše vlastní implementaci něčeho velmi
základního, jen proto, aby se vyhnul závislosti na nové knihovně,
atd.
V programování
platí, podobně jako v jiných lidských činnostech, že vkus a
soudnost roste se zkušeností. Nerodíme se se schopností poznat
dobrou hudbu od špatné, jsme vychováváni k tomu poznat kvalitu od
škváry tím, jak posloucháme. Podobně se z nás gurmán nestane,
dokud neochutnáme opravdu dobrá jídla.
Cit pro eleganci a
jednoduchost řešení tak najdete snáze u zkušeného vývojáře
než u začátečníka. Opačně to ale neplatí – i zkušený
programátor může odbýt návrh rozhraní, nemá-li čas nebo je mu
to jedno.
Dobrá, jak se tedy
snadno stanete vnímavým k estetické stránce software?
Nejde to snadno, ale
stojí to za tu námahu: Čtěte cizí zdrojový kód, snažte se
pochopit složitější systémy. Proč je API navrženo právě
takto a ne jinak, jak jsou části odděleny a jak propojeny, jak
vypadají úspěšné refaktorizace, atd. Uvažujte nad komunikačními
protokoly, datovými strukturami, relačními schematy. Snažte se
vidět, jak se systém vyvíjí v čase – sledujte, které jeho
části se mění pomalu a které rychle. Co je jednoduchá změna a
jak vypadá drahá oprava. Proč a kde se schovávají chyby.
Kde je užitečné optimalizovat a kde je to naopak škodlivé. Přečtěte si o tom nějaké chytré texty a buďte kritičtí.
A nejen to. Čtěte
dobré knihy nejen o SW, foťte nebo kreslete, cestujte a
naslouchejte, poslouchejte nebo provozujte muziku, obdivujte krásné
věci, přemýšlejte o symetrii, o řádu světa, o eleganci.
A Captain
Obvious by
ještě dodal: Pokud
se chcete stát dobrým softwarovým architektem, především velmi
programujte!
Žádné komentáře:
Okomentovat