Skip to content

Kategória: Narancs

Single Level of Abstraction (SLA)

Miért?
Az absztrakciós szint betartása elősegíti a jól olvashatóságot.

Egy kódsor több absztrakciós szinten lehet. Egy változó értékadása alacsonyabb absztrakciós szinten van, mint például egy eljárás meghívása. Hiszen egy eljárás meghívása mögött sokkal több logika lehet, mint egy változó értékadása mögött. Még maguk az eljárás-meghívások is különböző absztrakciós szinteken lehetnek. Egy Framework eljárásának meghívása más szinten van, mint az alkalmazás egy eljárásának meghívása.Ahhoz, hogy a kódot jól lehessen olvasni és megérteni, egy eljárásban csak egy absztrakciós szinten lenne szabad használni. Különben az olvasónak nehezére esik az, hogy szétválassza az esszenciális dolgokat a részletektől. Amennyiben bittologatások szükségesek, akkor ezt nem kellene keverni eljárások meghívásával.

Segíthet az újságcikk analógiája: ott legfelül a legfontosabb dolog a cím áll. Ebből nagy vonalakban ki kellene derüljön, hogy miről fog szólni a cikk. A cikk első mondatában ezt egy magasabb absztrakciós szinten írja le. Minél lejjebb halad az ember a cikkben annál több részlet merül föl. Így strukturálhatjuk a kódunkat is. Az osztály neve a cím. Utána következnek a nyilvános eljárások magas absztrakciós szinten. Ezek lehet, hogy alacsonyabb szintű eljárásokat hívnak meg, míg legvégül a „bittologató eljárások” maradnak. Egy ilyen felosztás mellett mint az osztályok olvasója eldönthetem, hogy milyen részletességi fokozatot szeretnék megtekinteni. Amennyiben csak nagy vonalakban érdekel, hogy hogyan működik az osztály, akkor csak a nyilvános eljárásokat kell megnéznem. Ezekben a funkcionalitást egy magas absztrakciós szinten oldjuk meg. Amennyiben részletesebben érdekel a működés, akkor jobban bele tudok mélyedni és megnézem a privát eljárásokat.

Forrás: Tiszta kód (Clean Code), 36. o. ff.

Single Responsibility Principle (SRP)

Miért?
A fókuszálás megkönnyíti a megértést. Egy olyan osztály, amelynek csak egy feladata van, érthetőbb, mint egy „szatócsbolt”.

A Single Responsibility Principle (SRP) egyike a SOLID-elveknek. Így hangzik: Egy osztálynak csak egy felelőssége kellene hogy legyen.A Single Responsibility Principle hátterében az a meggondolás áll, hogy egy alkalmazás funkcionalitásának bővítése vagy megváltoztatása csak néhány osztályt kellene érintsen. Minél több osztályhoz kell hozzányúlni, annál nagyobb lesz annak a veszélye, hogy a szükséges változtatások miatt problémák lépnek fel más helyeken, melyeknek tulajdonképpen semmi köze sincsen a bővítéshez. A Single Responsibility Principle megsértése csatoláshoz (coupling) vezet, és ezzel emeli a komplexitást, nehezebbé válik a kód megértése.

Separation of Concerns (SoC)

Miért?
Ha egy darab kódnak nincsen egy világosan meghatározott feladata, akkor nehéz lesz megérteni, használni és adott esetben javítani vagy bővíteni.

Ha egy darab kódnak nincsen egy világosan meghatározott feladata, akkor nehéz lesz megérteni, használni és adott esetben javítani vagy bővíteni.
Vonatkozások szétválasztásaként fordítható. Ez az elv azt jelenti, hogy nem szabad több funkcionalitást egy osztályban összefoglalni. Mik azok a vonatkozások? Különböző vonatkozások a „teljesen különböző” célok. Azt is mondják, hogy a vonatkozások egymásra ortogonálisak, és legfőképpen a funkcionalitási egység fő feladatára ortogonálisak. Tipikus példák a különböző vonatkozásokra: Tracing, Logging, tranzakcionalitás, cache-elés. Ezeket a vonatkozásokat a Separation of Concerns-elv alapján specializált funkcionális egységekbe kellene kihelyezni.A Separation of Concerns-elv szorosan összefügg a Single Responsibility-elvvel. Így a felelősségek (responsibility) befoglaló halmaza a vonatkozások (concern). Ideális esetben minden vonatkozás (concern) egy felelősségből (responsibility) áll, mégpedig a főfeladat felelősségéből. Egy felelősségben (responsibility) gyakran több vonatkozás (concern) keveredik. Mivel ez műszakilag gyakran elkerülhetetlen, ezért az elv nem azt mondja ki, hogy a felelősség (responsibility) csak egy vonatkozásból (concern) állhat, hanem hogy a vonatkozásokat el kell különíteni. Egy eljáráson belül például tisztán felismerhetőnek kell lennie, hogy több felelősség (concern) van. Továbbá a vonatkozásokat (concerns) nem szabad vadul szétszórni az eljárásban, hanem úgy kell őket csoportosítani, hogy világos legyen, melyik tartozik egy vonatkozáshoz (concern).

