[gesichtete Version][gesichtete Version]
Inhalt gelöscht Inhalt hinzugefügt
+BKL und weiteres synonym
K typografische Anführungszeichen, Links optimiert
 
(31 dazwischenliegende Versionen von 21 Benutzern werden nicht angezeigt)
Zeile 1:
Bei '''Quelltextklonen''' (auch '''Codeduplikate''', '''Softwareklonen''' oder einfach nur '''Klonen''') handelt es sich um ähnliche Abschnitte im [[Quelltext]] eines [[Computerprogramm]]s. Solche Klone sind eine Form von [[redundanter Code|redundantem Code]] und entstehen vorwiegend durch [[Kopieren und Einfügen]]. Da sie negative Auswirkungen auf die [[Softwarewartung|Wartung]] haben, sind Klone ein starker Indikator für mangelnde [[Softwarequalität|Qualität]].
{{Dieser Artikel|beschreibt Quelltextklone in der Softwaretechnik – für weitere Bedeutungen siehe ''[[Klon]]'' oder ''[[Klon (Informationstechnik)]]''}}
Bei '''Quelltextklonen''' (auch '''Codeduplikate''', '''Softwareklonen''' oder einfach nur '''Klonen''') handelt es sich um ähnliche Abschnitte im [[Quelltext]] eines Programms. Klone sind eine Form von [[Redundanz]] und entstehen vorwiegend durch [[Copy&paste]]. Da sie negative Auswirkungen auf die [[Softwarewartung|Wartung]] haben sind Klone ein starker Indikator für mangelnde [[Softwarequalität|Qualität]].
 
== Ähnlichkeit ==
Bei Klonen handelt es sich im Allgemeinen um ähnliche Quelltextabschnitte. Damit ist die Definition der Ähnlichkeit ein zentraler Punkt, der auch in der Forschung noch intensiv diskutiert wird. Es herrscht allerdings Übereinstimmung darüber, dass es keine universell einsetzbare Definition gibt, sondern sich diese immer nach dem konkreten Anwendungsfall richtet. Bei der Definition der Ähnlichkeit sind unter anderem die folgenden Aspekte zu berücksichtigen:
 
; Mindestlänge
* '''Mindestlänge''': Das sich jedes Programm aus den [[Token (Übersetzerbau)|atomaren Elementen]] (Schlüsselwörter, Operatoren, Bezeichner, ...) der jeweiligen Programmiersprache zusammensetzt, besteht auf dieser Ebene immer Ähnlichkeit zwischen verschiedenen Codefragmenten. Allerdings gibt es auf dieser Ebene selten sinnvolle Abstraktionsmöglichkeiten und diese atomaren Elemente schon als Klone anzusehen ist selten hilfreich. Daher gehört zur Definition der Ähnlichkeit die Festlegung einer Mindestlänge die angibt wie lang Codeabschnitte mindestens sein müssen damit sie als Klone angesehen werden. In welcher Einheit diese Mindestlänge angegeben wird richtet sich nach dem Erkennungsverfahren. Beispiele für Mindestlängen sind Werte wie 10 Zeilen, 100 Tokens, 7 Anweisungen, usw.
: Da sich jedes Programm aus den [[Token (Übersetzerbau)|atomaren Elementen]] (z. B. Schlüsselwörter, Operatoren, Bezeichner, …) der jeweiligen Programmiersprache zusammensetzt, besteht auf dieser Ebene immer Ähnlichkeit zwischen verschiedenen Codefragmenten. Allerdings gibt es auf dieser Ebene selten sinnvolle Abstraktionsmöglichkeiten und diese atomaren Elemente schon als Klone anzusehen ist selten hilfreich. Daher gehört zur Definition der Ähnlichkeit die Festlegung einer Mindestlänge, die angibt wie lang Codeabschnitte mindestens sein müssen, damit sie als Klone angesehen werden. In welcher Einheit diese Mindestlänge angegeben wird, richtet sich nach dem Erkennungsverfahren. Beispiele für Mindestlängen sind Werte wie 10 Zeilen, 100 Tokens, 7 Anweisungen usw.
 
; Normalisierung
* '''Normalisierung''': Neben der Mindestlänge hat es sich bewährt den Code hinsichtlich der Definition von Ähnlichkeit zu normalisieren. So werden in vielen Fällen [[Kommentar (Programmierung)|Kommentare]] im Code in Bezug auf Klone ignoriert. Eine weitere oftmals angewandte Normalisierung ist die Abstraktion von [[Bezeichner|Bezeichnern]], d.h. zwei [[Schleife (Programmierung)|Schleifen]] werden als Klone angesehen auch wenn in der einen i und in der anderen j als Schleifenvariable verwendet wird. In ähnlicher Weise können [[Literal|Literale]] normalisiert werden. Komplexere Normalisierung könnten zum Beispiel darin bestehen bei [[Kommutativgesetz|kommutativen]] Operationen die Reihenfolge der Operanden eindeutig zu machen oder bei Schleifenkonstrukten von der Art der Schleife zu abstrahieren. Welche Normalisierung sinnvoll ist richtet sich im Allgemeinen stark nach dem Anwendungsfall. Da die Normalisierung aber einen sehr großes Einfluss auf die Ergebnisse hat sollte diese gewissenhaft vorgenommen werden. Hierfür ist nicht zuletzt eine gewisse Erfahrung im Bereich der Klonerkennung erforderlich.
: Neben der Mindestlänge hat es sich bewährt, den Code hinsichtlich der Definition von Ähnlichkeit zu normalisieren. So werden in vielen Fällen [[Leerraum|Leerräume]], [[Einrückungsstil]] und [[Kommentar (Programmierung)|Kommentare]] im Code in Bezug auf Klone ignoriert. Eine weitere oftmals angewandte Normalisierung ist die Abstraktion von [[Bezeichner]]n, d. h. zwei [[Schleife (Programmierung)|Schleifen]] werden als Klone angesehen, auch wenn in der einen ''i'' und in der anderen ''j'' als Schleifenvariable verwendet wird. In ähnlicher Weise können [[Literal]]e normalisiert werden. Komplexere Normalisierung könnte zum Beispiel darin bestehen, bei [[Kommutativgesetz|kommutativen]] Operationen die Reihenfolge der Operanden eindeutig zu machen oder bei Schleifenkonstrukten von der Art der Schleife zu abstrahieren. Welche Normalisierung sinnvoll ist, richtet sich im Allgemeinen stark nach dem Anwendungsfall. Da die Normalisierung aber einen sehr großen Einfluss auf die Ergebnisse hat, sollte diese gewissenhaft vorgenommen werden. Hierfür ist nicht zuletzt eine gewisse Erfahrung im Bereich der Klonerkennung erforderlich.
 
