From Wikipedia, the free encyclopedia
A kódduplikáció (duplicate code) egy programozási kifejezés azon esetre, mikor a forráskód egyes részei többször (duplikálva) fordulnak elő, akár ugyanabban a programban, akár ugyanazon fejlesztő(csoport) által készített vagy fenntartott, különböző programokban. A kódduplikáció több okból is nemkívánatos.[1]
Ahhoz, hogy egy kódot duplikáltnak – és ne véletlenül hasonlónak – lehessen tekinteni, általában meg kell feleljen bizonyos követelményeknek (például adott kódmennyiség egyezése). A duplikált kódok szekvenciáit néha kódklónoknak vagy egyszerűen klónoknak nevezik, és a kódduplikációk automatikus felderítését klónészlelésnek (clone detection) nevezik.
A kódduplikáció nem feltétlenül jelenti azt, hogy két vagy több kódrészlet karakterenként azonos (beleértve például a változók elnevezését). Olyan részletek is egymás duplikátumainak tekinthetőek, melyek pusztán funkcionálisan azonosak.
Kódduplikációt eredményeztetnek a következők:
Előfordulhat az is, hogy olyan új funkcióra van szükség, amely nagyon hasonló a program egy másik részében létezőtől, így egy fejlesztő egy olyan kódot ír, mely nagyon hasonlít egy más által létrehozott, már meglévő kódrészlethez. A tanulmányok szerint ilyen esetekben az újonnan írt kód általában szintaktikailag nem hasonló.[2]
Egy másik oka lehet a kódduplikációnak az automatikus kódgenerálás, ahol a kódismétlést arra használják, hogy a fejlesztést megkönnyítsék vagy annak sebességét növeljék. A tényleges generátor nem tartalmaz kódismétlést a forráskódjában, csak az általa előállított kimenet ilyen.
A kódismétlést általában úgy javítják, hogy a kérdéses kódrészletet saját egységbe (függvénybe vagy metódusba) helyezik, és ezt az egységet hívják meg az összes olyan helyről, ahol eredetileg használva volt. Segíthet egy nyílt forráskódú fejlesztési stílus használata, amelyben az összetevők központosított helyen vannak.
A duplikált funkcionalitásokat tartalmazó kódot nehezebb fenntartani, mert:
Másrészt, ha a kód egyik példányát különböző célokra használják, és nincs megfelelően dokumentálva, fennáll annak a veszélye, hogy egy adott célját szem előtt tartva frissítik, de ez nem lesz szükséges vagy megfelelő a többi használati célra.
A fenti szempontok nem relevánsak az automatikusan létrehozott kódok esetében, mivel ott a funkcionalitásnak csak egy példánya található a forráskódban.
A régi időkben, amikor kis memóriaterület állt rendelkezésre, a kódismétlés további hátránya volt, hogy szükségtelenül foglalta a memóriát.
Ha egy szoftveres sebezhetőséggel rendelkező kódot másolnak, és a fejlesztő nincs tudatában ennek, a biztonsági rés továbbra is fennállhat a duplikátumban.[3] Egy duplikátum refaktorálása sok szoftvermutatón javíthat, például a kódhossz, ciklomatikus komplexitás és csatolás. Ez rövidebb kompilálási időket, alacsonyabb kognitív terhelést, kevesebb emberi hibát és kevesebb ottfelejtett vagy figyelmen kívül hagyott kódrészletet eredményezhet. Azonban nem minden duplikátumot lehet refaktorálni.[4]
A duplikátumok hatékony megoldások lehetnek, ha a programozási nyelv túl bonyolult vagy alkalmatlan absztrakciókat biztosít, különösen ha a felhasználói felület technikákkal, például szimultán szerkesztéssel támogatja ezeket. Ezenkívül a refaktorálás alatt a kódba programhibák kerülhetnek, és ez a kockázat felülmúlhatja a karbantartási előnyöket.[5] Wagner, Abdulkhaleq és Kaya tanulmánya arra a következtetésre jutott, hogy bár emelkedett munka szükséges a duplikátumok szinkronban tartása érdekében, ezek nem okoznak lényegesen több problémát mint egy duplikátum-mentes kód, feltéve hogy az érintett fejlesztők tisztában vannak velük.[6]
Számos különböző algoritmust javasoltak a duplikált kód felderítésére. Például:
Tekintsük az alábbi kódrészletet egy egészeket tároló tömb átlagának kiszámításához.
extern int tomb1[];
extern int tomb2[];
int osszeg1 = 0;
for (int i = 0; i < 4; i++)
osszeg1 += tomb1[i];
int atlag1 = osszeg1 / 4;
int osszeg2 = 0;
for (int i = 0; i < 4; i++)
osszeg2 += tomb2[i];
int atlag2 = osszeg2 / 4;
A két "for" ciklus átírható egyetlen funkcióvá:
int atlagszamitas(int* tomb)
{
int osszeg = 0;
for (int i = 0; i < 4; i++)
osszeg += tomb[i];
return osszeg / 4;
}
vagy – általában előnyben részesített – a tömbben lévő elemek számának paraméterezésével.
A fenti függvény használatával olyan forráskódot kapunk, amely nem rendelkezik a ciklus ismétlésével:
extern int tomb1[];
extern int tomb2[];
int atlag1 = atlagszamitas(tomb1);
int atlag2 = atlagszamitas(tomb2);
Megjegyzés: Ebben az esetben a fordító dönthet úgy, hogy mindkét hívást beilleszti a függvénybe (inline expansion), és a kapott gépi kód megegyezik a duplikált és nem duplikált esetekben. Ha ez az optimizáció nem történik meg, akkor a függvényhívások költsége miatt a kód valószínűleg lassabb lesz. Elméletileg számíthat a megnőtt futási idő.
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.