Dave Farley törvényei

Dave Farley vicces és érdekes ember, nagy fejlesztői tapasztalattal, és nem mellesleg kiváló megfigyelő. A törvényeit projektek közben, emberekkel dolgozva fogalmazta meg, és a fejlesztést, a programozást tudományos szemszögből közelítette meg. A törvényei ezek:

  1. Az emberek hibásak
  2. Minden dolog sokkal komplikáltabb, mint ahogy gondolod
  3. Minden dolog érdekes tud lenni

Az emberek hibásak. Ez nem a viselkedésre vonatkozik, hanem inkább az emberre mint valamilyen megtervezett dologra. Az emberi szervezet nem tökéletes, eleve úgy van felépítve, hogy csaljon: optikai csalódás, akusztikai csalódás, vakfolt. Az emberi természetbe kódolva van a nagyjáboli megoldások elégségessége, és valljuk be, az életben sok területen ez elég is. Mi emberek hajlunk arra, hogy „Jól van az úgy", egy programban viszont nem lehet majdnem jó számítás vagy majdnem jó működés. Ez nekünk természetellenes, és ezért olyan küzdelmes a tesztelés is számunkra. Amint elkezdnek a teszten jó eredmények jönni, azonnal hajlamosak vagyunk azt gondolni, hogy amit csináltunk, az jó, és mehet is rögtön a gitbe.

Pedig nem így van. Itt jön a második törvény: minden dolog komplikáltabb, mint ahogy gondolod. A peremfeltételeknél vagy különleges esetekben egy probléma, egy programkód is produkálhat szélsőséges dolgokat, és ezeket le kell kezelni. Még akkor is, ha csak ritkán fordulhatnak elő, és az alap megoldás, amit elsőre gondoltunk, szinte teljesen lefedi az eseteket.

A tesztelés és a hibakezelés viszont legtöbbször unalmas, mert úgy érezzük, hogy nem a valódi üzleti logikára koncentrálunk, hanem csak a szükséges köröket futjuk. Erre való a harmadik törvény: mindig próbáljuk meg valamilyen érdekes dolgot vagy értéket találni még az unalmas munkában is. Mert minden munka tud élvezetes vagy érdekes lenni, ha a megfelelő szögből tekintünk rá. Ha elkezdünk azon gondolkodni, hogy miként tehetem a saját kódom „golyóállóvá", akkor a hibakezelés kihívássá válik. Én például a teszteknél mindig futtatok egy statisztikát, hogy mekkora a valós kód és a teszt kód egymáshoz viszonyított aránya, és a tesztnek el kell érnie az 50%-ot. Ebben a kihívásban el lehet merülni, és hirtelen a tesztelés sem lesz monoton. De ugyanilyen érzés, amikor valós esetekkel próbálod elérni a 100%-os code coverage-t. Mert közben az az érzésed alakul ki, hogy amit csináltál, abban az üzleti logika mellett a kiváló minőség is ugyanúgy érték. Sőt, ez az, amire igazából büszke vagy. Nem arra lesz az ember büszke, hogy megcsinált egy üzleti funkciót, amit mások is tudnak használni, hanem arra lesz büszke, hogy úgy csinálta meg, hogy arra bátran rá lehet támaszkodni, és a kódját bárki bármikor megnézheti, sőt örül is, ha valaki megnézi. Ennek a gondolkodásnak az elsajátítása teszi lehetővé, hogy egy programozó a TDD rajongója legyen, és e szemlélet szerint végezze a munkáját.

Régebbi mérések szerint egy programozó naponta 15 sort ír. Ugye, hogy ez kevés? A számítás módja viszont ez volt: a projekt során a tényleges programba bekerülő sorok száma, osztva a projekt első napjától az utolsó napjáig lévő idővel, és osztva a projekten dolgozó programozók számával. A programsorokba csak az éles és végleges kódok számítanak bele, a vargabetűk és tévutak nem. A segédeszközök kódja szintén nem számít bele, és a tesztelésre írt kódok szintén nem. A projekt vége felé a munka lelassul, és ez a szakasz legtöbbször már az átadás után van. Az ügyfél használja a terméket, de még mi mindig javítunk benne, és sokszor csak keservesen keressük a hibákat: debug, teszt, javítás. Ezekben az időkben nem tudunk igazán értékes kódot készíteni, és a projekt idejének nagy részét valójában ez a szakasz emészti fel. A mai tesztelési módszerekkel, és azzal, hogy a unit tesztek korát éljük, a problémák hamarabb derülnek ki. A unit tesztek segítettek abban, hogy a napi 15 sort feljebb tudjuk vinni. A sok „nem értékes" kód tehát abban segít, hogy egyre több értékes kód legyen.

