Definition
Redundanzen
In der Programmierung versteht man unter diesem Begriff das mehrfache Vorhandensein gleicher oder inhaltlich sehr ähnlicher Strukturen im Quelltext.
Dazu gehören z. B. doppelt implementierte Programmteile (doppelter Code) oder sich wiederholende Logik in verschiedenen Methoden.
Erläuterungen
Redundanzen sind in der Regel unerwünscht, da sie den Quelltext unübersichtlich machen, die Wartung erschweren und die Fehleranfälligkeit erhöhen. Ändert sich etwa eine Anforderung, muss die Änderung an mehreren Stellen vorgenommen werden, was das Risiko von Inkonsistenzen erhöht.
In der Softwareentwicklung wird daher versucht, Redundanzen durch geeignete Techniken zu vermeiden, etwa durch Modularisierung (Zerlegung in wiederverwendbare Methoden oder Klassen) oder durch Vererbung und Polymorphie in der objektorientierten Programmierung.
Entfernung von Redundanzen
Betrachten wir einen simplen Quelltext mit stark redundantem Code:
public void zeigeKreis() { System.out.println("Figur: Kreis"); System.out.println("Farbe: blau"); } public void zeigeQuadrat() { System.out.println("Figur: Quadrat"); System.out.println("Farbe: blau"); }
Die beiden Methoden sind fast völlig identisch, sie unterscheiden sich nur in einem Punkt, nämlich in der Angabe der Figur "Kreis" oder "Quadrat".
Entfernung durch Modularisierung
Hier eine Version ohne Redundanzen, die durch Modularisierung erreicht wurde:
public void zeigeFigur(String name) { System.out.println("Figur: " + name); System.out.println("Farbe: blau"); }
Der gemeinsame (redundante) Code wurde in ein neues Modul ausgelagert, in Java wäre das also eine neue Methode (bei größeren "Umbauten" würde man dann eine eigene Klasse anlegen, für dieses kurze Beispiel reicht aber eine eigene Methode).
zeigeFigur("Kreis"); zeigeFigur("Quadrat");
Die so erstellte Methode wird dann einmal mit dem Parameter "Kreis" und einmal mit dem Parameter "Quadrat" aufgerufen.
Wenn sich jetzt die Anforderungen an die Ausgabe ändern, muss nur noch an einer Stelle in der Klasse gearbeitet werden, nämlich in der neuen Methode zeigeFigur().
Entfernung durch Polymorphie
Zunächst benötigen wir eine Oberklasse, die wir einfach mal Figur nennen:
public abstract class Figur { private String farbe = "blau"; // gemeinsame Eigenschaft public final void zeige() { System.out.println("Figur: " + bezeichnung()); System.out.println("Farbe: " + farbe); } protected abstract String bezeichnung(); }
Die gesamte Ausgabe der Informationen wird von der Oberklasse bereit gestellt. Für jede Figur erstellen wir dann eine Unterklasse, Kreis und Quadrat. Hier der Quelltext von Kreis:
public class Kreis extends Figur { @Override protected String bezeichnung() { return "Kreis"; } }
Die Quelltext von Quadrat ist analog aufgebaut.
Schließlich die Klasse Demo, die auf die beiden Klassen zugreift:
public class Demo { public static void main(String[] args) { Figur f1 = new Kreis(); Figur f2 = new Quadrat(); f1.zeige(); f2.zeige(); } }
Zugegeben, der Quelltext dieser Version ist deutlich länger als der der redundanten Version, aber er dient ja auch nur zur Demonstration des Prinzips: "Vermeidung von Redundanzen durch Polymorphie".
Hier ein paar Gründe, wieso der überarbeitete und längere Quelltext doch besser ist als die kurze aber redundante Version.
Warum Redundanz durch Polymorphie vermeiden?
Die folgende Übersicht wurde von ChatGPT 5.0 erstellt und von mir leicht überarbeitet. Von mir hinzugefügte oder geänderte Stellen sind kursiv dargestellt.
-
Änderungen an einer Stelle statt an vielen
Wenn sich etwas ändert (z. B. die Farbe oder die Art der Ausgabe), reicht es, eine Methode zu ändern. In unserem Beispiel ist das die Methode zeige() in der abstrakten Klasse Figur.
In einer redundanten Lösung müssten alle Stellen angepasst werden, was zu einem hohen Fehlerrisiko führt.
-
Erweiterbarkeit ohne Umbau
Mit Polymorphie können jederzeit neue Figuren (z. B. Rechteck, Sechseck) hinzugefügt werden, ohne bestehende Methoden ändern zu müssen.
public class Rechteck extends Figur { @Override protected String bezeichnung() { return "Rechteck"; } }
Das Prinzip nennt man Open-Closed-Principle: Software soll für Erweiterungen offen, für Änderungen geschlossen sein. Als Beispiel für die Erweiterbarkeit wurde das Projekt um die Klasse Rechteck erweitert.
-
Wiederverwendbarkeit und Wartbarkeit
Auch wenn der Einstiegscode länger wirkt, spart man später viel Arbeit: Der Quelltext ist klar strukturiert, Rollen und Verantwortlichkeiten sind sauber getrennt. Für große Projekte ist das unverzichtbar.
Ich konnte eben das Projekt durch eine neue Klasse Rechteck sehr leicht und ohne viel Aufwand erweitern.
-
Bessere Lesbarkeit durch klare Struktur
Polymorphie zwingt zu einer sauberen Klassenhierarchie. Für Studierende sieht das am Anfang nach "viel mehr" aus, aber Fachleute erkennen die Struktur sofort und verstehen schneller, wie das Programm funktioniert.
Quellen:
- Balzert: Objektorientiert Programmieren, 4. Auflage, Springer-Verlag Berlin 2025.