; Ungleiche Abschnitte („Gaps“)
* '''Ungleiche Abschnitte („Gaps“)''': Auch wenn man mit der Normalisierung die Definition der Ähnlichkeit schon sehr weit fassen kann ist weiterhin zu überlegen ob Klone darüber hinaus kleinere ungleiche Abschnitte ("Gaps") beinhalten dürfen. Der Vorteil ist, dass mehrere kleine Klone dadurch zu größeren Klonen verschmelzen, was die Redundanz auf höherer Ebene sichtbar macht. Die Gaps weisen zudem auf Unterschiede hin die möglicherweise unbeabsichtigt sind. Allerdings wird die Erkennung von Klonen mit Gaps nicht von allen Werkzeugen unterstützt. Zudem muss festgelegt werden wie viele Gaps ein Klon enthalten darf.
: Auch wenn man mit der Normalisierung die Definition der Ähnlichkeit schon sehr weit fassen kann, ist weiterhin zu überlegen, ob Klone darüber hinaus kleinere ungleiche Abschnitte („Gaps“) beinhalten dürfen. Der Vorteil ist, dass mehrere kleine Klone dadurch zu größeren Klonen verschmelzen, was die Redundanz auf höherer Ebene sichtbar macht. Die Gaps weisen zudem auf Unterschiede hin, die möglicherweise unbeabsichtigt sind. Allerdings wird die Erkennung von Klonen mit Gaps nicht von allen Werkzeugen unterstützt. Zudem muss festgelegt werden, wie viele Gaps ein Klon enthalten darf.
 