Régen, ha egy modul elkészült és bekerült a kódba, először éles lett, és voltak benne bugok, vagy olyan esetek, amelyek nem voltak kezelve. Ezeket szépen lassan, egyesével felderítettük, és egy idő után az adott modul stabillá kristályosodott. Ekkor már bátran lehetett rá támaszkodni, és ezekre a modulokra épült a szervezet üzleti értéke. Ezek a modulok és algoritmusok kincsek voltak, és egy termék vagy vállalkozás tudott ezek köré épülni. Viszont ezeket a modulokat senki nem merte átírni, és nem is volt szabad bennük komoly változtatásokat végrehajtani, mert a rátámaszkodó programok stabilitását veszélyeztettük vele. Ezek a modulok így teljes egészében megkövesedtek, és nem voltak képesek a hosszabb idő után felmerülő igények teljesítésére, legyen az egy újabb fejlesztői környezet, egy technológia vagy akár csak egy szabályrendszer bevezetése. És szépen lassan ezek az egykor stabil sziklák, amikre a szervezet épült, elkezdtek horgonnyá válni, gátakká. Ezeken a projekteken egyszer csak nem volt már élvezetes dolgozni, és a munkamorál és a termelékenység is odaveszett. Külön szakszavunk is van ezekre a forrásokra, a „legacy code", ami ma már szitokszónak számít. Hiszen minden egyes megtalált és javított bug egy újabb if-et, elágazást, vagy esetet rakott a kódba. És ma már egy komplett if-háló van, és amikor megnézünk egy függvényt, és abban olyan vizsgálatot találunk, amiről nem tudjuk, miért van benne, csak azt, hogy ilyenkor a program kicsit másképp működik, akkor már nem merünk belenyúlni, nem uraljuk a kódot. És itt kezdődik a gány kód, a gány a fertő, a fertő a halál...

Ma viszont, ha egy modulnak alapos unit tesztjei vannak, akkor sokkal biztosabbak lehetünk abban, hogy az adott modulban már a fejlesztés során jó pár hibát kijavítottunk, így már az induló minősége is sokkal jobb. Emellett, ha egy újabb hibát találunk a használata során, akkor azt először egy újabb unit teszttel elő kell hozni, és csak utána javítani. Így tudjuk, hogy a javításunk nem tört el más unit teszteket, és a program javítása nem okozott további hibákat a kódban. A unit tesztek másik nagy előnye, hogy a modult refaktorálni lehet, és technológiát lehet váltani alatta, mert amíg a tesztek lefutnak, addig a program úgy működik, ahogy elvárható. És így a modulok át tudnak esni olyan refakt körökön, amik megszüntetik az if-hálót, és irtják a gányt! A gány a fertő, a fertő a halál...

Mivel a modulok meg tudnak újulni, továbbra is stabil sziklák maradnak, amelyekre a szervezetet vagy a terméket építeni lehet, de nem válnak érinthetetlen bálványokká és horgonyokká.

A tettek mezeje

De akkor hogyan csináljuk? Az előző fejezetben arról volt szó, hogyan ne csináljuk, és milyen hibákat követhetünk el mi, programozók. Tudnunk kell azt is, hogyan kellene csinálni. Sok módszer van, amelyik egyformán jó lehet, és csapatonként, emberenként és termékenként is más-más lehet a megoldás. Közös pontok azért vannak, a saját vagy mások tapasztalataiból, és minden olyan módszer vagy folyamat, amit a szervezet életében alkalmazunk, valahogyan csatlakozik ezekhez az alaptételekhez.

  • People first
  • Check everything
  • Change everything

Az ember az első, vagyis a dolgozó, aki az értéket teremti. Nektek kell jól érezni magatokat a helyeteken, nektek kell elégedettnek lenni a feladattal és körülményekkel, és az elért eredményekkel. A második pont: mérj mindent, a döntések ne tippek vagy megérzések alapján szülessenek, hanem mérések és eredmények alapján. A harmadik: merj változtatni. Ha nem változik a program, ha nem változol te, ha nem változnak a módszerek, akkor nem is tudnak jobbak lenni.

