Kódduplikáció

(Ismétlődő kód szócikkből átirányítva)

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.

Felbukkanása szerkesztés

Kódduplikációt eredményeztetnek a következők:

  • Másol-beillesztéses programozás (copy-paste), amely akadémiai körülmények között plagizálásnak is tekinthető
  • Kódlopás (scrounging), amikor egy kódrészletet azért másolnak be, „mert működik”. Sok esetben ez a művelet a klónozott kód enyhe módosítását vonja maga után, mint például a változók átnevezése vagy részletek beillesztése, törlése. A programozási nyelv szinte mindig lehetővé teszi, hogy a kód egy példányát különböző helyekről hívják meg, de ehelyett a programozó létrehoz egy duplikátumot, valószínűleg mert:
    • nem ismeri megfelelően a nyelvet
    • nincs ideje tisztességesen megcsinálni
    • nem érdekli a megnövekedett szoftverrothadás

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.

Javítása szerkesztés

 
Az ismétlődő kód javításának legjobb példája a kód függvénybe ágyazása

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.

Hátrányok és esetleges előnyök szerkesztés

A duplikált funkcionalitásokat tartalmazó kódot nehezebb fenntartani, mert:

  • hosszabb
  • ha frissítésre szorul, fennáll annak a veszélye, hogy a kód egyik helyen frissül, a többieken pedig nem

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] 

Klónészlelés szerkesztés

Számos különböző algoritmust javasoltak a duplikált kód felderítésére. Például:

  • Baker algoritmusa[7]
  • Rabin–Karp karakterlánc-kereső algoritmus
  • Absztrakt szintaxisfák használata[8]
  • Vizuális klónészlelés[9]
  • Count Matrix Clone Detection[10][11]
  • Helyfüggő hash
  • Anti-unifikáció[12]

Példa funkcionalitást ismétlő kódra szerkesztés

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ő.

Jegyzetek szerkesztés

  1. Spinellis, Diomidis: The Bad Code Spotter's Guide. InformIT.com. (Hozzáférés: 2008. június 6.)
  2. Code similarities beyond copy & paste by Elmar Juergens, Florian Deissenboeck, Benjamin Hummel.
  3. Li (2016. április 25.). „CLORIFI: software vulnerability discovery using code clone verification”. Concurrency and Computation: Practice and Experience 28 (6), 1900–1917. o. DOI:10.1002/cpe.3532.  
  4. Arcelli Fontana (2013. március 28.). „Software Clone Detection and Refactoring”. ISRN Software Engineering 2013, 1–8. o. DOI:10.1155/2013/129437.  
  5. Kapser, C.; Godfrey, M.W., ""Cloning Considered Harmful" Considered Harmful," 13th Working Conference on Reverse Engineering (WCRE), pp. 19-28, Oct. 2006
  6. Wagner (2016. március 28.). „On the relationship of inconsistent software clones and faults: an empirical study”. Proc. 23rd IEEE International Conference on Software Analysis, Evolution, and Reengineering (SANER 2016), 79–89. o. DOI:10.1109/SANER.2016.94.  
  7. Brenda S. Baker. A Program for Identifying Duplicated Code. Computing Science and Statistics, 24:49–57, 1992.
  8. Ira D. Baxter, et al. Clone Detection Using Abstract Syntax Trees
  9. Visual Detection of Duplicated Code by Matthias Rieger, Stephane Ducasse.
  10. Yuan, Y. and Guo, Y. CMCD: Count Matrix Based Code Clone Detection, in 2011 18th Asia-Pacific Software Engineering Conference. IEEE, Dec. 2011, pp. 250–257.
  11. Chen, X., Wang, A. Y., & Tempero, E. D. (2014). A Replication and Reproduction of Code Clone Detection Studies. In ACSC (pp. 105-114).
  12. Bulychev, Peter, and Marius Minea. "Duplicate code detection using anti-unification." Proceedings of the Spring/Summer Young Researchers’ Colloquium on Software Engineering. No. 2. Федеральное государственное бюджетное учреждение науки Институт системного программирования Российской академии наук, 2008.

Fordítás szerkesztés

Ez a szócikk részben vagy egészben a Duplicate code című angol Wikipédia-szócikk ezen változatának fordításán alapul. Az eredeti cikk szerkesztőit annak laptörténete sorolja fel. Ez a jelzés csupán a megfogalmazás eredetét és a szerzői jogokat jelzi, nem szolgál a cikkben szereplő információk forrásmegjelöléseként.

További információk szerkesztés

Kapcsolódó szócikkek szerkesztés