Veränderlich vs. unveränderlich beschreibt, ob Systeme, Infrastruktur oder Daten nach der Erstellung geändert werden können. Veränderliche Ressourcen können an Ort und Stelle geändert werden. Unveränderliche Ressourcen können nicht geändert werden – bei jeder Änderung wird eine neue Instanz erstellt.
Veränderlich versus unveränderlich ist ein Prinzip, das moderne Ansätze sowohl für die Softwareentwicklung als auch für das Infrastrukturmanagement antreibt.
Der Unterschied lässt sich mit dem Schreiben von Text auf ein Whiteboard vergleichen. Wenn Sie Wörter hinzufügen, Teile löschen oder den geschriebenen Text ändern können, ist das wie eine veränderliche Ressource. Aber wenn das Whiteboard in dem Moment, in dem Sie fertig sind, unter Glas eingeschlossen ist und Sie ein neues Whiteboard verwenden müssen, um etwas anderes zu schreiben, ist das eine unveränderliche Ressource.
Während dieses Konzept im Großen und Ganzen auf die gesamte Computertechnik anwendbar ist, ist es am häufigsten in der Programmierung anzutreffen. Beim Programmieren ist es für allgemeine Aufgaben unerlässlich zu verstehen, welche Datentypen direkt geändert werden können und wann eine neue Kopie erstellt werden muss. Zu diesen Aufgaben gehören das Schreiben von Algorithmen, das Erstellen von Anwendungsprogrammierschnittstellen (APIs) und das Entwerfen von Klassen in objektorientierter Programmierung (OOP).
Die Wahl, veränderliche oder unveränderliche Objekte zu verwenden, wirkt sich darauf aus, wie Daten im Speicher verwaltet werden, wie sicher sie gemeinsam genutzt oder verändert werden können und ob unbeabsichtigte Nebeneffekte auftreten können. Dies ist der Grund, warum veränderlich versus unveränderlich ein grundlegendes Konzept sowohl für Anfänger als auch für erfahrene Programmierer ist.
In der Programmiersprache Python sind beispielsweise Listen und Wörterbücher veränderliche Typen. Elemente können innerhalb dieser Objekte hinzugefügt, entfernt oder geändert werden. Im Gegensatz dazu sind Objekte wie boolesche Werte (wahre oder falsche Werte) oder Tupel – geordnete Sammlungen wie (1,2,3) – unveränderliche Typen. Ihr Inhalt kann nicht geändert oder mutiert werden, ohne ein völlig neues Objekt zu erstellen.
Branchen-Newsletter
Bleiben Sie mit dem Think-Newsletter über die wichtigsten – und faszinierendsten – Branchentrends in den Bereichen KI, Automatisierung, Daten und mehr auf dem Laufenden. Weitere Informationen finden Sie in der IBM Datenschutzerklärung.
Ihr Abonnement wird auf Englisch geliefert. In jedem Newsletter finden Sie einen Abmeldelink. Hier können Sie Ihre Abonnements verwalten oder sich abmelden. Weitere Informationen finden Sie in unserer IBM Datenschutzerklärung.
Die Wahl zwischen veränderlichen und unveränderlichen Daten hängt im Allgemeinen von drei Schlüsselfaktoren ab: ob Daten häufig aktualisiert werden müssen, über Threads hinweg gemeinsam genutzt werden oder einen Versionsverlauf erfordern.
Veränderliche Typen funktionieren im Allgemeinen am besten, wenn Daten häufig aktualisiert werden müssen und mehrere Teile eines Programms dasselbe Objekt ändern.
Veränderliche Objekte ändern die Daten an Ort und Stelle und reduzieren die Speicherbelegung, indem sie die Erstellung neuer Objekte überflüssig machen. Dies kann die Prozessorauslastung der Garbage-Collection – dem Prozess des Entfernens ungenutzter Daten, um Speicher freizugeben – verringern, da weniger temporäre Objekte erstellt und abgeholt werden müssen.
Warenkörbe in Apps verwenden beispielsweise veränderliche Listen, um Artikel direkt hinzuzufügen oder zu entfernen, ohne dass für jede Änderung neue Objekte erstellt werden müssen.
Veränderliche Typen erzielen bei sich häufig ändernden Daten (wie z. B. wachsenden Listen oder Echtzeitzählern) eine bessere Leistung, da sie vorhandene Objekte aktualisieren, anstatt neue zu erstellen. Diese Effizienz beschleunigt Vorgänge in Datenstrukturen, die auf schnelle Änderungen angewiesen sind.
Beispielsweise kann die Playlist einer Musik-App eine veränderliche Liste verwenden, um schnelle Aktualisierungen vorzunehmen. Dies kann in Mikrosekunden geschehen, wenn ein Titel hinzugefügt oder gelöscht wird, verglichen mit der Neuerstellung einer Wiedergabeliste mit 1.000 Titeln für jede Änderung.
Mit veränderlichen Objekten können mehrere Teile eines Programms auf dasselbe Objekt zugreifen und es ändern. Dieser Prozess ermöglicht es ihnen, mit einem gemeinsamen Zustand zu arbeiten – den Daten, die mehrere Komponenten lesen und schreiben, um ihre Aktionen zu koordinieren. Es ist nützlich, wenn Komponenten koordinieren oder über gemeinsame Daten kommunizieren müssen.
Eine Projektmanagement-App verwendet beispielsweise veränderliche Objekte, um Aufgabenlisten, Kalender und Benachrichtigungen zu teilen. Wenn ein Teammitglied eine Aufgabe aktualisiert, sieht jeder die Änderung sofort.
Unveränderliche Typen funktionieren in der Regel am besten, wenn sich Daten nach ihrer Erstellung nicht ändern sollen. Dies ist besonders wichtig bei Anwendungen mit Parallelität, bei denen mehrere Teile eines Programms auf dieselben Daten zugreifen.
Da der Zustand eines unveränderlichen Objekts festgelegt ist, wird er nicht durch anderen Code geändert. Diese Funktion macht Programme vorhersehbarer und leichter verständlich, da sie Fehler im Zusammenhang mit unerwarteten Mutationen beseitigt.
Beispielsweise speichern Banking-Apps Transaktionsdatensätze häufig als unveränderliche Objekte, sodass sie später kein no-code ändern kann. Es ist kritisch für die Einhaltung gesetzlicher Vorschriften und die Führung von Prüfprotokollen, die belegen, dass die Transaktionen nicht manipuliert wurden.
Unveränderliche Objekte sind im Allgemeinen Thread-sicher, da sich ihr Zustand nach der Erstellung nicht ändern kann. Mehrere Threads können sie gleichzeitig und ohne Konflikte sicher lesen, obwohl Entwickler die Referenzen in gleichzeitigen Systemen immer noch sorgfältig verwalten müssen. Dadurch sind sie ideal für Multithread-Programme, bei denen mehrere Threads auf dieselben Daten zugreifen müssen, ohne Konflikte zu verursachen.
Eine App kann zum Beispiel gleichzeitig Threads für aktuelle Bedingungen, Vorhersagen und Warnungen ausführen. Das Speichern von Wetterdaten als unveränderliche Objekte bedeutet, dass jeder Thread dieselben Informationen lesen kann, ohne dass das Risiko einer unerwarteten Änderung besteht.
Unveränderliche Objekte können das Debugging vereinfachen, da sich die Werte während der Programmausführung nicht unerwartet ändern. Diese Funktion kann durch Seiteneffekte verursachte Fehler reduzieren und Teams helfen, Probleme schneller zu lösen.
Zum Beispiel speichern Videospiele häufig den Zustand und Statistiken der Spieler als unveränderliche Objekte. Da sich diese Werte nicht unerwartet ändern können, können Entwickler Fehler leicht aufspüren, da sie wissen, dass nicht zusammenhängender Code die Statistiken nicht verändert.
Zwei der am weitesten verbreiteten Programmierstile – die objektorientierte Programmierung (OOP) und die funktionale Programmierung – gehen unterschiedlich mit der Wandelbarkeit um.
OOP setzt oft auf Veränderlichkeit und entwickelt Programme um Objekte herum, die sowohl Daten als auch Verhaltensweisen enthalten. Diese Objekte können sich im Laufe der Zeit mithilfe spezieller Funktionen, der so genannten Setter, ändern. Sie können den Wert einer Eigenschaft aktualisieren (z. B. durch die Änderung des Alters einer Person oder des Preises eines Produkts).
Im Gegensatz dazu tendiert die funktionale Programmierung zur Unveränderlichkeit. Es erstellt und gibt neue Werte zurück, wenn sich etwas ändern muss, wodurch Programme vorhersehbarer und einfacher zu testen sind.
Programmiersprachen unterscheiden sich auch in ihrer Herangehensweise an veränderliche und unveränderliche Typen.
In Python sind sowohl veränderliche als auch unveränderliche Typen üblich.
Ein Beispiel sind Zeichenfolgen – Zeichenfolgen wie Namen oder Sätze. In Python sind Strings unveränderlich. Durch das Anfügen von neuem Text wird ein neues Zeichenfolgenobjekt erstellt. Im Gegensatz dazu sind Listen veränderlich. Diese geordneten Sammlungen sind iterierbar. Sie können Elemente innerhalb des Listenobjekts hinzufügen, entfernen oder ändern.
Anstatt einen Compiler (ein Programm, das Code vor der Ausführung in Maschinensprache konvertiert) zu verwenden, um Code zu überprüfen, bevor er ausgeführt wird, prüft Python Typen zur Laufzeit. Das bedeutet, dass Fehler nur abgefangen werden, während das Programm ausgeführt wird. Fehler im Zusammenhang mit der Veränderlichkeit, z. B. der Versuch, eine unveränderliche Zeichenfolge zu ändern, lösen einen TypeError aus.
Wenn der Fehler nicht behoben wird, wird das Programm sofort gestoppt und die Ausführung weiterer Codes verhindert. Dieses Verfahren ermöglicht eine schnellere Entwicklung, erfordert jedoch eine sorgfältige Handhabung des Typs.
Das Verständnis der Veränderbarkeit in Python hilft, Fehler beim Austausch von Daten zwischen Funktionen oder bei der Arbeit innerhalb eines gemeinsam genutzten Moduls zu vermeiden. Tutorials und Codebeispiele auf GitHub bieten Best Practices für die Verwendung von Pythons integrierten Typen.
JavaScript verwendet sowohl veränderliche als auch unveränderliche Typen. Wie Python sind auch Strings unveränderlich. Im Gegensatz zu Python sind jedoch alle Objekte standardmäßig veränderlich.
Die flexible Syntax von JavaScript unterstützt sowohl objektorientierte als auch funktionale Stile, sodass Entwickler die Veränderlichkeit nach Bedarf verwalten können.
Ähnlich wie bei Python sindJava-Strings unveränderlich. Sobald eine Zeichenkette erstellt ist, kann ihr Wert nicht mehr geändert werden. Diese Eigenschaft kann für Programme, die häufig Text erstellen oder ändern, ineffizient sein.
Um dieses Problem zu beheben, bietet Java den StringBuilder an – eine veränderliche Zeichenfolgenklasse, mit der Text direkt geändert werden kann, ohne neue Objekte erstellen zu müssen. Es kann die Leistung verbessern und die Speichernutzung reduzieren, wodurch die Sicherheit der Unveränderlichkeit mit den Nutzen der Veränderbarkeit in Einklang gebracht wird.
C++ verwendet das Schlüsselwort const, um Variablen, Funktionen und sogar ganze Objekte als schreibgeschützt zu markieren. Es kann Entwicklern eine differenzierte Kontrolle über die Veränderlichkeit geben und ein veränderliches Objekt effektiv in ein unveränderliches Objekt verwandeln, indem es Änderungen verhindert.
Wie Java können C++-Strings je nach Implementierung veränderlich oder unveränderlich sein.
C++ unterstützt sowohl objektorientierte als auch funktionale Programmierstile. Im OOP-Stil ändern Entwickler vorhandene Objekte im Laufe der Zeit, während die funktionale Programmierung neue Werte erstellt, anstatt vorhandene Daten zu ändern.
Die Prinzipien der Veränderbarkeit und der Unveränderlichkeit gehen über die Programmierung hinaus und umfassen auch Infrastruktur und Systeme. Moderne Softwareentwickler wenden dieselben Konzepte an, wenn sie Cloud-Architekturen und Bereitstellungen entwerfen.
Veränderliche Infrastruktur bezieht sich auf Server oder andere IT-Ressourcen, die nach der Bereitstellung geändert werden können. Sie können sich beispielsweise bei einem Server anmelden und die Software manuell aktualisieren, Konfigurationen ändern oder Patches installieren. Dieser Ansatz bietet zwar Flexibilität, kann aber zu Konfigurationsabweichungen führen, bei denen Server zu einzelnen „Schneeflocken“ werden und Änderungen nicht mehr verfolgt oder reproduziert werden können.
Unveränderliche Infrastruktur bedeutet, dass Server oder IT-Ressourcen nach der Bereitstellung nicht mehr geändert werden können. Anstatt laufende Systeme zu aktualisieren, stellen Teams neue Instanzen mit integrierten Änderungen bereit und entfernen dann die alten. Dieser Ansatz reduziert Konfigurationsabweichungen, vereinfacht das Rollback und trägt zu einer konsistenten Bereitstellung bei.
Die Prinzipien der Veränderlichkeit und Unveränderlichkeit lassen sich auch auf andere Bereiche des Software- und Systemdesigns anwenden.
Einige Datenbanken verwenden reine Append-Protokolle, d. h. jede Änderung wird dauerhaft aufgezeichnet und kann nicht geändert werden. Andere sind veränderlich und ermöglichen die direkte Aktualisierung oder Löschung von Daten, wie z. B. die Bearbeitung eines Dokuments.
Bestimmte Cloud-Speichersysteme können als unveränderlicher Speicher konfiguriert werden, um frühere Versionen zu speichern und sie vor Änderungen zu sperren. Dies trägt dazu bei, dass Daten nicht versehentlich geändert oder gelöscht werden. Durch den veränderlichen Speicher können Dateien jederzeit bearbeitet oder ersetzt werden.
Viele Tools zur Versionskontrolle, wie z. B. Git, folgen einem unveränderlichen Modell, bei dem jeder Commit als separater, unveränderlicher Snapshot gespeichert wird. Es trägt dazu bei, einen zuverlässigen Versionsverlauf zu gewährleisten, auch wenn neue Änderungen hinzugefügt werden.