object in object oriented programming

object in object oriented programming

Stell dir vor, du baust ein Haus, aber jedes Mal, wenn du den Lichtschalter betätigst, muss der Schalter erst beim Fundament nachfragen, ob er überhaupt existiert, während die Glühbirne gleichzeitig versucht, ihre eigene Farbe vor dem Stromnetz zu verstecken. Was in der Architektur wie Wahnsinn klingt, ist der Alltag der modernen Softwareentwicklung. Wir haben uns jahrzehntelang eingeredet, dass die Welt aus sauberen, abgeschlossenen Einheiten besteht, die wir einfach nur modellieren müssen. Das Object In Object Oriented Programming war das Versprechen einer Ordnung, die Komplexität bändigen sollte, indem sie Daten und Verhalten hinter einer hübschen Fassade vereint. Doch genau hier liegt der fundamentale Irrtum, den fast jeder Informatikstudent im ersten Semester schluckt, ohne zu kauen. Wir dachten, wir bilden die Realität ab, aber wir haben stattdessen ein bürokratisches Labyrinth aus Abhängigkeiten erschaffen, das Flexibilität im Keim erstickt. Die Idee, dass ein Stück Code sowohl sein Wissen als auch seine Logik in einer untrennbaren Kapsel mit sich herumtragen sollte, ist weniger ein Geniestreich als vielmehr eine Altlast, die uns heute daran hindert, wirklich effiziente und wartbare Systeme zu bauen.

Die Lüge der Kapselung und das Object In Object Oriented Programming

Die Informatiklegende Alan Kay, der den Begriff ursprünglich prägte, dachte eigentlich an biologische Zellen oder Computer in einem Netzwerk. Er wollte Kommunikation, nicht Hierarchie. Was die Industrie daraus machte, war jedoch etwas völlig anderes: eine starre Struktur aus Klassen und Vererbung. Wenn wir heute von dieser Methode sprechen, meinen wir meistens die C++- oder Java-Schule der Neunzigerjahre. In dieser Welt wird uns beigebracht, dass Kapselung der heilige Gral ist. Daten sollen geschützt sein. Nur das Objekt selbst darf sie verändern. Das klingt auf dem Papier wunderbar sicher, führt in der Praxis aber zu einem Phänomen, das Kritiker oft als das Bananen-Problem bezeichnen. Du willst die Banane, aber was du bekommst, ist ein Gorilla, der die Banane hält, und der gesamte Dschungel hängt auch noch hinten dran.

Diese enge Kopplung zwischen dem Zustand einer Information und den Funktionen, die darauf operieren, ist die Wurzel vieler technischer Schulden. In einem echten System fließen Daten. Sie werden transformiert, gefiltert und über Netzwerkgrenzen geschickt. Ein starres Konstrukt versucht krampfhaft, diesen Fluss zu stoppen, indem es die Daten in kleine Tresore sperrt. Das Resultat ist ein Wald aus sogenannten Getter- und Setter-Methoden, die die Kapselung ohnehin ad absurdum führen. Wir tun so, als hätten wir Geheimnisse, aber am Ende muss doch jeder alles wissen, um die Arbeit zu erledigen. Wir haben eine Architektur der Misstrauenszone geschaffen, in der die Interaktion zwischen den Komponenten komplizierter ist als die eigentliche Geschäftslogik. Wer schon einmal versucht hat, ein tief verschachteltes Klassensystem zu refactoren, weiß, dass man eher ein Kartenhaus im Sturm umbaut, als ein modulares System verbessert.

Warum Hierarchien in der Logik scheitern müssen

Eines der hartnäckigsten Missverständnisse ist der Glaube, dass die Welt hierarchisch organisiert ist. In Lehrbüchern ist das einfach. Ein Hund ist ein Säugetier, ein Säugetier ist ein Tier. In der echten Softwareentwicklung bricht dieses Modell sofort zusammen. Was ist, wenn dein Hund plötzlich auch ein steuerpflichtiges Gut in einer kommunalen Datenbank sein muss? In der klassischen Denkweise fängst du an, Mehrfachvererbung zu nutzen oder Interface-Friedhöfe zu graben. Du versuchst, eine Realität, die in Graphen und Netzwerken denkt, in einen Baum zu pressen. Das funktioniert nicht. Es hat nie funktioniert. Es führt nur dazu, dass Entwickler abstrakte Basisklassen erstellen, die so viel generische Logik enthalten, dass niemand mehr versteht, was sie eigentlich tun sollen.

Die Fixierung auf das Object In Object Oriented Programming hat dazu geführt, dass wir die Komposition vernachlässigt haben. Anstatt kleine, austauschbare Werkzeuge zu bauen, erschaffen wir Monolithen im Kleinen. Ein modernes System in Rust oder Go zeigt uns oft einen besseren Weg, indem es Datenstrukturen strikt von Methoden trennt oder Verhalten über Traits definiert, ohne eine starre Ahnenreihe zu erzwingen. In Deutschland, wo Ingenieurskunst oft mit Gründlichkeit und strikter Struktur gleichgesetzt wird, hielten wir besonders lange an diesen starren Modellen fest. Große Banken- und Versicherungssysteme, die in den frühen Zweitausendern nach diesen Prinzipien gebaut wurden, sind heute kaum noch zu bewegen. Sie sind wie versteinerte Denkmäler einer Epoche, die dachte, man könne Software wie eine mechanische Uhr planen. Die Welt ist aber eher wie ein Ökosystem. Sie ist unordentlich, redundant und ständig im Wandel. Ein System, das auf starren Identitäten beharrt, zerbricht, wenn sich die Anforderungen verschieben.

