Start / Seminare / Modern Java Development
Modul
Modernes Java im Bestandscode
6 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Modernes Java im Bestandscode
0:00 Im ersten Modul haben wir uns angesehen, was modernes Java kann. Auf einer leeren Seite ist das alles wunderbar. Nur arbeitet kaum jemand auf einer leeren Seite. Der Alltag sieht anders aus: Da steht Code, den vor acht Jahren jemand geschrieben hat, der längst das Haus gewechselt hat. Genau dorthin gehen wir jetzt. Wir lernen eine Anwendung kennen, die alle typischen Altlasten mitbringt — und wir wenden den Maßstab aus Modul 1 zum ersten Mal auf echten Code an.
0:27 Diese Anwendung begleitet uns bis zum letzten Modul.
Modernes Java im Bestandscode
0:31 Der Rest des ersten Tages gehört der Praxis. Wir schauen uns Lagerwerk an — unser Übungsprojekt —, arbeiten uns durch die üblichen Verdächtigen von veränderbaren Datenmodellen bis zur verschluckten Ausnahme, und legen dabei Konventionen fest. Dieses Festlegen ist wichtiger, als es klingt: Was wir hier beschließen, schreiben wir am zweiten Tag auf.
0:51 Und zwar für einen Leser, der noch gar nicht im Raum ist — den Coding Agent. Vier Ziele. Wir lernen Lagerwerk kennen, und zwar gründlich genug, dass Sie sich später darin bewegen können. Wir wenden den Maßstab aus Modul 1 auf echten Bestandscode an — das ist etwas anderes, als ihn auf einer Folie zu lesen. Wir legen Konventionen fest, auf die wir am zweiten Tag den Agenten verpflichten. Und wir benennen, was einem Umbau strukturell im Weg steht.
1:18 Der letzte Punkt klingt defensiv, ist aber der wertvollste: Er verhindert, dass wir am dritten Tag gegen eine Wand laufen.
Das Projekt Lagerwerk kennenlernen
1:26 Beginnen wir mit einer Führung durch das Haus. Sie bekommen gleich ein Projekt in die Hand, das Sie nicht geschrieben haben — so wie im echten Leben. Nehmen Sie sich für dieses Kapitel bewusst Zeit. Wer das Projekt jetzt versteht, kommt in allen späteren Übungen deutlich schneller voran. Wer es überspringt, sucht am dritten Tag noch die Klasse, um die es gerade geht.
1:48 Lagerwerk verwaltet ein Lager: Artikel, Lagerplätze, Bewegungen, Inventuren. Fachlich ist das angenehm überschaubar — jeder versteht, was ein Zugang und ein Abgang sind. Technisch ist es dagegen ein realistisches Stück Software: über Jahre gewachsen, aufgeteilt in mehrere Maven-Module, und eben nicht einheitlich auf einem Java-Stand.
2:09 Genau diese Mischung brauchen wir. Ein sauberes Beispielprojekt würde in jeder Übung glänzen und uns nichts beibringen. Lagerwerk hat Ecken — und an diesen Ecken findet das Seminar statt. Diese Tabelle sieht harmlos aus und enthält das zentrale Problem des Projekts. Achten Sie auf die erste Zeile: Der Kern steht auf dem ältesten Stand.
2:30 Und auf die Fußzeile: Alle anderen Module hängen am Kern. Damit ist die Reihenfolge jeder Migration bereits festgelegt, und zwar nicht von uns, sondern von den Abhängigkeiten. Sie können die schöne, moderne API-Schicht nicht weiter hochziehen, solange der Kern darunter festhängt. Merken Sie sich diese Konstellation — im siebten Modul kartieren wir sie systematisch und leiten daraus den Migrationsplan ab.
2:54 Der erste Punkt klingt organisatorisch, ist aber didaktisch entscheidend: Ein gemeinsames Projekt macht Übungen vergleichbar. Wenn jeder an seinem eigenen Code arbeitet, hat am Ende jeder ein anderes Erlebnis und niemand kann vom anderen lernen. Der zweite Punkt ist der ehrlichere: Gemischte Stände sind der Normalfall. Ich habe selten ein gewachsenes Java-Haus gesehen, in dem alle Module dieselbe Version haben.
3:17 Wenn Ihr Projekt einheitlich ist — Glückwunsch, dann sind die Übungen für Sie einfacher als für die anderen. Fünf Schritte, und der vierte ist der eigentliche. Ein Fachobjekt einmal komplett zu verfolgen — von der Schnittstelle bis in die Datenbank — bringt mehr Verständnis als jedes Architekturdiagramm. Sie sehen dabei nicht nur, wo die Klassen liegen, sondern auch, wo Fachlogik sitzt, die eigentlich woanders hingehört.
3:42 Und dann Schritt fünf: Notieren Sie, was unklar geblieben ist. Das ist keine Fleißaufgabe zum Selbstzweck. Diese Liste ist im fünften Modul die Vorlage dafür, was ein Agent über das Projekt wissen muss. Der letzte Punkt ist der häufigste, und er trifft besonders die Guten: Wer sofort aufräumen will, verliert den Überblick.
4:02 Die Versuchung ist groß — man liest den Code, sieht drei Dinge, die man besser machen würde, und fängt an. Eine Stunde später weiß man mehr über drei Klassen und nichts über das Projekt. Widerstehen Sie dem heute. Aufgeräumt wird ab dem zweiten Kapitel, und zwar gezielt. Und der zweite Punkt zur Warnung: Die Modulnamen sagen erstaunlich wenig darüber, wer tatsächlich von wem abhängt.
Unveränderliche Datenmodelle
4:26 Damit zum ersten echten Umbau. Wir nehmen uns die Datenmodelle vor — genauer: die Tatsache, dass man sie überall ändern kann. Das ist eine der stillsten Fehlerquellen in gewachsenem Code, weil sie nie einen Fehler wirft. Sie sorgt nur dafür, dass niemand mehr sagen kann, welcher Wert wann gültig war. Und weil nichts abstürzt, steht so ein Problem auch auf keiner Prioritätenliste — bis jemand anfängt, einen Fehlerbericht zu untersuchen.
4:52 Stellen Sie sich einen Vertrag vor, den jeder unterwegs noch ändern kann. Sie prüfen ihn, geben ihn weiter, und drei Schreibtische später steht etwas anderes drin — ohne dass jemand böse Absichten hatte. Genau das passiert mit veränderbaren Objekten in einer Anwendung mit mehreren Schichten. Ein unveränderliches Objekt ist der ausgedruckte, unterschriebene Vertrag: Was geprüft wurde, bleibt geprüft.
5:15 Der eigentliche Gewinn liegt nicht in der Technik, sondern darin, dass Sie beim Lesen des Codes nicht mehr fragen müssen, wer hier noch dazwischenfunkt. Das Entscheidende an diesem Beispiel steht im Kommentar der letzten Zeile: aufgerufen an vierzehn Stellen. Die Klasse selbst ist harmlos, der Setter ist harmlos — was sie gefährlich macht, ist die Verteilung.
5:36 Wenn Sie nun einen Fehlerbericht bekommen, in dem ein Status falsch ist, haben Sie vierzehn Kandidaten und keine Reihenfolge. Und weil jeder dieser Aufrufe für sich genommen vernünftig aussieht, hilft auch das Lesen nicht weiter. Das ist der Punkt, an dem Unveränderlichkeit von einer Stilfrage zu einer Zeitersparnis wird.
5:54 Ich möchte den dritten Punkt herausgreifen, weil er im Alltag den größten Unterschied macht: Fehlersuche wird kürzer. Nicht weil weniger Fehler passieren — die passieren weiterhin —, sondern weil die Zahl der Verdächtigen sinkt. Wenn ein Wert nur an einer Stelle entstehen kann, müssen Sie auch nur eine Stelle ansehen. Der vierte Punkt ist der, den man erst beim Schreiben von Tests bemerkt: Unveränderliche Objekte brauchen keinen Aufbau, kein Präparieren, keinen Zustand.
6:21 Sie erzeugen sie und prüfen sie. Das macht Tests kürzer und lesbarer. Der letzte Punkt ist der wichtigste für diese Übung: Der Umbau strahlt weiter aus als gedacht. Sie nehmen einen Setter weg und stellen fest, dass an vier Stellen Objekte schrittweise befüllt werden — erst erzeugt, dann nach und nach ergänzt. Das lässt sich lösen, kostet aber Zeit, und deshalb sollten Sie die Reichweite vorher prüfen.
6:45 Und der zweite Punkt bleibt eine echte Einschränkung: Manche Frameworks erwarten einen leeren Konstruktor und Setter. Da hilft kein Prinzip, da hilft nur eine bewusste Entscheidung, wo die Grenze verläuft. Jetzt greifen Sie selbst ein. Suchen Sie sich eine Modellklasse in Lagerwerk und nehmen Sie ihr die Setter. Der Build muss danach grün sein — das ist die Pflicht.
7:08 Die Kür ist die Zahl, um die ich Sie bitte: Wie viele Aufrufstellen mussten Sie anfassen? Notieren Sie sie. Im sechsten Modul geben wir dieselbe Aufgabe einem Agenten, und dann vergleichen wir. Nicht um zu sehen, wer schneller ist, sondern um zu sehen, wer vollständiger war.
Fachliche Zustände sauber abbilden
7:25 Im dritten Kapitel geht es um eine Altlast, die praktisch jedes gewachsene Java-Projekt hat: fachliche Zustände als Zeichenketten. Das ist so verbreitet, dass es kaum noch auffällt. Zugleich ist es eine der wenigen Stellen, an denen ein moderner Umbau sofort und messbar Fehler verhindert. Deshalb lohnt es sich, hier genauer hinzusehen — auch wenn die Umstellung, wie wir gleich sehen werden, an den Rändern des Systems Sorgfalt verlangt.
7:50 In Lagerwerk ist der Bewegungsstatus eine Zeichenkette. Das ist bequem, solange man ihn hinschreibt, und unangenehm bei allem, was danach kommt. Jeder Vergleich ist ein Tippfehler-Risiko. Jede neue Ausprägung bedeutet eine Suche durch das gesamte Projekt — und die Suche findet nur, was gleich geschrieben ist. Der Vergleich, der es trifft: Sie haben einen Schlüsselbund, aber die Schlüssel sind nicht beschriftet, sondern jemand hat den Zweck jedes Mal neu auf einen Zettel geschrieben.
8:18 Manchmal mit Tippfehler. Achten Sie auf den Kommentar in der letzten Zeile — dort steht das eigentliche Problem. Wenn irgendwo im Projekt jemand den Status kleingeschrieben ablegt, läuft dieser Vergleich still am Ziel vorbei. Kein Fehler, keine Ausnahme, keine Warnung. Die Buchung wird einfach nicht verbucht, und irgendwann fragt jemand aus der Fachabteilung nach.
8:40 Das ist die teuerste Sorte Fehler: einer, der nichts kaputt macht, sondern nur das Falsche tut. Genau deshalb lohnt sich hier der Umbau, auch wenn er Aufwand bedeutet. Der vierte Punkt ist der, den man erst im Alltag zu schätzen lernt: Die Entwicklungsumgebung kann Verwendungen zuverlässig finden. Bei einer Zeichenkette müssen Sie über Textsuche gehen und hoffen, dass alle dieselbe Schreibweise benutzt haben.
9:04 Bei einem Typ fragen Sie das Werkzeug, und es antwortet vollständig. Das ist keine Kleinigkeit — es ist der Unterschied zwischen einer Änderung, die Sie sicher durchführen können, und einer, bei der Sie am Ende hoffen. Und Hoffnung ist in der Softwareentwicklung eine teure Strategie. Zwei dieser Punkte betreffen die Außenwelt, und sie sind der Grund, warum dieser Umbau nicht trivial ist.
9:27 In der Datenbank stehen die alten Zeichenketten, und sie müssen lesbar bleiben — Sie können nicht einfach die Repräsentation wechseln und hoffen, dass die Altdaten sich anpassen. Dasselbe gilt für Schnittstellen nach außen: Wer Ihre API nutzt, hat sich auf die heutigen Werte eingestellt. Der Umbau innen ist also erlaubt, die Grenzen müssen kompatibel bleiben. Das ist machbar, aber es gehört geplant und nicht nebenbei erledigt.
Streams sinnvoll einsetzen
9:52 Jetzt zu einem Thema, bei dem ich bewusst gegen den Strom schwimme. Streams gibt es seit Java 8 — sie sind also nichts Neues. Trotzdem gehören sie hierher, weil sie im Bestand so oft falsch eingesetzt werden. Und weil das Gegenbeispiel, bei dem die gute alte Schleife gewinnt, mindestens so lehrreich ist wie das Musterbeispiel.
10:11 Ein Stream beschreibt, was mit einer Sammlung geschehen soll, statt wie durchlaufen wird. Das Bild dazu: Sie sagen im Restaurant, was Sie essen möchten, statt in die Küche zu gehen und den Weg zum Herd zu beschreiben. Der Gewinn liegt in der Lesbarkeit. Und genau deshalb ist es so bemerkenswert, dass Streams so häufig für das Gegenteil sorgen.
10:30 Sobald zu viel in eine Kette gepackt wird, kippt der Vorteil — und Sie haben eine Zeile, die zwar elegant aussieht, die aber niemand mehr im Kopf durchspielen kann. Drei Schritte, jeder benannt: filtern, sortieren, einsammeln. Sie lesen diesen Code wie einen Satz, und das ist genau das Kriterium. Achten Sie auf die Methodenreferenz beim Filtern — dass die Bedingung einen fachlichen Namen hat, trägt hier mehr zur Verständlichkeit bei als der Stream selbst.
10:57 Die Fußzeile nennt eine Faustregel, die sich bewährt hat: drei Schritte sind die Obergrenze für gute Lesbarkeit. Wenn Sie beim vierten oder fünften ankommen, ist das kein Verbot — aber ein Hinweis, dass hier eine benannte Methode besser wäre. Der erste Punkt ist die eigentliche Begründung: Die fachliche Absicht steht vor der Mechanik.
11:17 Bei einer klassischen Schleife lesen Sie zuerst, wie durchlaufen wird, und erst danach, was dabei passiert. Beim Stream ist es umgekehrt. Für Code, den man häufiger liest als schreibt — und das ist praktisch jeder Code —, ist das ein echter Gewinn. Der vierte Punkt ist der praktische Nebeneffekt: Wenn sich die Anforderung ändert, betrifft das einen Schritt in der Kette, nicht die ganze Schleifenlogik.
11:40 Der zweite Punkt ist mein Favorit, weil er so verbreitet ist: Seiteneffekte im forEach. Da hat jemand die Schleife formal in einen Stream übersetzt, aber innen wird weiterhin eine Liste befüllt oder ein Zähler hochgezählt. Das ist eine getarnte Schleife — sie hat alle Nachteile beider Welten und keinen der Vorteile. Und der erste Punkt gilt ohne Einschränkung: Bei verschachtelten Streams über mehrere Ebenen gewinnt die Schleife.
12:04 Das ist kein Rückschritt, das ist eine bewusste Entscheidung für Lesbarkeit.
Fehlerbehandlung im Bestand
12:09 Im fünften Kapitel geht es um etwas, das selten in Architekturdiskussionen auftaucht und regelmäßig für die längsten Fehlersuchen sorgt: den Umgang mit Ausnahmen. Wir sehen uns an, was in Lagerwerk steht, und legen anschließend eine Konvention fest. Diese Konvention ist kein Selbstzweck — sie wandert im fünften Modul wörtlich in die Anweisungsdatei für den Agenten. Was wir hier beschließen, befolgt morgen also jemand anders.
12:35 In Lagerwerk finden sich alle Klassiker: leere Fangblöcke, generische Ausnahmen ohne Aussage, Fehlerbehandlung als Kontrollfluss. Jeder einzelne Fall ist damals wahrscheinlich begründet gewesen — jemand hatte es eilig, jemand wusste nicht, was tun. In Summe entsteht daraus ein Projekt, in dem niemand mehr weiß, ob ein ausbleibender Fehler bedeutet, dass alles gut ging.
12:57 Der Ausweg ist nicht, jede Stelle einzeln zu diskutieren, sondern eine Konvention festzulegen. Dann wird aus einer Geschmacksfrage eine Regel. Fünf Zeilen, und der Kommentar sagt alles: passiert selten. Vermutlich stimmte das sogar. Nur läuft dieser Bestandsabgleich nachts, und wenn er scheitert, merkt es niemand — bis bei der Inventur die Zahlen nicht stimmen und jemand anfängt, in einem Zeitraum von Wochen nach der Ursache zu suchen.
13:23 Das ist der Grund, warum ich diesen Block den teuersten des Projekts nenne. Er ist nicht falsch, er ist stumm. Und Stille ist bei nächtlichen Abläufen die schlechteste aller Rückmeldungen. Der erste Punkt ist die Kernaussage des Kapitels: Ein sichtbarer Fehler ist billiger als ein falsches Ergebnis. Das klingt selbstverständlich und widerspricht dem ersten Impuls — der lautet nämlich, das System möge bitte weiterlaufen.
13:48 Der vierte Punkt ist der, der uns morgen begegnet: Der Agent kann sich an eine geschriebene Regel halten. An eine ungeschriebene nicht. Wenn Sie also heute Nachmittag eine Konvention festlegen, ist das keine Bürokratie — es ist die Vorarbeit dafür, dass morgen jemand anders sie befolgen kann. Der dritte Punkt ist der, über den am wenigsten geredet wird: protokollieren und weiterwerfen. Für sich genommen wirkt beides vernünftig.
14:13 Zusammen führt es dazu, dass derselbe Fehler auf jeder Ebene einmal im Protokoll landet — und Sie im Ernstfall drei Einträge sehen und rätseln, ob es drei Fehler waren. Entscheiden Sie sich: entweder behandeln und protokollieren, oder weiterreichen und den Aufrufer entscheiden lassen. Und der letzte Punkt ist der bittere: Eine Konvention, die nirgends steht, ist keine Konvention. Sie ist eine Erinnerung.
Struktur und Testbarkeit
14:37 Im letzten Kapitel des Tages heben wir den Blick von den einzelnen Klassen auf den Zuschnitt des Projekts. Das ist zugleich die Brücke zum zweiten Tag. Denn hier gilt ein Satz, den ich Ihnen mitgeben möchte: Was für einen Menschen schwer zu überblicken ist, ist es für einen Agenten auch. Struktur ist keine Ästhetik — sie ist die Voraussetzung dafür, dass Werkzeuge helfen können.
14:59 Lagerwerk ist nach Schichten geschnitten: alle Dienste in einem Paket, alle Repositories in einem anderen. Das war jahrelang die übliche Empfehlung, und es hat eine unangenehme Folge. Eine fachliche Änderung — sagen wir, Buchungen bekommen ein neues Feld — berührt vier Pakete. Der Zusammenhang existiert nur im Kopf des Entwicklers.
15:18 Stellen Sie sich eine Werkstatt vor, in der alle Schrauben in einem Regal liegen, alle Muttern im nächsten, und für jede Reparatur laufen Sie durch die ganze Halle. Diese Tabelle stellt zwei Ordnungsprinzipien gegenüber, und beide haben ihre Berechtigung — es geht hier nicht um richtig und falsch. Interessant ist die letzte Zeile, und deshalb steht sie auch dort: Kontext für Leser wie Agent. Bei Schichten müssen Sie für eine fachliche Frage vier Ordner öffnen.
15:45 Bei einem fachlichen Zuschnitt einen. Am zweiten Tag, wenn wir Kontext für einen Agenten zusammenstellen, wird aus diesem Komfortthema plötzlich eine Kostenfrage — denn jeder unnötige Ordner im Kontext ist bezahlter Platz, der der eigentlichen Klasse fehlt. Der zweite Punkt ist die Verbindung zum Rest des Seminars: Testbare Klassen sind die Voraussetzung für jede sichere Migration. Wir kommen darauf im achten Modul ausführlich zurück.
16:11 Halten Sie jetzt schon fest, welche Klassen in Lagerwerk sich nur mit halbem Framework testen lassen — das sind genau die Stellen, an denen die Migration später unangenehm wird. Und der letzte Punkt ist der Satz von eben, jetzt als Einordnung: Ein Agent hat kein Vorwissen über Ihr Projekt. Er hat nur, was er sieht. Der erste Punkt ist eine Warnung an alle, die jetzt Lust auf Umbau bekommen haben: Paketstruktur umbauen als Selbstzweck lohnt sich nicht.
16:37 Solche Umbauten erzeugen riesige Änderungslisten, in denen jede echte Änderung untergeht. Machen Sie es, wenn Sie ohnehin an der Fachlichkeit arbeiten. Und der letzte Punkt ist ein bewusstes Bremsen: Große Umbauten ohne Testnetz sind zu diesem Zeitpunkt zu früh. Wir haben das Netz noch nicht. Das bauen wir im achten Modul — und danach ist der Umbau eine ganz andere Angelegenheit.
17:00 Damit endet der erste Tag. Sie kennen Lagerwerk — die Module, die Stände, die wichtigsten Altlasten. Sie haben Konventionen festgelegt für Datenmodelle, fachliche Zustände und den Umgang mit Fehlern. Sie wissen, wann ein Stream hilft und wann er schadet. Und Sie haben benannt, was einem Umbau strukturell im Weg steht. Morgen kommt ein Werkzeug dazu.
17:22 Und die Konventionen von heute werden zu dem, was dieses Werkzeug über Ihr Projekt weiß.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →