Top 5 clean code technika

Miután végig olvastam a Clean Code-os könyvet, azon gondolkodtam: tök jó volt ez a könyv, de hogyan fogjuk tudni a projektben alkalmazni a több száz oldalon keresztül ismertetett mintákat, szabályokat?
Aztán eszembe jutott egy ötlet: kiválasztom, hogy szerintem mi az az 5 legfontosabb szabály vagy smell, ami leginkább befolyásolja a tiszta kód kialakulását, és aminek az alkalmazását szigorúan vesszük, miközben kódolunk. Íme az én listám.

Single Responsibility Principle (SRP)

Az SRP alkalmazásától azt várom, hogy megszűnnek a gigaméretű osztályok (ún. „God class”-ok), helyettük sok kisméretű osztályt hozunk létre, amelyek önmagukban könnyen átláthatóak és tesztelhetőek. Ha később változik a funkcionalitás, az nagyon könnyen módosítható a kódban.

Duplikációk (azaz Don’t repeat yourself)

Ugyan korábban is úgy gondoltam, hogy a duplikációk megszüntetése fontos, a könyv felvilágosított abban, hogy a legkisebb duplikációt is érdemes komolyan venni. Az elv szigorú alkalmazásától azt várom, hogy a kód azonos műveletet végző részeinek kiemelése új absztrakciókat hoz létre a programban.

A duplikációkat érdemes magasabb szinten is áttekinteni. Nem csak az duplikáció, ami karakterről karakterre megegyezik.

Túl sok argumentummal rendelkező metódus

A könyv szerint az a legjobb, ha nincs argumentuma egy metódusnak, ennél kicsit rosszabb, ha egy argumentummal rendelkezik, a kettő és a három nagyon indokolt esetben elfogadható, de a háromnál több argumentum biztosan megkérdőjelezhető.

Természetesen lehetne ezekben az esetekben Parameter Objecteket készíteni, de ezzel nem oldjuk meg az eredeti problémát, azt, hogy sok adatot adunk át egy metódusnak (csak becsomagoltuk).

A megoldás a problémára az, hogy külön osztályt kell létrehozni, amely a konstruktorában megkapja a szükséges adatokat, így a metódusok már magukon az osztály fieldjein végzik a számításokat. Ez az elv tovább erősíti az SRP-t.

Válasszunk leíró, nem félreérthető elnevezéseket!

Ezt nem lehet eléggé hangsúlyozni. A megfelelő elnevezések használata egyértelművé teszi a kódot, és feleslegessé teszi a gyorsan elavuló kommenteket.

Egy metódus egy dolgot végezzen!

Ez az elv a végletekig leegyszerűsíti a metódusokat, és pár sorossá redukálja őket. Pl. ha ciklus kell, akkor a metódus csak a bejárást végezze, és delegálja tovább a ciklusmagot, ha kivételeket kell kezelni, akkor külön legyen metódus, ami csak a kivételkezelésért felel stb.

Ha apró metódusokat tudunk készíteni, az azt jelenti, hogy az először bonyolultra sikerült kódot megfelelően dekomponálni vagyunk képesek, és az egyes részek megfelelő elnevezésévél áttekinthetőbbé tudjuk tenni a kódunkat.

A sok apró metódustól azt is várom, hogy sokkal szembeötlőbbé válnak a duplikációk, ill. az, ha egy osztály már túl sok mindent csinál. (És akkor jöhet az SRP.)

Ti mit választanátok be a top 5-be? (Íme egy cheat sheet, ami segít választani a Clean Code-minták közül. Forrás: http://www.planetgeek.ch/2010/06/22/clean-code-and-clean-tdd-cheat-sheets)

Share
This entry was posted in Programozás and tagged , . Bookmark the permalink. Follow any comments here with the RSS feed for this post. Trackbacks are closed, but you can post a comment.

Comments

  • SRP: ovele azert vigyazni kell, mert a) hasznalata sok-sok osztalyt eredmenyez, ami a kezelhetoseget rontja; b) nehez azt az egy feleloseget meghatarozni. Egyebkent nagyon jo szemlelet.
    Túl sok argumentummal rendelkező metódus: Ez viszont nem feltetlen allja meg a helyet. Ha konstruktorban adjuk at azokat az adatokat, amik a metodushoz kellenek, akkor bevezetunk egy olyan allapotot az objektumnak, ami a klienshez kapcsolodik. Ez viszont tobbszalu alkalmazasoknal problemass lehet. Tehat szerintem: ami allapottal kapcsolatos az konstruktorban menjen at (ha van alapertelmezes, akkor esetleg lehet ra settert csinalni), ami viszont nem az allapothoz tartozik, az csak szepen metodus parameter legyen.

  • A túl-sok argumentumos pont ellentmond a funkcionális programozás -szintén megfontolandó- elveinek:

    -Metódus csak a paramétereiben megkapott értékekkel dolgozzon, ne legyen külső függősége és ne változtasson meg semmit a környezetében.
    -Ne használjunk állapotokat.
    -Használjunk immutable objektumokat.

    Egyre gyakrabban köszönnek vissza egyébként a funkcionális programozás elvei az enterprise java programozásban.

    A post-ban felvázolt megoldásnak van egy-két hátránya:
    -szinkronizációról gondoskodni kell.
    -életciklus. Mi van ha kétszer hívják meg a metódust? Mennyire újrafelhasználható ez az objektum?
    -field-eket érjen el a metódus vagy accessor-okat? Öröklődés lehessen?

  • Amúgy az első ötöt választanám be. :) (Class design.)

  • Nagyon szep munka ez a Cheet Sheet, de a konyv olvasasa nelkul, nem tudok mit kezdeni az egymondatos definiciokkal, nem egyertelmu, hogy mit jelentenek. … ugy tunik, semmi sem ment meg attol, hogy elolvassam a konyvet! :)

  • Egy metódus egy dolgot végezzen!
    Ez az elv a végletekig leegyszerűsíti a metódusokat, és pár sorossá redukálja őket. Pl. ha ciklus kell, akkor a metódus csak a bejárást végezze, és delegálja tovább a ciklusmagot, ha kivételeket kell kezelni, akkor külön legyen metódus, ami csak a kivételkezelésért felel stb.
    —————-
    Erre tudsz esetleg példát bemutatni? Az átláthatóságára lennék kíváncsi.

  • Marhefka István

    Jul 19th, 2010

    zmb: Igen, az SRP-től pont azt várom, hogy viszonylag kisméretű osztályaim legyenek. A felelősség meghatározása igazából csak gyakorlat kérdése.

    Túl sok argumentummal kapcsolatos metódus kapcsán nem teljesen értem az állapottal kapcsolatos gondolatmenetet, de a kitérőként megemlített, setteres megoldás első blikkre nem tűnik egy elegáns megoldásnak ;)

    Egyébként ha a metódusnak átadom a sok argumentumot, akkor rendszerint azokat legtöbbször tovább is kell passzolnom (mivelhogy a metódusból kisebb, önmagukban is értelmezhető metódusokat hozok létre). Így másból nem áll a kód olvasgatása, mint a parametérek passzolgatásából. Ha ezt a sok logikát egy külön osztályba szervezem ki, akkor olvashatóbbá válik a kód (vagy legalábbis azt várom tőle).

  • Marhefka István

    Jul 19th, 2010

    pcjuzer: Az egyetemen mi is tanultunk (nekünk is tanítottak :)) funkcionális programozást, arra még viszont nem sikerült rájönnöm, hogy pontosan mi a közös része az enterprise szoftverfejlesztéssel.

    Én úgy gondolom, hogy a funkcionális programozás elvei megfontolandóak, de egyáltalan nem mérvadóak az enterprise fejlesztés során. (Miért is kellene azoknak lenniük? Írhatnál erről egy postot! ;-))

    Az általad felvetett érvek (funkcionális programozás érvei kapcsán):

    - Metódus csak a paramétereiben megkapott értékekkel dolgozzon, ne legyen külső függősége és ne változtasson meg semmit a környezetében: egy metódust egy objektumon hívunk (legalábbis OOP-ben). Ha nem használja a metódus az objektum fieldjeit, akkor ezzel az erővel static is lehetne.

    - Ne használjunk állapotokat: ez mindenképpen hasznos irányelv általában, de ha állandóan ezen stresszelnék, akkor már idegroncs lennék :)

    - Használjunk immutable objektumokat: ez is mindenképpen üdvözítő elv.

    “A post-ban felvázolt megoldásnak van egy-két hátránya” – gondolom, itt a többargumentumos metódusos gondolatmenetre gondolsz. Biztosan vannak hátrányai, de úgy gondolom, hogy egy elég jó rendezőelv a kód tisztán tartásához.

  • Marhefka István

    Jul 19th, 2010

    pcjuzer: Szóval a SOLID-elveket részesíted előnyben :)

    Beugratós ez a top 5 kérdés, mert mindenkinek más lesz (saját skilljétől és projektjétől függően). Én pl. szívem szerint a “használj leíró elnevezéseket!” pontot nem is vettem volna bele a listába, mert nekem annyira nyilvánvaló, és helyette inkább mást választottam volna. Összességében nézve viszont ez egy igenis fontos elv.

  • Marhefka István

    Jul 19th, 2010

    juliusc: Hát, igen, sajnos, nem úszod meg a könyv elolvasását! ;)

  • Marhefka István

    Jul 19th, 2010

    lukit: Nincs nálam most a könyv, hogy az ottani példákat ide másoljam. Szerdán megteszem.

  • István: Oké, felírom a subject queue-mba!

  • disclaimer: nem olvastam a könyvet de az arg nélküli metódusok ilyesztő baromságnak tűnnek elsőre (de nyitott vagyok vitára ;))

    én változatlanul Kent Back: Implementation Patterns c könyvét tartom mérvadónak low-level kódolási technikákból és ha egy fontosat kell mondani belőle akkor tartsd külön a gyakran változó dolgokat a ritkán változóktól (és igen, érdemes elolvasni a könyvet mert nem mondok részleteket :))

  • Marhefka István

    Jul 20th, 2010

    Kristóf: Nem olyan nagy baromság az az arg nélküli metódus…

    A “tartsd a változó kódot a ritkán változótól” jó ötlet, csak szerintem a legtöbb fejlesztő egy (új) üzleti probléma kapcsán nincs képben arról, hogy mik a kódnak azon a részei, amik gyakran fognak változni, és mik azok, amik nem. Másrészt pedig az SRP automatikusan megoldja ezt a problémát.

    Először én is Kent Beck két könyvét olvastam (TDD, Implementation Patterns), azóta elkezdtem másokat is olvasni ezekben a témákban. Én arra jutottam, hogy mások egyértelműen jobbakat írnak, és nem is annyira jók azok a Kent Beckes könyvek…

  • hát pedig Kent Back smalltalkos volt és ugye aki smalltalkott programozott, már rossz coder nem lehet.. ;)))

    az arg nélküli metódus használatára dobj fel egy példát ha tartod a véleményed, megnézném közelebbről

  • Marhefka István

    Jul 20th, 2010

    Kristóf: Nem vonom kétségbe Kent Beck kóderi képességeit, én csak a könyveiről alkottam véleményt.

    Eljuttatom Hozzád a könyv azon részét, ami érdekel.

  • A sok paraméteres metódusoknál mindenképpen megemlíteném a builder patternt. Eleinte idegenkedtem tőle, de nálunk a gyakorlatban nagyon jól bevált

  • Tetszik mi? butcher :)

  • De hogy erdemben hozzaszoljak a vitahoz enis. Parameter nelkuli metodus, humm… Szep elgondolas de akkor mashol kell atadnod a parametereket es ugye ami egyuve tartozik azt ne bontsuk szet. Tegyuk fel van egy metodusod ami 10 parametert fogad (mondjuk beszur egy sort egy db-be es most felejtsuk el ORM-et), akkor tegyem azt az egy metodust egy kulon osztalyba, adjam at a 10 parametert konstruktorban vagy setterben es insertaljak? Valljuk be ez kicsit abszurd lenne. A masik reszrol megkozelitve viszont valoban abszurd egy 10-20 parameteres metodus (en 5-nel huznam meg a hatart, es akkor is lesz par hely ahol akar tobb is lehet de ez elegge ritka), vannak esetek ahol builder pattern kivalthatja a dolgokat, de van ahol csak parameter ojjektum a megoldas (sztem ezt sem szabad lenezni). Mondjuk rubyban ez szepen meg van oldva (nevesitett parameter atadassal atlathato marad a kod pl:
    ojjektum.metodus :nev=>’nev’, :cim=>’cim’
    )

    de belul ugyanolyan hash lesz ebbol is mintha egy parameter tombot adnank at.

    Az en par eves programozoi tapasztalatom alapjan ugy latom hogy patternek kellenek, ajalott hasznalni oket, de nem esz nelkul es nem mindenhol. (kulonben hova lesz a muveszi szabadsag? ;) )

  • Marhefka István

    Jul 26th, 2010

    b0c1: Mostanra vált világossá számomra, hogy itt egy kis félreértésről van szó. Én nem arra gondoltam, hogy mindig 0 paraméterű metódusokat csináljunk, és külön osztályt csináljunk, aminek a konstruktorában adjuk át a paramétereket.

    Ha jól emlékszem, a könyvben említett egyik példa a Point osztály. Ahelyett, hogy X és Y koordinátákat adnánk át külön-külön egy metódusnak, azokat egy Point osztályba rakhatjuk, ezáltal egy paraméter kerül átadásra a kettő helyett. (Azt hiszem, ezzel a példával nem szereztem nagy meglepetést senkinek :))

    Végeredményben úgy gondolom, hogy az általad említett példa az adatbázisba történő rekord beszúrásával kapcsolatban is ugyanez a minta. (Az osztály deklarációjában nevesítettek a kérdéses oszlopok, és a megfelelő fieldek a megfelelő oszlopok értékét tartalmazzák.)

    Azonban a legtöbbször nem ennyire egyértelmű a helyzet, és nem csinálunk minden metódushoz külön parameter objectet (amivel nekem önmagában semmi bajom), csak azért, hogy minél kevesebb paraméterünk legyen. És itt jön a képbe az említett Clean Code-os technika, ami teljesen megkérdőjelezi pl. a 3 argumentum hosszabb argumentumlistákat.

    Először én is szkeptikus voltam, de elkezdtem betartani az elvet. A tapasztalatom az, hogy azáltal, hogy törekszünk az egészen rövid argumentumú metódusokra, hamarabb kiütközik az, ha egy adott osztály vagy metódus már túl sok felelősséggel bír, és ehelyett inkább ki kell szervezni a funkcionalitást egy újabb osztályba.

    Ahol lehet (érdemes, célszerű), ott természetesen alkalmazhatjuk a parameter object (is).

  • “Egy metódus egy dolgot végezzen!”. Pont most futottam bele egy ilyen kódba. Valaki betartotta ezt. Túlságosan is következetesen. Ez jó elmélet, mondhatni az esetek 95%-ban kimondottan hasznos. De vannak kivételek.
    Régi kódot bolygattam meg. Egy kis metódus hív egy másikat. Az egy újabbat. Esetleg belerak egy feltételes elágazást. Esetleg castol és elágazik. S mikor eclipsben elkezded ezt bejárni… Mikor 10 java file van nyitva és már 20-30 (szó szerint) szinten keresztül próbálod követni a kódot, akkor bizonyos embereket elküldenél valahova… S persze a javítás azonnal kell. S ha egy ilyen kis építőkockát megmozgat az ember, fogalma sincs mi fog borulni… A kód 12 éves, nincs itt aki írta, nincs junit teszt, nincs doksi, az üzleti elemzők sem tudnak semmit róla.

    Szóval jó az elmélet, de csak megfelelő doksival és junit tesztekkel. Másképp szerintem inkább a káoszt fokozza, mint segíti. Másrészt, ha van kismillió metódusom, akkor azokat fejben is kell bizonyos szinten tartani, hogy tudd mi van, mi nincs.

    Nekem jobban bejöttek (mégha talán veszélyesebbek is) a 2-3 argumentumos util jellegű metódusok. Kicsit csináljon többet, mint egy dolog, írok rá komplexebb tesztet, de számomra karbantarthatóbb és jobban használható. Persze itt is fontos a mértékletesség.

  • Marhefka István

    Sep 9th, 2010

    szilsan: “Ez jó elmélet, mondhatni az esetek 95%-ban kimondottan hasznos.” Igazad van, de azt hiszem, ez általánosságban is elmondható a szakmánkban :) Ahogy közhelyesen mondják: “There’s No Silver Bullet” (Amúgy – ha jól tudom – ez a mondás is a Mythical Man-Month óta van.)

    “Egy kis metódus hív egy másikat. Az egy újabbat. Esetleg belerak egy feltételes elágazást. Esetleg castol és elágazik. S mikor eclipsben elkezded ezt bejárni… Mikor 10 java file van nyitva és már 20-30 (szó szerint) szinten keresztül próbálod követni a kódot, akkor bizonyos embereket elküldenél valahova…”

    Önmagában a kis metódusok nem garantálják a sikert. Úgy kell szervezzük a forráskódunkat, hogy ami összetartozik, az lehetőleg egy helyen legyen. (Kohézió.) Amúgy egyetértek, én sem szeretem az állandó delegálást, áttekinthetlenné teszik a kódot. De ez szerintem általában nem abból fakad, hogy kis metódusméretre törekszünk, inkább az objektumok közötti bonyolult asszociációk eredményeznek ilyet.

    “Szóval jó az elmélet, de csak megfelelő doksival és junit tesztekkel.” A teszteket mindenképpen írni kell. Ha kisebbek a metódusok, és alkalmazzuk az SRP-t is, megvalósítható a unit tesztelés is.

    “Másrészt, ha van kismillió metódusom, akkor azokat fejben is kell bizonyos szinten tartani, hogy tudd mi van, mi nincs.” Itt is a korábbi gondolatot ismételném, ami a kohézióra hajaz. Mésrészt pedig a sok kisebb méretű metódus lehetőséget biztosít arra, hogy észrevegyük a kódban rejtőző duplikációkat. Ezeket pedig kiküszöbölhetjük, és egy szinttel magasabb szinten írhatjuk a kódot, mert kiemeljük a duplikációt. (Ezért is vettem be ezt az elvet is a Top 5 közé.)

    “Nekem jobban bejöttek (mégha talán veszélyesebbek is) a 2-3 argumentumos util jellegű metódusok.” Pontosan nem értem, mire gondolsz. A Util jellegű osztályok (ill. metódusok, ahogy Te mondtad), procedurális kódot eredményeznek. Ez bizonyos esetekben nem gond, de összetett domain modellek megvalósításakor érdemes kihasználni az OO előnyeit, mert akkor jelentősen csökkenthető a komplexitása a kódnak.

  • Util method alatt azt értem, hogy a metódusom több dolgot is csinálhat a bemenet függvényében. Valóban, így nem lesz very-pure OOP. Mindenesetre nekem az a tapasztalatom, hogy nagyon-nagyon tiszta OOP ritkán jön/jöhet létre. Aztán lehet, nekem kéne fejlődnöm ezen a téren :)
    “sok kisebb méretű metódus lehetőséget biztosít arra, hogy észrevegyük a kódban rejtőző duplikációkat” – nem tudom. Erre vannak tool-ok, amelyek segítenek felismerni ezt. Inkább a tervezés fázisában látom azt a helyet, ahol ki kell buknia a duplikáltságnak – mert ha jó üzleti logika (nem tartalmaz duplikációt), és a fejlesztés ezt implementálja, akkor a kód sem tartalmazhat duplikációt (és ez igaz DB szinten is). De sajnos nincs tökéletes specifikáció, nincs olyan, aki mindent átlát. Kellenek a segéd tool-ok, és még így sem lehet tökéletes a kód.

    A kohézió, amit említesz. Az elején minden jónak tűnik: modulok, interfacek, határok, kapcsolat, kommunikáció, protokolok. Minden megvan a maga helyén. Majd jön az első, a második, sokadik “feature request”, kezdenek a határok közeledni. majd jön a “ez gyorsan kell azonnalra” feature, átlapolódások… és ez már egy lavina , és egyszer csak ül az ember a szószban és újraírná az egészet. De ezt mindenki ismeri, s úgy látom erre nincs megoldás, jó esetben is csak törekvés van rá. Most is, sírni tudnék némelyik megoldáson, de nincs kapacitás refactorálni, meg “élesben ez már működik”, meg csak az a lényeg, hogy menjen – egyszer meg majd borul az egész.

    Huh, elkalandoztam. Naszóval igazad van, nincs univerzális megoldás. De törekedni kell :)

  • @szilsan: normalis nincs olyan, hogy ez gyorsan kell, azonnalra. Vagy ha van, akkor nincs melle SLA garancia. Egy uj kodot meg kell irni, le kell tesztelni, bugfixalni kell, ellenorizni kell – es csak akkor lehet ra vallalni azokat a garanciakat, amiket a kod tobbi reszere.

    Ami a korlatozott parameterszamu objektumokat jelenti: en is azt mondom, hogy ovatosan kell hasznalni azokat. Van olyan feladat, amikor egyszeruen sok parametert kell atadni, mert ez szukseges ahhoz, hogy az adott muvelet mukodni kezdjen.

    A masik: ha egy konstruktornak sok parametere van, az mar kivetel a szabaly alol? Aligha. Ez esetben viszont egyedul a Builder pattern teszi lehetove a szabaly betartasat, betartatasat, ami viszont nem mindig jo megoldas.

    Felreertes ne essek: en is torekszem arra, hogy 1,2,3 argumentumnal tobbet ne adjak at egy metodusnak, de szerintem a 3 argumentum meg boven elfogadhato, tobb az mar kerulendo.

  • Ohm, termeszetesen a korlatozott parameterszamu _metodusokra_ gondoltam.

  • Marhefka István

    Mar 21st, 2012

    “ez gyorsan kell azonnalra” – erre van pár kedvenc aranyköpésem:

    - “The only way to go fast is to go well” (Robert C. Martin)

    - ASAP is poison. (Rework c. könyv)

  • Marhefka István

    Mar 21st, 2012

    hron84: ez a kevés paraméterrel eredeti szándékom szerint azért került bele, mert ha a Single Responsibility Principle-t helyesen alkalmazzuk, akkor egy-egy funkció/algoritmus/behaviorhöz egy-egy nem túl bonyolult osztály tartozik, ami saját tagváltozóiban tárolja a végrehajtáshoz szükséges adatok. Így az osztályon belüli metódusoknak nincs szükségük arra, hogy ezeket újra és újra paraméterként átadjuk.

    Ha tökéletes az SRP szerint az osztályunk felelőssége, nem biztos akkor sem, hogy érdemes mindent tagváltozóba bevinni, mert a legtöbbször az osztályon belüli metódusok hívási sorrendje nem mindegy, és ezt a rejtett időbeliség (Hidden Temporal Coupling) jó paraméterátadással explicitté tenni.

    Ha most írnám a cikket, ez nem kerülne bele a TOP 5-ba :)

    Szerintem amúgy a sok paraméter mindenképpen problémát jelöl, de szerintem sok esetben nincs rá normális megoldás a technológiai integrációs problémák és a nyelvi korlátok miatt.

  • Nos, én egy laza egyszerű mozdulattal azt mondanám, hogy SOLID, és akkor le is van tudva 5 egyben és ehez tennék még négy továbbit :)

    SOLID
    Code at Wrong Level of Abstraction
    Structure over Convention
    KISS
    YAGNI ha ez is van a táblában

    Egyébként maga Uncle Bob is elmondja, hogy nem az lesz, hogy megvilágosodsz, ha elolvastad a könyvet, és máris jó kódot fogsz írni elsőre, sőt, ő maga is bemutatja a könyvben, hogy hogyan írt meg először valamit, és refaktorálta át 3-4 lépésben. Ez egy nagyon kemény, és fájdalmas tanulási folyamat.

    Én azon rögögök, amikor egyesek jönnek, és elkezdik magyarázni az elolvasása után, hogy igen, ezekkel egyet értek, de a paraméteradás résszel nem. De hát ott van szépen érvekkel és példákkal. Hozd te is az érvedet, de csak azért, mert ezt a részét nem értetted meg, ne mondd azt, hogy hülyeség. Igen, 3 hét intenzív tanulás után, mert rengeteg
    könyvet és videót tettem magamévá, nekiülltem, hogy na most akkor, és lefagytam. Egy autoloader osztályt már 3 napja írtam, mire elkészült 50 sor lett az egész osztály mindenestül.

    Ha érdekel, akkor nagyon sokat kell olvasni és gyakorolni, ezt nem lehet megúszni. Ha nem értetted meg a könyvből, keress más fórumokat, és kérdezz ott, előbb utóbb rutinszerű lesz ezeknek az elveknek a betartása.

    A múltkor valaki azzal jött, hogy ok, de a setter-eket én meghagyom, nekem az úgy kényelmes. Rendben kisbarátom, csak akkor arra kérlek, ne nevezd magad profi programozónak.

    $Car->setEngine(Enginge $Engine);

    Komolyan? Láttunk már olyat az életben, hogy valaki menet közben motort cserélt? :))

    A jelenlegi kód, amit saját magamtól örököltem, katasztrófális. Mindenhol statikus metódosuk, amik más statikus metódusokat hívnak meg, na ez a végeláthatatlan, és így lesz 20-30 fájl nyitva egyszerre. Szép csendben elkezdtem refaktorálni, sokszor 3 perc amíg kiszervezek egy blokkot onnan, ahova nem való, és átteszem egy metódusba, vagy másik oszályba, adok magamnak rá időt, mondjuk 10 percet, hogy jó névvel lássam el, megfelelő könyvtárba, domain alá tegyem, és kész, tiszta száraz érzés, tudni fogom mit csinál, ha tesztem is van rá mégjobb, rájöttem, hogy kinyírtam vele 3 duplikációt, azokról a helyekről is ezt hívom majd, és mostantól megbízom benne, nem kell mindig végigmenni rajta, megnyitogatni, Jelölöm a könyvtárakat egy perfix-szel, ahol már az új módszereket használom, és szép lassan minden nap fejlődik és tisztább lesz a kódom, míg egyszer majd teljesen az.

    Nem kellett a nulláról újrakezdeni, pici átalakítás az autoloaderen, és kb. 1 óra munkával elkerültem, hogy amikor két hét múlva elő kelljen vennem, 2 órákat töltsek el azzal, amig kidebugolom, hogy akkor ezt most itt hogy? Ja, most ez az eset van, akkor erre megyek, aha, de ez spéic eset, basszus, hol tartottam? Na akkor elölről… stb..
    Na meg persze a későbbi ilyen 1-2 kidobott órák, amikor haladhattam volna, de nem tudtam, nem voltam hajlandó rászánni 10 percet most, hogy tisztábban hagyjam ott a kódot, mint ahogy akkor találtam, mikor hozzá kellett nyúlnom.

  • vaso123: Egyetértek Veled, a legfontosabb (a működő kódon túl), hogy merjük folyamatosan javítani (refaktorálni) a kód minőségét, és ez hamar kifizetődik.

    Persze, arra általában nincs idő, hogy újra megírjuk a szoftvert, tapasztalatom szerint pragmatikusan érdemes hozzáállni a folyamathoz. Én ezek mentén az elvek mentén próbálok dönteni/haladni:

    1) Milyen változás hozná a legnagyobb hatást a szoftverben? (Elsősorban a delivery speed szempontjából, mert a refaktorálás ugyebár azt jelenti, hogy nem változtatom meg a szoftver megfigyelhető működését.)
    2) Hogyan tudom ezt eladni/el tudom-e ezt adni a többi résztvevőnek? (Product ownernek/megrendelőnek, csapattársaimnak, managementnek stb.)
    3) Hogyan tudom ezt lépésről lépésre végrehajtani? (Azon túl, hogy irtó kockázatos a bigbang típusú refaktorálás (napokig/hetekig túrom a kódot, aztán a végén kipottyan a refaktorált kód), nem is lehet azt könnyen eladni, hogy 1 hónapig csak reszelünk, és addig nincs is szállítás.)

    Ahhoz, hogy egyáltalán képesek legyünk refaktorálásra akár nagyobb léptékekben is jó tesztekre van szükség.

    A “jó” számomra a következőket jelenti (végletekig szigorúan értelmezve):

    1. elég gyors: hogy ne kelljen órákat várni, hogy megtudjam, a változtatásaim helyesek-e, (különben nem fogjuk megvárni minden egyes változtatás után a tesztek lefutását, és így több commitra eggyüttesen futnak le majd a tesztek. Ha eltörik a build, nehezen tudjuk meghatározni, hogy milyen változás okozta a hibát, és kinek a felelőssége a javítás. Fennáll a veszélye, hogy nem fog érdekelni, mit mutatnak a tesztek.)
    2. stabil: instabil tesztek állandó ellenőrzése sok energiát visz el, egy idő után már senkinek nem lesz kedve megnézni, miért szállnak el a tesztek,
    3. lehessen bennük bízni: mindenki tudja, hogy pontosan mit várhatunk a tesztektől (minden fejlesztő, tesztelő/PO/PM) – a csapaton belül (és akár kívül is) minden irányból meglegyen a bizalom a szoftverben,
    4. karbantartható: ha nehezen karbantarthatóak a tesztek, akkor nem tudom a kódomat refaktorálni/továbbfejleszteni, mert a tesztek megakadályozzák azt (a rossz tesztkód a produkciós kód és a tesztkód refaktorálhatóságának rovására is megy),
    5. könnyen megérhető: ha nem érthető meg a tesztem, akkor fennáll a veszélye annak, hogy ha eltörik, akkor nem akarja azt senki sem megérteni és megjavítani (ld. @Ignore).

    7 év eltelt a post megírása óta. Most úgy gondolom, a jó (clean) kód ismérve, hogy jó tesztek vannak-e hozzá.

Leave a Comment