A számítógép-programozásban kódszagnak nevezzük a forráskódnak azokat a jellemzőit, melyek egy mélyebb problémára utalhatnak. Maga a probléma nem biztos, hogy programhibaként nyilvánul meg: jól működő, a specifikációnak mindenben megfelelő programkódok is tartalmazhatnak egyszerre akár több kódszagot is. Azonban ha egy kód teli van kódszagokkal, és találnak egy hibát, akkor a kódszagok miatt nehezebb megkeresni a kódban, és nehezebb kijavítani. Ha új követelmények jelennek meg, akkor azokat nehezebb bevezetni, és nagyobb annak a valószínűsége, hogy újabb hibákat vezessenek be a kódba.

A kódszagok olyan kódstruktúrák, amelyek rontják a kód minőségét. Alapvető programfejlesztési elveket sértenek meg. Lelassíthatják a fejlesztést, növelhetik a bugok és a hibák előfordulását a kódban. Szubjektív eldönteni, hogy mi számít kódszagnak: a paradigmán túl függhet a fejlesztési metodológiától, a programozási nyelvtől, sőt, a fejlesztőtől is.

Az elnevezést angolul (code smell) Kent Beck terjesztette a Wardswikin az 1990-es években. Martin Fowler Refractoring című könyve 1999-ben jelent meg, és elsőként használta könyvben az elnevezést. Az agilis fejlesztésben is elkezdték használni ezt a kifejezést.

Robert C. Martin szerint a kódszagok listájának értékelési rendszernek kell lennie a szoftverfejlesztésben. Cunningham definíciója szerint a kódszag arra utal, hogy valami elromolhatott, de nem bizonyítja, hogy valóban el is romlott.

A kódszag által jelzett mélyebb probléma feltárható, ha a kódra rövid visszacsatolású ciklust végzünk. A ciklusban két lépés váltakozik: kódszagok felderítése, kódszagok javítása. Maga a javítás is bevezethet újabb kódszagokat, különösen, ha az elemzés nem volt elég mély, vagy a javítást figyelmetlenül végezzük. Lehet, hogy az újabb vizsgálat során olyan kódszagokra bukkanunk, melyeket elsőre nem vettünk észre. A refraktorálást végző fejlesztő szempontjából a kódszagok heurisztikák arra, hogy refraktorálásra van szükség, így a kódszagok refraktorálási igényt jelentenek. A kódszagok mennyisége becsülhető azzal, hogy mennyire érthető a kód, mennyire módosítható, bővíthető, milyen könnyű tesztelni, mennyire megbízhatóan működik és mennyire alkalmas újrafelhasználásra.

Kódszagokat kézzel is lehet keresni, de vannak hozzá automata eszközök is. Ezek közé tartozik a Checkstyle, a PMD, a FindBugs és a SonarQube.

2015-ben statisztikai elemzést végeztek automata eszközökkel félmillió kódsoron. Kézzel átvizsgáltak 9164 commitot. Az elemzés szerint: tapasztalati bizonyítékok léteznek a technikai adósság következményeire, de csak anekdotikus bizonyítékok vannak a miért, hogyan és mikor kérdések megválaszolására az általános vélekedés szerint az ilyen kódszagok gyakran a sürgős karbantartási feladatoknak, valamint annak a nyomásnak tudhatók be, hogy a funkciókat minél hamarabb bevezessék, miközben a piacra lépés gyorsaságát a kód minősége elé helyezik.