Das Problem der Identität und des Zustands

Ein weiterer kritischer Punkt ist der Umgang mit dem Zustand. Wenn jedes Ding im Code seinen eigenen internen Zustand verwaltet, wird Nebenläufigkeit zum Albtraum. Wir müssen Sperren setzen, Mutexe verwalten und hoffen, dass keine Race-Condition das gesamte Kartenhaus zum Einsturz bringt. Die funktionale Programmierung hat uns längst gezeigt, dass Unveränderlichkeit der Schlüssel zur Skalierbarkeit ist. Doch der klassische Ansatz zwingt uns dazu, Objekte als lebendige Wesen zu betrachten, die sich über die Zeit verändern. Das macht das Debugging zur Detektivarbeit. Man fragt sich nicht nur, was der Wert einer Variable ist, sondern man muss die gesamte Lebensgeschichte dieses Objekts rekonstruieren, um zu verstehen, wie es in diesen korrupten Zustand geraten konnte. In einer Welt, in der wir auf Tausenden von Kernen in der Cloud rechnen, ist ein Modell, das auf lokalem, veränderlichem Zustand basiert, schlichtweg veraltet. Es ist ein Relikt aus einer Zeit, in der Speicher teuer und Prozessoren einsam waren.

Die Illusion der Wiederverwendbarkeit

Man versprach uns damals, dass wir Code wie Legosteine zusammenstecken könnten. Einmal geschrieben, überall eingesetzt. Die Realität sieht anders aus. Code ist nur selten ohne seinen Kontext wiederverwendbar, wenn er in eine Klasse eingemauert wurde. Die einzige wirklich erfolgreiche Wiederverwendung in der Softwaregeschichte fand auf der Ebene von Bibliotheken statt, die Daten transformieren, nicht auf der Ebene von Geschäftsobjekten. Ein Sortieralgorithmus ist wiederverwendbar. Eine Kundenklasse ist es fast nie, weil jeder Kunde in jedem System andere Attribute und Regeln hat. Wir haben Jahre damit verschwendet, die perfekte Abstraktion zu suchen, anstatt einfach Funktionen zu schreiben, die Daten von A nach B schieben. Die Arroganz, die Welt in ein festes Schema pressen zu wollen, hat uns eine Komplexität beschert, die heute kaum noch ein einzelner Mensch durchdringen kann.

Es gibt einen Grund, warum moderne Frameworks und Sprachen sich immer mehr von der reinen Lehre entfernen. Wir sehen eine Rückkehr zur Einfachheit. Daten sind Daten. Funktionen sind Funktionen. Das ist keine Rückschrittlichkeit, sondern eine notwendige Korrektur. Wir müssen aufhören, unsere Programme wie Biologieexperimente zu behandeln und anfangen, sie wieder wie Datenflüsse zu begreifen. Wenn wir die Daten aus den Tresoren befreien, gewinnen wir die Freiheit zurück, sie so zu kombinieren, wie es das aktuelle Problem erfordert, nicht wie es ein Architekt vor fünf Jahren in einem UML-Diagramm vorgesehen hat. Die eigentliche Aufgabe der Softwareentwicklung ist es, Probleme zu lösen, nicht Kathedralen aus Klassenhierarchien zu bauen, in denen die Logik hinter Schichten von Abstraktionen verhungert.

Skeptiker werden nun einwerfen, dass ohne diese Strukturen das totale Chaos ausbricht. Sie werden sagen, dass man große Teams nur koordinieren kann, wenn jeder seinen eigenen kleinen Bereich hat, den er kontrolliert. Das ist ein Scheinargument. Chaos entsteht nicht durch fehlende Klassen, sondern durch schlechte Schnittstellen und mangelnde Disziplin beim Datenfluss. Ein funktionales Design mit klaren Verträgen zwischen Modulen ist oft weitaus stabiler als ein Geflecht aus Objekten, die sich gegenseitig über versteckte Seiteneffekte beeinflussen. Es geht nicht darum, Struktur aufzugeben, sondern die falsche, künstliche Struktur durch eine natürliche, datenzentrierte Ordnung zu ersetzen. Wir haben uns zu lange hinter Begriffen wie Polymorphie und Vererbung versteckt, um die Tatsache zu verschleiern, dass wir oft selbst nicht genau wissen, wie unsere Daten transformiert werden sollen.

Die Zukunft gehört Systemen, die klein, flach und transparent sind. Wir brauchen keine digitalen Götter in Form von Allwissenden-Manager-Objekten, die alles kontrollieren. Wir brauchen einfache Rohre und Filter. Die Ära der großen, schweren Software-Architekturen geht zu Ende, weil sie den Anforderungen an Geschwindigkeit und Skalierbarkeit nicht mehr gewachsen ist. Wenn du das nächste Mal vor einer komplexen Aufgabe stehst, versuch nicht, ein Modell der Welt zu bauen, sondern konzentrier dich darauf, was mit den Daten passieren muss. Alles andere ist nur teures Theater, das wir uns gegenseitig vorspielen, um uns wie echte Ingenieure zu fühlen. Am Ende des Tages interessiert es den Nutzer nicht, ob dein Code ein Meisterwerk der Abstraktion ist, sondern ob er funktioniert und schnell angepasst werden kann.

Wahre Modularität entsteht nicht durch das Einsperren von Logik in starre Hüllen, sondern durch die radikale Trennung von dem, was eine Information ist, und dem, was mit ihr geschieht.

MS

Martin Schulz

Martin Schulz hat für verschiedene Online-Redaktionen gearbeitet und steht für Qualitätsjournalismus mit Substanz.