A Domain Driven Design-ban például megpróbáljuk a Business Domain-t szigorúan elkülöníteni az infrastruktúrától. Így ott a Business Domain egy osztálya nem tartalmazhat infrastruktúrát, pl. adatelérést, hanem csak és kizárólag az üzleti logikát képezheti le. A perzisztencia egy „vonatkozás (concern)”, aminek semmi köze az üzleti logikához. A Separation of Concerns laza csatoláshoz (coupling) és erős összetartáshoz (cohesion) vezet. Az egyes komponensek egyenként egy feladatra, egy vonatkozásra (concern) fókuszálnak és ezáltal könnyen megérthetők. Minden rész, amiből a komponens felépül, erre az egy feladatra van kihegyezve, ezáltal a darabok szorosan összefüggnek (erős összetartás (cohesion). A Separation of Concerns továbbá jól tesztelhető komponenseket is eredményez. Mert ha egy kódegység célja fókuszált, akkor kevésbé széles teszteket kell készíteni. A tesztelendő kódegység tekintetében kevesebb tesztparaméter-kombinációt kell ellenőrizni. Amennyiben a vonatkozások szétválasztását konzekvensen használják, akkor az objektumorientáltságot ki kell egészíteni az aspektusorientált programozással (AOP). Ezáltal lehetségessé válik az aspektusok, mint pl. a tranzakcionalitás, tracing és a cache-elés, teljes kiemelése az eljárásokból.

Forráskód konvenciók

Miért?
A kódot gyakrabban olvassák, mint írják. Ezért fontosak a konvenciók, melyek segítik a kód gyors olvasását és felfogását.

A következő aspektusokat tartjuk fontosnak:
  • Névkonvenció
  • Helyes kommentelés

Ezzel nem azt akarjuk mondani, hogy más konvenciók feleslegesek, hanem csak azt, hogy ezzel a kettővel kellene kezdeni, mert ezek annyira alapvetőnek tűnnek. Bármilyen kódkonvencióról legyen szó, a legfontosabb, hogy nem a konkrét kidolgozása a lényeg, hanem a konvenciók konzekvens betartása. És fontos az, hogy tudatos legyen a konvenciók szükségessége.

Névkonvenciók

Miért?
Névkonvenciók nélkül az embernek újra és újra az egyes fejlesztőkre kell ráhangolódnia.

A névkonvencióknak az a feladata, hogy támogassák az olvasót abban, hogy megértse a kódot. Mivel pl. hasznos lehet a helyi változók megkülönböztetése a mezőktől, ezért ezt lehetne támogatni egy névkonvencióval. Hogy egy ilyen konvenció az adott esetben hogyan néz ki, az már ízlés kérdése. Egyesek a „this.xyz”-t szeretik, mások a „_xyz”-t. Hogy melyik változatot használjuk az nem fontos. Nekünk csak az fontos, hogy a konvenciókat konzekvensen betartsák. Továbbá a mezők névkonvenciójának szükségessége a kontextustól függ. Egy 400 soros osztályban nagyon fontosnak tartanánk egy olyan névkonvenciót, amelyik megkülönbözteti a változókat és a mezőket, míg átlátható osztályokban ez inkább a háttérbe szorul. A Root Cause Analysis segítségével a Clean Code fejlesztők a névkonvenciók szükségességének okát kutatják.

Helyes kommentelés

Miért?
A felesleges vagy hibás kommentek feltartják az olvasót. A kódnak olyan tisztának és érhetőnek kellene lennie, hogy megálljon kommentek nélkül.

Pongyola fogalmazásban: Egy komment a kódban annak a jele, hogy még lehet javítani a kódon. Ennek tipikus esete, amikor 3 sor kód fölött egy komment helyezkedik el. Ebben az esetben valószínűleg segíthet az, hogy kiemeljük a három sort egy eljárásba (Refactoring: Extract Method), és a kommentet az eljárás neveként használjuk. Általánosan a kommentek szükségességét azzal lehet csökkenteni, hogy a változóknak, eljárásoknak, osztályoknak stb. jó nevet adunk.

A következő helyett

    int hossz; // mm-ben

jobb volna:

    int hosszMmBen;

A következő helyett:

    public double Ár() {
        // kiszámolja a bruttó árat...
    }

jobb volna:

    public Money BruttoÁr() {
        ...
    }

Nem azt kellene kommentelni, amit az ember tesz, hanem sokkal inkább azt, hogy miért tette ezt.

Issue Tracking

Miért?
Csak azt nem felejti el az ember, amit felír, és csak azt fogja tudni hatékonyan delegálni és nyomon követni.

Minden „issue” strukturált menedzselése már csak azért is szükséges, hogy semmi ne tűnjön el. Csak akkor lehet a pontokat priorizálni illetve sorrendbe rakni, ha van lehetőség a pontok áttekintésére. Ehhez nincsen feltétlen szükség kifinomult eszközökre, egy tábla papír cetlikkel is megteszi. És legfőképpen nem az eszköznek kellene itt az előtérben lennie, hanem magának a tevékenységnek.

Lásd az eszközök alatt.

Automatizált integrációs tesztek

Miért?
Az integrációs tesztek gondoskodnak arról, hogy a kód azt tegye, amit tennie kell. Ezt a rendszeres tevékenységet nem automatizálni időpocsékolás volna.

A legalapvetőbb feltételét a kód megváltoztatásának már a piros fokozaton lefektettük a verziókövető rendszer használatával. Aggodalom nélkül változtathatunk a kódon, egész fájlokat vagy könyvárakat törölhetünk le, a verziókövető rendszerből mindezt újra ki lehet venni.Amikor csak változtatásokat eszközölünk a kódon, mindig biztosnak kell lennünk abban, hogy semmit sem rontottunk el. És erre a biztonságra csak akkor tehetünk szert, ha a változtatások után teszteljük, hogy az alkalmazás úgy viselkedik-e, mint előtte. Ezeket a teszteket minden változtatás után kézzel végrehajtani nem volna megoldható, automatizálnunk kell azt. A szoftverfejlesztés egyik nagy baja a félelem attól, hogy valami fölött elsiklik a figyelmünk, hogy egy részletre nem terjed ki a figyelmünk, és ezáltal hibát okozunk olyan kódban, ami előzőleg működött. És ennél még az sem játszik szerepet, hogy a változtatások ahhoz vezetnek-e hogy javítjuk a kódot (refaktorálunk) vagy új követelményeknek megfelelően bővítettük azt. Addig amíg nem vagyunk biztosak benne, hogy a minden úgy működik, ahogyan előtte, addig marad a félelem. Ez ahhoz vezet, hogy kétség esetén a kódot úgy hagyjuk, ahogyan van, hiszen az működik. A szükséges refaktorálásokat elmulasztják a hibázás miatti félelemből.

Ahhoz, hogy a már futó projektekben (un. Brownfield projetekeben, ellentétben a Greenfield „zöldmezős”) meg tudjuk teremteni a biztonsági hálót, olyan eljárásokra van szükség, amiket a meglévő kódra lehet alkalmazni. Ehhez alkalmasak az automatizált integrációs tesztek. Vagy a felhasználói felületen kezdjük ezt el, és végig tesztelünk az alkalmazást összes rétegen keresztül, vagy lejjebb kezdjük el. Mindkét esetben több funkcionális egység összjátékát teszteljük.

Tehát mielőtt változtatásokat eszközölnénk a kódon, az érintett kódterületek lefedésére integrációs teszteket hozunk létre. Persze ebben a folyamatban használhatunk olyan eszközöket, mint a WatiN, UI Automation stb. Kívánatosak volnának persze a unit tesztek is, amelyek az egyes funkcionális egységeket elszigetelten tesztelik. Ehhez azonban a kódnak bizonyos feltételeknek kell megfelelnie, melyek vélhetően nem mindig adottak: a kódnak tekintettel kell lennie a Single Responsibility-elvre. Ellenkező esetben az egyes funkcionális egységek (komponensek, osztályok, eljárások) között olyan nagyok lesznek a függőségek, hogy nem lehet őket elszigetelten tesztelni. A távlati cél természetesen egy olyan kódbázis, amelyen lehetségesek a unit tesztek. Sőt, a jövőben a teszteket az implementálás előtt fogjuk létrehozni (Test first). De ahhoz, hogy a refaktorálással odáig el tudjunk jutni, először integrációs tesztekre van szükség, hogy biztosra mehessünk, az alkalmazás még mindig úgy viselkedik, mint a refaktorálás előtt.

Lásd az Eszközök alatt.

Olvasni, olvasni, olvasni

Miért?
A olvasás műveltté tesz!

Az olvasás műveltté tesz – mi meg vagyunk győződve arról, hogy ez szoftverfejlesztőkre is igaz. A szoftverfejlesztés továbbra is fejlődik. A nagy fejlődési lépések mellett, mint a procedurális programozás, objektumorientált programozás, funkcionális programozás, aspektusorientált programozás stb. folyamatosan vannak előrelépések kisebb területeken, amivel a szoftverfejlesztőknek foglalkozniuk kell. Vannak például technikák, mint a Dependency Injection vagy a Object Relational Mapper. De ezekben a technikákban is vannak fejlődési lépések, mint például a Domain Specific Languages (DSLs) a konfigurálás az XML alapú konfigurálással szemben. A szoftverfejlesztés technikai aspektusain kívül a folyamatot is fejlesztik. Így általánossá vált az a felismerés, hogy a vízesésmodell nem működik, és különböző agilis módszereket fejlesztettek ki. Mindezt a Clean Code fejlesztőnek szem előtt kell tartania.

Ezért azt javasoljuk, hogy évente legalább 6 szakkönyvet olvassunk el. Továbbá rendszeresen kellene periodikákat olvasni, ami alatt szakmai folyóiratokat és blogokat is értünk.

Javaslatokat az irodalomjegyzékben találhatunk.

Review-k

Miért?
Négy szem többet lát, mint kettő. Amikor egy fejlesztő elmagyarázza a kódját egy másik fejlesztőnek, akkor általában olyan részletek merülnek fel, amelyekre eddig nem fordított figyelmet.

A review-k ezért kétféle formában fordulnak elő: mint folyamatos páros programozás (pair programing) és mint önálló folyamatelem a code review. A cél mindkét esetben ugyanaz: a kódot véleményezze egy másik fejlesztő is. Ezzel el lehet kerülni az „üzemi rövidlátást”. Már az a tény, hogy egy fejlesztő a kódját bemutatja és a másiknak és elmagyarázza azt, már ez is aha élményekhez vezet.Általában más fejlesztőkkel való beszélgetések során derül ki egy kódbázisról, hogy hol találhatók az erősségei és gyengeségei. Éppen a folyamatos javítások folyamata követeli meg, hogy más fejlesztők meglátásaival szembesüljünk és azokat megvitassuk.

Természetesen nem csak a forráskód alkalmas review-k alapjául. Ezek kedvező lehetőséget teremtenek arra, hogy minden fejlesztési tevékenység eredményét megvizsgáljuk, amennyiben ezek írásos formában rögzítésre kerülnek. A teljesen informális review-k, mint a páros programozás (pair programing) vagy a második személy általi véleményezés mellet van a formális review egy review eljárással és a megfelelő szerepekkel. További ismert fajtái a review-nak a Walkthrough, technikai review, peer review és az inspekció.

A review-k kiegészítik a dinamikus teszteket, mint az automatizált unit teszteket és az automatizált integrációs teszteket a sárga fokozatból ill. a narancs fokozatból. Ezekkel a tesztekkel szemben a review-k nagyon is alkalmasak arra, hogy hibákat fedezzünk fel a követelmények között. Ha a fejlesztési folyamatban idejekorán szerepelnek, akkor nagyon korán fel lehet ismerni az ilyen hibákat. És minél korábban találunk meg hibákat, annál költségkímélőbb a kijavításuk.