=== Abgrenzung zu redundanten Literalen ===
Klone definieren sich darüber, dass Quelltextabschnitte einer gewissen Größe zueinander ähnlich sind. Aus diesem Grund spricht man bei einzelnen duplizierten Tokens üblicherweise nicht von Klonen. Dies betrifft vorwiegend redundante Literale im Quelltext, die besser als symbolische Konstante repräsentiert werden sollten (z.B.zum Beispiel alle Vorkommen des Literals ''3.14159'' durch eine [[Konstante (Programmierung)|Konstante]] mit dem [[Bezeichner]] ''PI''). Um die Wiederholung von Ausdrücken in den Quelltexten zu vermeiden, sollten also schon aus Gründen der Wartbarkeit und der effizienteren Fehlersuche kategorisch symbolische Konstanten verwendet werden.<ref>Markus Bautsch: ''[[b:Strukturierte Programmierung#Symbolische Konstanten|Codewiederholung – Symbolische Konstanten]]''. In: ''Strukturierte Programmierung''. [[Wikibook]]</ref>
 
== Begriffe ==
Es existierenexistiert eine Reihe von Begriffen, die sich mit der Zeit im Bereich der Softwareklone etabliert haben.
 
; Klon
: Ein Quelltextabschnitt der zu mindestens einem anderen Quelltextabschnitt ähnlich ist. Alternativ wird auch der Begriff ''Fragment'' verwendet. Die Ähnlichkeit wird entweder durch ein ''Klonpaar'' oder eine ''Klonklasse'' repräsentiert.
; Typ-1 -Klone
: Identische Quelltextabschnitte bis auf Layout und Kommentare.
: {|
:{| class="centered"
|+ '''Typ-1 -Klonpaar'''
|-
|
|<syntaxhighlight lang="java" highlight="1">
<syntaxhighlight lang="java" highlight="1">
int a = 0;
int b = a * a;
String str = "Peter";
</syntaxhighlight>
|
|<syntaxhighlight lang="java" highlight="1">
<syntaxhighlight lang="java" highlight="1">
int a = 0; // Comment
int b = a * a;
Zeile 35 ⟶ 37:
</syntaxhighlight>
|}
; Typ-2 -Klone
: Typ-1 -Klone, bei denen zusätzlich Unterschiede in den Bezeichnern oder Literalen existieren.
: {|
:{| class="centered"
|+ '''Typ-2 -Klonpaar'''
|-
|
|<syntaxhighlight lang="java" highlight="1-2">
<syntaxhighlight lang="java" highlight="1-2">
int a = 0;
int b = a * a;
String str = "Peter";
</syntaxhighlight>
|
|<syntaxhighlight lang="java" highlight="1-2">
<syntaxhighlight lang="java" highlight="1-2">
int a = 0; // Comment
int x = a * a;
Zeile 51 ⟶ 55:
</syntaxhighlight>
|}
; Typ-3 -Klone
: Typ-2 -Klone, die ungleiche Abschnitte (Gaps) enthalten. Insbesondere in der englischsprachigen Literatur wird auch der Begriff ''Near-Miss Clone'' verwendet.
: {|
:{| class="centered"
|+ '''Typ-3 -Klonpaar'''
|-
|
|<syntaxhighlight lang="java" highlight="1-2">
<syntaxhighlight lang="java" highlight="1-2">
int a = 0;
int b = a * a;
Zeile 62 ⟶ 67:
String str = "Peter";
</syntaxhighlight>
|
|<syntaxhighlight lang="java" highlight="1-3">
<syntaxhighlight lang="java" highlight="1-3">
int a = 0; // Comment
int x = a * a;
Zeile 69 ⟶ 75:
</syntaxhighlight>
|}
; Typ-4 -Klone
: Klone, die [[Semantik|semantisch]] ähnlich, aber nicht zwingend [[Syntax|syntaktisch]] ähnlich sind. Die syntaktische Ähnlichkeit liegt typischerweise unter 16 % und andere Unterschiede liegen in den genutzten Algorithmen, Datenstrukturen, benutzten Bibliotheken, Ein-/Ausgabebehandlung und dem objektorientierten Design.<ref>Stefan Wagner, Asim Abdulkhaleq, Ivan Bogicevic, Jan-Peter Ostberg, Jasmin Ramandani. [https://peerj.com/preprints/1516/?td=wk How are functionally similar code clones different?]. PeerJ Preprints, 2015.</ref> Aufgrund der Unmöglichkeit der Bestimmung von semantischer Ähnlichkeit hat dieser Klontyp wenig praktischen Nutzen.
; Klonpaar
: Ein Klonpaar repräsentiert die Relation zwischen exakt zwei ähnlichen Quelltextabschnitten (Klonen).
; Klonklasse
: Eine Klonklasse repräsentiert die Relation zwischen zwei oder mehr ähnlichen Quelltextabschnitten (Klonen).
; Klonüberdeckung
: Der Anteil des Systems der Teil eines Klons ist. Wird häufig verwendet, um das Ausmaß der Redundanz in einem System zu quantifizieren.
 
== Gründe ==
Klone erstehenentstehen fast ausschließlich durch Copy„copy-&Paste-Programmierungpaste-Programmierung“. Für das Entstehen von Klonen gibt es eine Reihe von Gründen, die sich in die folgenden Kategorien einteilen lassen: <ref name="Roy-2007-TR" />
 
* '''Entwicklungsstrategie''': Bestehende Funktionalität wird als Vorlage für neu zu erstellende Funktionalität verwendet. Dabei wird der bereits existierende Code kopiert und nach Bedarf angepasst. Hierzu zählen auch Situationen in denen Code dupliziert wird um Änderungen zu erproben ohne die Funktion des Systems zu gefährden (Branching).
 
* '''Vorteile bei der Wartung''': Durch die Wiederverwendung von existierendem Code soll die zukünftige Wartung erleichtert werden. So wird zum Beispiel bewährter Code wiederverwendet um das Risiko neuer Fehler zu minimieren. Außerdem können durch das Kopieren von Code unerwünschte Abhängigkeiten zwischen Komponenten vermieden und eine getrennte Wartung ermöglicht werden.
 
* '''Umgehen von Einschränkungen''': Programmiersprachen bieten unterschiedliche Arten von Abstraktionsmechanismen. Sollte in einer bestimmten Situation keine geeignete Abstraktionsmöglichkeit vorhanden sein wird dieses Problem oft durch Klone gelöst. Klone können aber auch aufgrund von Zeitdruck und fehlenden Kenntnissen des Entwicklers entstehen.
 
* '''Entwicklungsstrategie''': Bestehende Funktionalität wird als Vorlage für neu zu erstellende Funktionalität verwendet. Dabei wird der bereits existierende Code kopiert und nach Bedarf angepasst. Hierzu zählen auch Situationen, in denen Code dupliziert wird, um Änderungen zu erproben ohne die Funktion des Systems zu gefährden (Branching).
* '''Vorteile bei der Wartung''': Durch die Wiederverwendung von existierendem Code soll die zukünftige Wartung erleichtert werden. So wird zum Beispiel bewährter Code wiederverwendet, um das Risiko neuer Fehler zu minimieren. Außerdem können durch das Kopieren von Code unerwünschte Abhängigkeiten zwischen Komponenten vermieden und eine getrennte Wartung ermöglicht werden.
* '''Umgehen von Einschränkungen''': Programmiersprachen bieten unterschiedliche Arten von Abstraktionsmechanismen. Sollte in einer bestimmten Situation keine geeignete Abstraktionsmöglichkeit vorhanden sein, wird dieses Problem oft durch Klone gelöst. Klone können aber auch aufgrund von Zeitdruck und fehlenden Kenntnissen des Entwicklers entstehen.
* '''Unabhängige Implementierung''': Aufgrund mangelnder Kenntnis bestehender Funktionalität wird diese mehrfach implementiert. Zudem können Klone durch die Verwendung von Bibliotheken entstehen, die ein bestimmtes Protokoll erfordern.
 
== Negative Auswirkungen ==
Klone werden im Allgemeinen als [[Anti-Pattern]] angesehen, da sie dem Prinzip "[[Don’t repeat yourself]]" (DRY) widersprechen und als das am häufigsten auftretende Merkmal für schlechten Code gelten. Sie führen aus den genannten Gründen die Liste der so genanntensogenannten [[Code-Smell (Programmierung)|Code Smells]]s<ref name="Fowler-2000" /> an. Und auchAuch wenn es eine Vielzahl von Gründen für ihre Entstehung gibt, so haben Klone mitunter gravierende negative Auswirkungen auf die Software und ihre Wartung.
 
* '''Erhöhter Wartungsaufwand''': Klone erhöhen den Aufwand für die Wartung signifikant. Identischer Code muss unter Umständen mehrfach gelesen und verstanden werden. Zusätzlicher Aufwand ist erforderlich um zu verstehen ob kleine Unterschiede gewollt oder unbeabsichtigt sind. Im Fall einer Änderung muss diese mehrfach durchgeführt und getestet werden. Dabei muss für jede Kopie mindestens geprüft werden ob die Änderung auch hier durchgeführt werden muss -- selbst wenn die Kopie am Ende nicht verändert wird.
 
* '''Inkonsistente Änderungen''': Im Rahmen von Änderungen an Klonen besteht immer die Gefahr einzelne Kopien zu übersehen. Dieses Problem ist umso stärker je mehr Entwickler in einem Projekt beteiligt sind und unwissentlich voneinander kopieren. Auch wenn bestehender Code als Vorlage verwendet wird und angepasst werden muss besteht immer die Gefahr, dass diese Anpassung nicht korrekt durchgeführt wird. Ungewollt inkonsistente Änderungen können insbesondere dann problematisch sein wenn es sich bei der Änderung um einen Bugfix handelt. Der Fehler wird an einer Stelle behoben und es wird angenommen, dass das Problem damit gelöst sei obwohl der Fehler an noch mindestens einer anderen Stelle im System verbleibt. Diese unbeabsichtigten inkonsistenten Änderungen existieren nachweislich in hoher Zahl in produktiven Systemen.<ref name="Juergens-2009-ICSE" />
 
* '''Erhöhter Speicherbedarf''': Eine weitere Konsequenz von Klonen ist, dass der Codeumfang größer ist als er sein müsste. Dies betrifft sowohl den Speicherplatz der Quelltextdateien als auch die Größe des kompilierten Systems. Dies kann insbesondere im Bereich der [[Eingebettetes System|eingebetteten Systeme]] zu Problemen führen und teurere [[Hardware]] erforderlich machen. Zudem hat ein erhöhter Codeumfang auch einen erhöhten Zeitbedarf von [[Compiler]] oder [[Interpreter]] zur Folge.
 
* '''Erhöhter Wartungsaufwand''': Klone erhöhen den Aufwand für die Wartung signifikant. Oft muss identischer Code mehrfach gelesen und verstanden werden. Zusätzlicher Aufwand ist erforderlich, um zu verstehen, ob kleine Unterschiede gewollt oder unbeabsichtigt sind. Im Fall einer Änderung muss diese mehrfach durchgeführt und getestet werden. Dabei muss für jede Kopie mindestens geprüft werden, ob die Änderung auch hier durchgeführt werden muss – selbst wenn die Kopie am Ende nicht verändert wird.
* '''Kopieren von Fehlern''': Es besteht die Gefahr, dass der Quelltext kopiert wurde, in dem sich Fehler befinden. In der Folge muss der Fehler später an verschiedenen Stellen des Quelltextes gesucht und behoben werden. Dabei besteht die Gefahr einzelne Vorkommen zu übersehen.
* '''Inkonsistente Änderungen''': Im Rahmen von Änderungen an Klonen besteht immer die Gefahr, einzelne Kopien zu übersehen. Dieses Problem ist umso stärker, je mehr Entwickler in einem Projekt beteiligt sind und unwissentlich voneinander kopieren. Auch wenn bestehender Code als Vorlage verwendet wird und angepasst werden muss, besteht immer die Gefahr, dass diese Anpassung nicht korrekt durchgeführt wird. Ungewollt inkonsistente Änderungen können insbesondere dann problematisch sein, wenn es sich bei der Änderung um einen Bugfix handelt. Der Fehler wird an einer Stelle behoben und es wird angenommen, dass das Problem damit gelöst sei, obwohl der Fehler an noch mindestens einer anderen Stelle im System verbleibt. Diese unbeabsichtigten inkonsistenten Änderungen existieren nachweislich in hoher Zahl in produktiven Systemen.<ref name="Juergens-2009-ICSE" />
* '''Erhöhter Speicherbedarf''': Klone vergrößern den Codeumfang. Dies betrifft sowohl den Speicherplatz der Quelltextdateien als auch die Größe des kompilierten Systems. Dies kann insbesondere im Bereich der [[Eingebettetes System|eingebetteten Systeme]] zu Problemen führen und teurere [[Hardware]] erforderlich machen. Zudem hat ein erhöhter Codeumfang auch einen längere [[Compiler|Kompilierung]] zur Folge.
* '''Kopieren von Fehlern''': Es besteht die Gefahr, dass der kopierte Quelltext Fehler enthält. In der Folge kommt es zu den Problemen, die unter „Inkonsistente Änderungen“ beschrieben sind.
 
== Klonerkennung ==
Es existiert eine Vielzahl an Klonerkennungsverfahren,<ref name="Goede-2011-Dissertation" /> die sich grob anhand der Programmrepräsentation, mit der sie arbeiten, kategorisieren lassen. Die Verfahren unterscheiden sich unter anderem in der [[Laufzeit (Informatik)|Laufzeit]], [[Komplexität (Informatik)|Komplexität]], Qualität der Ergebnisse und verfügbaren Normalisierungen.
 
* '''Text''': Diese Verfahren haben keinerlei sprachspezifisches Wissen und interpretieren den Quelltext als reinen Text. Dadurch sind diese Verfahren vergleichsweise schnell und einfach zu implementieren. Der Nachteil ist, dass sie vom Layout des Quelltextes abhängig sind und nur sehr wenige Möglichkeiten der Normalisierung bieten.
* '''Tokens''': Diese Verfahren basieren auf einer [[Tokenizer|lexikalischen Analyse]] des Quelltextes und arbeiten auf einer Sequenz aus Tokens. Diese Verfahren sind immer noch vergleichsweise schnell und einfach zu implementieren. Durch eine gewisse Kenntnis der analysierten Sprache lassen sich Normalisierungen wie z.&nbsp;B. das Ignorieren von Kommentaren oder das Abstrahieren von Bezeichnern durchführen. Zudem sind diese Verfahren nicht anfällig gegen Unterschiede im Layout des Quelltextes.
* '''Baum''': Diese Verfahren arbeiten auf dem [[Abstrakter Syntaxbaum|abstrakten Syntaxbaum]] (AST) des Programms und suchen darin nach ähnlichen Teilbäumen. Dadurch bieten sie noch weitere Möglichkeiten der Normalisierung wie z.&nbsp;B. die Abstraktion von der Art einer Schleife oder die Reihenfolge der Operanden in kommutativen Operationen. Baumbasierte Verfahren sind allerdings komplexer zu implementieren und benötigen deutlich mehr Laufzeit. Zudem erfordern sie, dass der Quelltext syntaktischesyntaktisch korrekt ist und [[Parser|geparst]] werden kann. Dies ist ein deutlicher Nachteil gegenüber textbasierten und tokenbasierten Verfahren.
* '''Graph''': Diese Verfahren arbeiten zumeist auf dem Program Dependency Graph (PDG) und suchen nach ähnlichen Teilgraphen. Damit sind sie die am komplexesten zu implementierenden und zugleich langsamsten Verfahren. Ihr Vorteil besteht darin, dass sie Klone mit geringer syntaktischer Ähnlichkeit erkennen können, die von keinem der anderen Verfahren gefunden werden.
* '''Metriken''': Diese Verfahren berechnen für bestimmte Entitäten im Quelltext (z.&nbsp;B. [[Methode (Programmierung)|Methoden]]) [[Softwaremetrik|Metriken]] und erkennen Klone durch den Vergleich dieser Metriken. Sie sind recht einfach zumzu implementieren und auch vergleichsweise schnell. Der Nachteil besteht darin, dass Klone nur auf der vorher festgelegten Granularitätsstufe gefunden werden können. So können z.&nbsp;B. keine Klone innerhalb von Methoden gefunden werden, wenn die Metriken auf Basis ganzer Methoden berechnet werden. In der Praxis finden diese Verfahren wenig Anwendung, da viele Entitäten rein zufällig ähnliche Metrikwerte aufweisen, ohne dass eine syntaktische oder semantische Ähnlichkeit besteht.
 
Nicht jedes Verfahren lässt sich eindeutig einer der Kategorien zuordnen, da manche Verfahren Elemente aus verschiedenen Kategorien vereinen. So existieren z.&nbsp;B. ''hybride Verfahren'', die zunächst einen abstrakten Syntaxbaum erstellen, diesen dann serialisieren und ein tokenbasiertes Verfahren zur Erkennung von Klonen in der Sequenz der serialisierten Knoten einsetzen.
 
Weiterhin lassen sich Klonerkennungsverfahren danach unterschieden, ob sie ''inkrementell'' arbeiten oder nicht. Ein inkrementelles Verfahren<ref name="Goede-2009-CSMR" /><ref name="Hummel-2010-ICSM" /> erkennt Klone in mehreren aufeinanderfolgenden Versionen des Quelltextes. Im Vergleich zur wiederholten Anwendung eines nicht-inkrementellen Verfahrens für jede einzelne Version, machen sich inkrementelle Verfahren die Analyseergebnisse der vorherigen Version zunutze. Dadurch bieten inkrementelle Verfahren einen deutlichen Geschwindigkeitsvorteil bei der Klonerkennung über mehrere Versionen des Quelltextes.
 
=== Werkzeuge ===
Es gibt verschiedene Werkzeuge zur [[Statische Code-Analyse|statischen Analyse]] von Programmcode, die auch Quelltextklone finden können. Dazu gehören zahlreiche freie Werkzeugen wie das [[PMD (Software)|PMD]]-Plugin CPD (''(Copy/Paste Detector)''), [[Clone Digger]] (für [[Python (Programmiersprache)|Python]] und [[Java (Programmiersprache)|Java]]), [[Cppcheck]] (für [[C++]] und [[C (Programmiersprache)|C]]) und [[ConQAT]] (für [[Ada (Programmiersprache)|Ada]], [[ABAP]], [[C-Sharp|C#]], [[C (Programmiersprache)|C]], [[C++]], [[CobolCOBOL]], [[Java (Programmiersprache)|Java]], [[Visual Basic Classic|Visual Basic]], [[PL/I]]) sowie proprietäre Werkzeuge wie [[CCFinder]] (''(Code Clone Finder)'') oder [[Simian (Software)|Simian]] (''(Similarity Analyser)'').
 
== Klonmanagement ==
Zeile 120:
 
=== Entfernen ===
Die Klone werden entfernt, indem eine geeignete Abstraktion geschaffen wird, mehrmit der die redundanten Quelltextabschnitte vereinheitlicht werden können. HäufigDies wirdkann hierfürzum dasBeispiel Extract-Method-[[Refactoring]] angewendet. In [[Objektorientierung|objektorientierten]] Sprache besteht zudemdurch die MöglichkeitAuslagerung Klonevon durchwiederkehrenden AusnutzenAlgorithmen derin [[VererbungProzedur (Programmierung)|VererbungProzeduren]] und das Zusammenfassen der Kopien in einer gemeinsamenoder [[Basisklasse]]Methode (Pull-Up-Method-[[RefactoringProgrammierung)|Methoden]]) zu entfernenerfolgen.<ref>Markus InBautsch: Sprachen''[[b:Strukturierte dieProgrammierung#Methodenaufrufe|Codewiederholung einen [[PräprozessorMethodenaufrufe]]''. beinhalten,In: lassen''Strukturierte sich Klone auch durch entsprechende Makros entfernenProgrammierung''. Bei Klonen die mehrere Dateien oder ganze Subsysteme umfassen („Strukturelle Klone“) bietet sich an die Klone durch Auslagerung in [[Modul (Software)|ModuleWikibook]]</ref> oderHäufig wird hierfür das Extract-Method-[[Programmbibliothek|BibliothekenRefactoring]] zu entfernenangewendet.
 
In [[Objektorientierung|objektorientierten]] Sprache besteht zudem die Möglichkeit, Klone durch Ausnutzen der [[Vererbung (Programmierung)|Vererbung]] und das Zusammenfassen der Kopien in einer gemeinsamen [[Basisklasse]] (Pull-Up-Method-[[Refactoring]]) zu entfernen.<ref>Markus Bautsch: ''[[b:Strukturierte Programmierung#Vermeidung von Codewiederholung durch Vererbung|Vermeidung von Codewiederholung durch Vererbung]]''. In: ''Strukturierte Programmierung''. [[Wikibook]]</ref>
 
In Sprachen, die einen [[Präprozessor]] beinhalten, lassen sich Klone unter Umständen durch entsprechende Makros entfernen. Bei Klonen, die mehrere Dateien oder ganze Subsysteme umfassen („Strukturelle Klone“), bietet sich an, die Klone durch Auslagerung in [[Modul (Software)|Module]] oder [[Programmbibliothek|Bibliotheken]] zu entfernen.
 
=== Beobachten ===
Nicht immer lassen Klone sich einfach entfernen. Ein alternativer Umgang besteht darin, die Klone durch ein entsprechendes Werkzeug zu beobachten. Bei der Änderung eines Klons wird der Entwickler auf das VorhandeseinVorhandensein weiterer Kopien hingewiesen. Dadurch wird das Risiko von ungewollt inkonsistenten Änderungen vermieden.
 
== Klone außerhalb des Quelltextes ==
Klonerkennung fokussiert sich stark auf ähnliche Abschnitte im Quelltext eines Programms. Darüber hinaus existieren Klone aber auch in anderen Artefakten der Softwareentwicklung wie z.&nbsp;B. [[Modellgetriebene Softwareentwicklung|Modellen]]<ref name="Deissenboeck-2008-ICSE" /><ref name="Deissenboeck-2010-IWSC" /><ref name="Störrle-2010-ECSA" /> oder [[Lastenheft|Anforderungsspezifikationen]].<ref name="Domann-2009-ISESE" /><ref name="Juergens-2010-ICSE" /> Die Gründe für die Klone und deren negative Auswirkungen sind weitestgehend übertragbar. Die Definition der Ähnlichkeit hingegen muss angepasst werden. Während es für die Erkennung von Klonen im Quelltext bereits etablierte Verfahren gibt, wird an der Erkennung von Klonen in anderen Artefakten noch intensiv geforscht.
 
== Beispiel ==
Das folgende Beispiel in [[Java (Programmiersprache)|Java]] zeigt wie Klone durch ein Extract-Method-[[Refactoring]] entfernt werden können. Der Quelltext berechnet die Summe der Werte in zwei Arrays.
 
<sourcesyntaxhighlight lang="java">
public int sum(int[] values1, int[] values2) {
int sum1 = 0;
int sum2 = 0;
 
for (int i = 0; i < values1.length; i++)
{
sum1 += valuesvalues1[i];
}
 
for (int i = 0; i < values2.length; i++)
{
Zeile 148 ⟶ 152:
return sum1 + sum2;
}
</syntaxhighlight>
</source>
 
Die Schleife, die die eigentliche Berechnung vornimmt, kann in eine eigene Funktion extrahiert werden.
<sourcesyntaxhighlight lang="java">
public int sum(int[] values)
{
Zeile 161 ⟶ 165:
return sum;
}
</syntaxhighlight>
</source>
 
Die neue Funktion kann für jedes Array einmal aufgerufen werden. Dadurch wurdewurden die Klone entfernt und die Redundanz verringert.
<sourcesyntaxhighlight lang="java">
public int sum(int[] values1, int[] values2) {
return sum(values1) + sum(values2);
}
</syntaxhighlight>
</source>
 
Die Berechnung der Summe der Werte eines Arrays stellt einen Klon außerhalb des Quelltextes dar, da ab Java 8 für derartige Anforderungen Streams existieren. Die <code>public int sum(int[] values)</code> Methode kann daher gelöscht werden und die zweite Methode folgendermaßen geändert werden:
== Weblinks ==
<syntaxhighlight lang="java">
* Robert Tairas: ''[http://students.cis.uab.edu/tairasr/clones/literature/ Code Clones Literature].'' Abgerufen am 28. August 2013.
public int sum(int[] values1, int[] values2) {
return IntStream.of(values1).sum() + IntStream.of(values2).sum();
}
</syntaxhighlight>
 
== Literatur ==
* [[Martin Fowler]]: ''Refactoring. Wie Sie das Design vorhandener Software verbessern.'' Addison-Wesley, München 2000 (Originaltitel: ''Refactoring. Improving The Design Of Existing Code'', übersetzt von Bernd Kahlbrandt), ISBN 3-8273-1630-8.
* Nils Göde: ''Clone Evolution.'' Dissertation, Universität Bremen, Logos Verlag Berlin GmbH, Berlin 2011, ISBN 978-38325292083-8325-2920-8.
* Elmar Juergens, Florian Deissenboeck, Benjamin Hummel: ''[http://wwwbroy.in.tum.de/~juergens/publications/ICSE2009_FRD_0232_Juergens.pdf ''A Workbench for Clone Detection Research].''.] (PDF; 359&nbsp;kB) In: ''Proceedings of the 31st31<sup>st</sup> International Conference on Software Engineering'', IEEE Computer Society, 2009.
* Elmar Juergens, Florian Deissenboeck, Benjamin Hummel, Stefan Wagner: ''[https://www.cqse.eu/publications/2009-do-code-clones-matter.pdf ''Do code clones matter?]''] (PDF; 259&nbsp;kB) In: ''Proceedings of the 31st31<sup>st</sup> International Conference on Software Engineering'', S. 485–495. IEEE Computer Society, 2009.
* Rainer Koschke: ''[http://drops.dagstuhl.de/opus/volltexte/2007/962/pdf/06301.KoschkeRainer.962.pdf ''Survey of Research on Software Clones].''.] (PDF; 222&nbsp;kB) Dagstuhl Seminar: Duplication, Redundancy, and Similarity in Software, 2006.
* Dhavleesh Rattan, Rajesh Bhatia, Maninder Singh: ''Software clone detection: A systematic review.'' Information and Software Technology, Band 55, 2013, Ausgabe 7, SeiteS. 1165–1199, 2013.
* Chanchal Kumar Roy, James R. Cordy: ''[http://research.cs.queensu.ca/TechReports/Reports/2007-541.pdf ''A survey on software clone detection research].''.] (PDF; 577&nbsp;kB) Technical report, Queens University at Kingston, Ontario, (Canada,) 2007.
 
== Weblinks ==
* Robert Tairas: [http://students.cis.uab.edu/tairasr/clones/literature/ ''Code Clones Literature''.] Abgerufen am 28. August 2013.
 
== Einzelnachweise ==
<references>
<ref name="Deissenboeck-2008-ICSE">
<ref name="Deissenboeck-2008-ICSE">Florian Deissenboeck, Benjamin Hummel, Elmar Jürgens, Bernhard Schätz, Stefan Wagner, Jean-François Girard, Stefan Teuchert: ''[https://www.cqse.eu/publications/2008-clone-detection-in-automotive-model-based-development.pdf Clone detection in automotive model-based development].'' In Proceedings of the 30th International Conference on Software Engineering, S. 603–612. ACM, 2008.</ref>
<ref name="Deissenboeck-2010-IWSC">Florian Deissenboeck, Benjamin Hummel, Elmar JuergensJürgens, MichaelBernhard PfaehlerSchätz, Stefan Wagner, Jean-François Girard, Stefan Teuchert: ''[https://www.cqse.eu/publications/2010-model2008-clone-detection-in-practiceautomotive-model-based-development.pdf Model clone''Clone detection in practice].automotive model-based development''.] (PDF; 409&nbsp;kB) In: ''Proceedings of the 4th30<sup>th</sup> International WorkshopConference on Software Clones, S. 57–64Engineering''. ACM, 20102008, S. 603–612.</ref>
</ref>
<ref name="Domann-2009-ISESE">Christoph Domann, Elmar Juergens, Jonathan Streit: ''[https://www.cqse.eu/publications/2009-the-curse-of-copypaste-cloning-in-requirements-specifications.pdf The curse of copy&paste–cloning in requirements specifications].'' In Proceedings of the 3rd International Symposium on Empirical Software Engineering and Measurement, p. 443–446. IEEE Computer Society, 2009.</ref>
<ref name="Deissenboeck-2010-IWSC">
<ref name="Fowler-2000">[[Martin Fowler]]: ''Refactoring. Wie Sie das Design vorhandener Software verbessern.'' Addison-Wesley, München 2000 (Originaltitel: ''Refactoring. Improving The Design Of Existing Code'', übersetzt von Bernd Kahlbrandt), ISBN 3-8273-1630-8, S. 67–82</ref>
Florian Deissenboeck, Benjamin Hummel, Elmar Juergens, Michael Pfaehler: [https://www.cqse.eu/publications/2010-model-clone-detection-in-practice.pdf ''Model clone detection in practice''.] (PDF; 291&nbsp;kB) In: ''Proceedings of the 4<sup>th</sup> International Workshop on Software Clones''. ACM, 2010, S. 57–64.
<ref name="Goede-2009-CSMR">Nils Göde, Rainer Koschke: ''Incremental clone detection.'' In Proceedings of the 13th European Conference on Software Maintenance and Reengineering, pages 219–228. IEEE Computer Society, 2009.</ref>
</ref>
<ref name="Goede-2011-Dissertation">Nils Göde: ''Clone Evolution.'' Dissertation, Universität Bremen, 2011, S. 15–21.</ref>
<ref name="Domann-2009-ISESE">
<ref name="Hummel-2010-ICSM">Benjamin Hummel, Elmar Juergens, Lars Heinemann, Michael Conradt: ''[https://www.cqse.eu/publications/2010-index-based-code-clone-detection-incremental-distributed-scalable.pdf Index-based code clone detection]: Incremental, distributed, scalable.'' In Proceedings of the 26th International Conference on Software Maintenance. IEEE Computer Society, 2010.</ref>
<refChristoph Domann, name="Juergens-2009-ICSE">Elmar Juergens, FlorianJonathan Deissenboeck, Benjamin Hummel, Stefan WagnerStreit: ''[https://www.cqse.eu/publications/2009-dothe-curse-of-copypaste-cloning-codein-clonesrequirements-matterspecifications.pdf Do''The codecurse clonesof matter?]copy&paste–cloning in requirements specifications''.] (PDF; 107&nbsp;kB) In: ''Proceedings of the 31st3<sup>rd</sup> International ConferenceSymposium on Empirical Software Engineering, S.and 485–495Measurement''. IEEE Computer Society, 2009, S. 443–446.</ref>
</ref>
<ref name="Juergens-2010-ICSE">Elmar Juergens, Florian Deissenboeck, Martin Feilkas, Benjamin Hummel, Bernhard Schaetz, Stefan Wagner, Christoph Domann, Jonathan Streit: ''[https://www.cqse.eu/publications/2010-can-clone-detection-support-quality-assessments-of-requirements-specifications.pdf Can clone detection support quality assessments of requirements specifications?]'' In Proceedings of the 32nd International Conference on Software Engineering, S. 79–88. ACM, 2010.</ref>
<ref name="Fowler-2000">
<ref name="Koschke-2008-FSM">Rainer Koschke: ''Frontiers of software clone management.'' In Proceedings of Frontiers of Software Maintenance, S. 119–128. IEEE Computer Society,
[[Martin Fowler]]: ''Refactoring. Wie Sie das Design vorhandener Software verbessern.'' Addison-Wesley, München 2000 (Originaltitel: ''Refactoring. Improving The Design Of Existing Code'', übersetzt von Bernd Kahlbrandt), ISBN 3-8273-1630-8, S. 67–82
2008.</ref>
</ref>
<ref name="Roy-2007-TR">Chanchal Kumar Roy, James R. Cordy: ''[http://research.cs.queensu.ca/TechReports/Reports/2007-541.pdf A survey on software clone detection research].'' Technical report, Queens University at Kingston, Ontario, Canada, 2007, S. 3–7.</ref>
<ref name="Goede-2009-CSMR">
<ref name="Störrle-2010-ECSA">Harald Störrle: ''Towards clone detection in UML domain models.'' In Proceedings of the 4th European Conference on Software Architecture: Companion Volume, p. 285–293. ACM, 2010.</ref>
Nils Göde, Rainer Koschke: ''Incremental clone detection.'' In: ''Proceedings of the 13<sup>th</sup> European Conference on Software Maintenance and Reengineering''. IEEE Computer Society, 2009, S. 219–228.
</ref>
<ref name="Goede-2011-Dissertation">
Nils Göde: ''Clone Evolution.'' Dissertation, Universität Bremen, 2011, S. 15–21.
</ref>
<ref name="Hummel-2010-ICSM">
Benjamin Hummel, Elmar Juergens, Lars Heinemann, Michael Conradt: [https://www.cqse.eu/publications/2010-index-based-code-clone-detection-incremental-distributed-scalable.pdf ''Index-based code clone detection. Incremental, distributed, scalable''.] (PDF; 440&nbsp;kB) In: ''Proceedings of the 26<sup>th</sup> International Conference on Software Maintenance''. IEEE Computer Society, 2010.
</ref>
<ref name="Juergens-2009-ICSE">
Elmar Juergens, Florian Deissenboeck, Benjamin Hummel, Stefan Wagner: [https://www.cqse.eu/publications/2009-do-code-clones-matter.pdf ''Do code clones matter?''] (PDF; 259&nbsp;kB) In: ''Proceedings of the 31<sup>st</sup> International Conference on Software Engineering''. IEEE Computer Society, 2009, S. 485–495.
</ref>
<ref name="Juergens-2010-ICSE">
Elmar Juergens, Florian Deissenboeck, Martin Feilkas, Benjamin Hummel, Bernhard Schaetz, Stefan Wagner, Christoph Domann, Jonathan Streit: [https://www.cqse.eu/publications/2010-can-clone-detection-support-quality-assessments-of-requirements-specifications.pdf ''Can clone detection support quality assessments of requirements specifications?''] (PDF; 400&nbsp;kB) In: ''Proceedings of the 32<sup>nd</sup> International Conference on Software Engineering''. ACM, 2010, S. 79–88.
</ref>
<ref name="Koschke-2008-FSM">
Rainer Koschke: ''Frontiers of software clone management''. In: ''Proceedings of Frontiers of Software Maintenance''. IEEE Computer Society, 2008, S. 119–128.
</ref>
<ref name="Roy-2007-TR">
Chanchal Kumar Roy, James R. Cordy: [http://research.cs.queensu.ca/TechReports/Reports/2007-541.pdf ''A survey on software clone detection research''.] (PDF; 577&nbsp;kB) Technical report, Queens University at Kingston, Ontario (Canada) 2007, S. 3–7.
</ref>
<ref name="Störrle-2010-ECSA">
Harald Störrle: ''Towards clone detection in UML domain models.'' In: ''Proceedings of the 4<sup>th</sup> European Conference on Software Architecture''. ACM, 2010, Companion Volume, S. 285–293.
</ref>
</references>