Csoportosításuk Különböző szerzők különbözőképpen csoportosítják a kódszagokat. Az egyik csoportosítás a szintek szerinti: Alkalmazás szint: Duplikált kód: ugyanaz a kód, vagy több hasonló kód több helyen is előfordul az alkalmazásban. Ide számítanak azok az esetek is, amikor maga a kód különböző, mégis ugyanazt csinálja. Sörétespuska-sebészet: egyetlen változtatás miatt több más osztályban is változtatni kell. Osztály szint: Nagy osztály: egy osztály túl sok felelősséggel. Túl sok típust vagy össze nem tartozó metódust tartalmaz. Akár isten osztállyá is fejlődhet. Visszautasított örökség: a gyermek osztálynak nincs szüksége a szülő osztály összes metódusára, ezért letiltja, vagy úgy írja felül, hogy nem teljesíti annak szerződéseit. Ez megszegi a Liskov helyettesítési elvet. Varázsszámok, a szövegbe kódolt literálok: a varázsszám egy ismeretlen funkciójú, adott szám, például egy valahonnan felbukkanó 52 lehet a év heteinek száma vagy a francia kártya paklijának a mérete. A szövegbe kódolt literál egy több helyen felbukkanó, mindenütt egyforma szövegű string. Ha meg kell változtatni, akkor lehet, hogy mindenütt ugyanúgy kell átírni, ehhez meg kell találni minden előfordulását. A beégetett literálok nem teszik lehetővé a nyelvesítést sem. Jobb helyük van egy külső fájlban vagy adatbázisban. Szülő osztály konverziója utód osztályra, ami fölösleges absztrakciót jelez. Adatlabda: változók egy csoportja együtt mozog az alkalmazás különböző részein. Metódus szint: Hosszú paraméterlista: Még ha nem is hosszú a metódus, a sok paraméter miatt nehezebb megérteni, hogy melyiknek mi a szerepe.

Egy másik csoportosítás az okozott nehézségek alapján veszi őket számba: (Refractoring Guru) Felfújók: Hatalmasra növő kódszakaszok, metódusok, osztályok, amelyek túl nagyok ahhoz, hogy könnyen lehessen őket használni. Ezek a kódszagok nem egyszerre keletkeznek, hanem együtt nőnek az alkalmazással. Erre az a megoldás, hogy értelmes részekre kell őket felosztani. Hosszú metódus Nagy osztály: egy osztály, aminek egynél több felelősséget kell ellátnia Primitívmánia: primitívekkel próbálnak meg leírni olyan adatokat, melyet osztállyal célszerűbb lenne Hosszú paraméterlista Adatlabda Visszaélés az objektumorientációval: Úgy teszünk, mintha objektumorientált programot írnánk, de valójában nem ezt tesszük, egy természetszerűleg objektumorientált nyelvben és környezetben. Alternatív osztályok különböző interfészekkel Visszautasított örökség Switch utasítások, polimorfizmus használata helyett Ideiglenes mező: az idő legnagyobb részében üres, sok találgatásra okot adó mező Változásakadályok: megnehezítik a program bármilyen változtatását Divergens változás: ha megváltoztatsz egy metódust, akkor ugyanannak az osztálynak több látszólag független metódusát is meg kell változtatni Sörétespuska-sebészet Párhuzamos öröklési hierarchiák: Ha egy hierarchiát bővítesz, akkor mágikusnak látszó okokból egy másik hierarchiát is bővítened kell Nélkülözhetők: Jelen vannak a programban, de ha nem lennének, akkor nem hiányoznának. Egy érthetőbb, tisztább, hatékonyabb programot kapnánk. Kommentdömping: a kommenteknek azt kell elmagyarázniuk, mi mire való, nem azt, hogy mi mit csinál. Duplikált kód. Lásd még: DRY (programtervezési minta) Adat osztály: adatrekord, a hozzá tartozó metódusok nélkül. Csak getterei és setterei vannak. Holt kód: kódszakasz, aminek eredményét sehol sem használja a program. Lusta osztály: egy figyelmet alig érdemlő, alig használt osztály. Spekulatív általánosság: jövőbeli tervek számára előkészített kódrészletek, metódusok, osztályok, modulok. A YAGNI elvének megsértése. Duplikátorok: Ugyan nem ismételnek kódrészletet, de bonyolultabbá teszik a kommunikációt a programon belül. Képességirigység: egy metódus inkább egy másik osztállyal foglalkozik, mint amiben benne van. Helytelen intimitás vagy bennfentes kereskedelem: egy metódus egy másik osztály privát metódusait hívogatja vagy privát mezőit manipulálja. Az egységbe zárás megsértése. Inkomplett könyvtárosztály: egy programkönyvtár már képtelen kielégíteni az alkalmazás igényeit. Üzenetlánc: egy objektumnak egy tőle távol levő objektum információira van szüksége, amit közvetítők láncolatán keresztül szerez be. Közbülső ember: egy objektum csak delegációval foglalkozik.

Fordítás

Hivatkozások

Források

Boundy, David, Software cancer: the seven early warning signs or here, ACM SIGSOFT Software Engineering Notes, Vol. 18 No. 2 (April 1993), Association for Computing Machinery, New York, NY, USA Refractoring Guru

Kategória:Programozási antiminták