Az ember az első

Adrian Cockcroft, a Netflix technikai igazgatója mondta, hogy ennek a mentalitásnak volt köszönhető, hogy a Netflix gyorsabban tudott dolgokat végrehajtani, mert mindenki a célért dolgozott, és nem központilag volt megmondva, hogy mit kell csinálni. Önálló döntéshozó pontok voltak, csoportok, amelyek a saját dolgaikról tudtak dönteni. A döntésnél persze figyelembe kell venni a szervezet érdekeit, nem csak az egyéni érdekeket. De hiszem, ha motivált és tenni akaró emberek vannak egy csoportban, akkor az egyéni célok és a csoport céljai ugyanazok: létrehozni valamit. Ilyenkor a motiváció magától jön.

„Ha hajót akarsz építeni, ne hívj össze embereket, hogy gyűjtsenek fát, ne oszd fel a munkát és adj parancsokat, hanem keltsd fel bennük a vágyat a nagy, végtelen tenger iránt."
— Antoine de Saint-Exupéry
What are you doing?

Three men were carrying the stones. Somebody asked them: what are you doing?
„I am working hard," answered the first man, wiping the sweat out of his face.
„I am earning money," the second man said, rolling up the sleeves.
The third man said, looking upwards at the sky: „I am building a temple."

Feel the difference.

Szerintem ebben van a motiváció lényege. A főnök nem tud motivációt adni, a vezetés dolga az, hogy megfogalmazza a víziót, és életben tartsa. Hogy hogyan? Először is úgy, hogy a dolgozó az első. Aki értéket teremt, annak kell olyan körülményeket és feladatokat kapnia, amit élvez, amit meg tud csinálni. De ha a korábbi fejezetből indulunk ki, akkor láthatjuk, hogy valójában minden feladat élvezetes tud lenni. Ha valami nem az, akkor csináljuk gyakrabban, és találjuk meg a módját, hogyan törjük apróbb részekre, és így végül szüntessük meg a fájdalmat.

Ha valami fáj, csináld gyakrabban

A mindennapi munkában sok feladatot utálunk, vagy azért, mert monoton, vagy azért, mert sokat kell várni, vagy azért, mert veszélyes és könnyű elrontani. Az „If it hurts, do it more often, and bring the pain forward" Jez Humble Continuous Delivery könyvéből van, és nem csak a Continuous Deliveryre érvényes. Ha egy adott munkafolyamat valamiért kellemetlen, akkor azzal, ha gyakrabban csináljuk, egyrészt rutinná válik, másrészt egy idő után ki fogunk rá találni valamilyen automatizálási lehetőséget.

Nem kell rögtön nagyban gondolkodni. A feladatot fel kell bontani kisebb részekre, és azokat egyesével megoldani, egyszerűsíteni vagy automatizálni. Ez már középtávon is megtérül, mert nő a minőség, senki nem kerüli ezt a munkafolyamatot, és nem rontja a munkakedvet sem. Ahogy sok más területen, itt is igaz a Pareto-elv: a kellemetlen jelenségek 80%-a az okok mindössze 20%-ára vezethető vissza. Ezeket kell először megoldani, és ezeket is kis erőbefektetéssel. Először nem a tökéletes megoldás a lényeg, hanem az, hogy valamilyen megoldás legyen a problémára. Minden előrehaladás már segít, és ezt folyamatosan csinálva, folyamatos lesz a fejlődés is.

Ha egy dolgot megoldunk, más dolgok persze továbbra is kényelmetlenek vagy veszélyesek maradnak. Ezeket a következő körben oldjuk meg, és így, közösen, szépen lassan elfogyasztjuk a problémát. Ha valami rosszul ment, vagy rosszul sült el, akkor analizálni kell az okokat, és úgy kell fejleszteni a rendszerünket, hogy a jövőben elkerüljük ezeket a hibákat. Ennél is fontosabb, hogy nem hibáztatjuk sem magunkat, sem másokat. Senki nem akar hibázni, de hibák mégis vannak.

Az az érték, ami a vevőnek érték, nem az, ami a főnöknek. Egy szervezet csak akkor lehet sikeres, ha a vevők elégedettek. A sikerhez nem csak ez kell, de enélkül biztosan nem lesz siker.