Az alul- és túltervezett kód

A mai posztban két jelenségről az under engineering-ről és az over engineering-ről írok. Ha le kell fordítanom őket, akkor az alultervezettség ill. túltervezettség fogalmakat használom. (Ha valaki jobb fordítást tud, szívesen veszem.)

Under engineering

Egy alultervezett kód fő ismérve, hogy igencsak nehezen érhető meg (gány), és ezáltal igen nehézkes a továbbfejlesztése, karbantartása. A gyakorlatban ez igencsak sűrűn előfordul. A fejlesztő nem látja a “big picture”-t, a lokális problémákra fókuszál (rendszerint azokat is rosszul oldja meg), és ezáltal nem képes a kódját rendszerezetten felépíteni.

Teljesen természetes dolog, amikor egy probléma megoldásának elején nem látjuk még, hová vezet az út, és a program belső struktúráit nem megfelelően építjük fel, de ez nem mentség arra, hogy a kód így is maradjon.

Fontosabb az, hogy ahogy haladunk a programmal, éberen őrködjünk a saját és fejlesztőtársaink programkódja felett, és ismerjük fel (vagy el!), ha valami “bűzlik”. Ilyenkor ne sajnáljuk az időt a refaktorálásra, és rakjuk rendbe az érintett kódot. Ha rendben van a kód, könnyebb azt tovább fejleszteni, hibát javítani benne, és ezáltal időt, pénzt és idegességet(!) takarítunk meg.

Ez persze, nem megy könnyen, mert ki akarna belepiszkálni olyan kódba, ami már “működik”. Ennek a helyzetnek a megelőzésére (is) ajánlott alkalmazni a Test Driven Development-et, és a kódunkhoz automatizált teszteseteket írni. (Ennek mikéntjéről majd máskor.) Ha vannak tesztjeink, amik bármikor futtathatóak, akkor magabiztossággal fejlesztünk tovább vagy alakítunk át egy meglévő kódbázist, és nem az jut eszünkbe, hogy “ezt még bottal se piszkálnám”.

Kereshetjük a kifogásokat (Joshua Kerievsky, Refactoring to Patterns):

  • nincs időnk arra, nem szánunk elég időt rá, vagy nem adnak elég időt arra, hogy refaktoráljunk,
  • gyorsan kell új funkciókat fejleszteni a rendszerbe,

…és a végén marad az alultervezett kód.

Over engineering

Egy túltervezett kód a következők miatt alakul ki:

  • ismerek egy tervezési mintát, ami a megoldandó feladatra _a_ “szép megoldás” (legalábbis azt képzelem),
  • általánosan akarom megoldani a feladatot, mert mégiscsak programozó matematikus (vagy … – mindenki egészítse ki magának) vagyok,
  • nem ismerem a pontos üzleti elvárásokat, ezért megcsinálom a programot úgy, hogy majd a későbbiekben is jó legyen.

A túltervezett kód legalább olyan rossz, mint az alultervezett. Bonyolult a program, rengeteg az áttét, és akár olyan szintű absztrakció is jelen lehet a kódban, amely a valósághoz már nem köthető. Az eredmény nem csupán nehezen értelmezhető kód, és a jól “kitalált”, “általános” megoldás még be is szűkíthet minket. Állandóan azt kerülgetjük, szenvedünk, ahelyett, hogy új, üzletileg értékes funkciókkal bővítenénk a szoftverünk tudását.

Míg az alultervezett kód kis részekben, folyamatosan refaktorálható, a túltervezett kód rendszerint magasabb szintekre gyűrűzik fel, és átalakítása az alkalmazás egy nagyobb részét érinti. Ezért a már megírt, túltervezett kódra épülő kódbázist nem könnyű felszámolni…

…és a végén marad a túltervezett kód.

A megoldás: KISS és YAGNI

KISS princípium (Keep It Short and Simple) lényege, hogy mindig annyit csináljunk meg, amennyire szükség van (röviden és egyszerűen), és közben folyamatosan refaktoráljunk. A készülő kód funkcionalitásban konvergál az elvárt felé, és mivel azt folyamatosan karbantartjuk (és nem bonyolotítjuk túl), a lehető legegyszerűbb megoldáshoz juthatunk.

Az ortodox XP-ből (eXtreme Programming) származó YAGNI-elv lényege a túltervezett kód ellen ad útmutatásokat: “Úgysem lesz rá szükséged” – mondja (“You Ain’t Gonna Need it.”). A kísértés, hogy olyan kódot írjunk, amely nem szükségszerű, a következő hátrányokkal jár (Wikipédia):

  • A hasznos funkciók kifejlesztésétől, tesztelésétől és továbbfejlesztésétől vesszük el az időt.
  • Az új funkciókat nyomkövetni, dokumentálni és tesztelni kell.
  • Minden új funkció bizonyos hatással lesz a jövőre, ezáltal egy most kifejlesztett, szükségtelen feature megakadályozhatja egy későbbi szükséges funkció megalkotását.
  • Ameddig nincs szükség egy adott funkcióra, nehéz megmondani, hogy pontosan hogyan is kellene annak működnie. Ha pedig ez fennáll, nem várható el, hogy az helyesen is működjön, még akkor sem, ha egyszer szükség lesz rá.
  • A szoftver egyre nagyobb és bonyolultabb lesz.

Ugyan az elvek pofonegyszerűnek tűnnek, de észre sem vesszük, hogy valójában rengetegszer döntünk velük ellentétesen. Elsajátításuk nem egyszerű, alkalmazásuk önmérsékletre, következetességre int. Figyeljük magunkat és munkánkat! A code review-k is segíthetnek abban, hogy egy bűzlő kódrészletet utólag külső szereplőként is áttekinthessünk, és fejlesztőtársaink visszajelzései is mutatják, ha valami nincs rendjén.

Share
This entry was posted in Programozás and tagged , , , , , , , . Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL.

Comments

Leave a Comment