Modul 12 · Migration Deep Dive · Stufe 2 Java Core

Collections

Vector, Hashtable und Enumeration wird nachvollziehbar in generische Collections und unveränderliche Sichten überführt. Die Akte zeigt nicht nur das Ziel, sondern die tatsächlichen Dateien, APIs, Dependencies, Codebelege, Tests, Risiken und Cutover-Schritte.

Collection WrapperSnapshot
1 → 1Produktionsdateien
22 → 26Java-Zeilen
1 → 1Testdateien
0 / 0Dependencies entfernt / neu
NIEDRIGRisiko · Score 0

Was sich konkret ändert

DimensionLegacyModernMigrationskonsequenz
Programmiermodellimperativ / ohne Framework-Annotationenexplizite Java-AbstraktionenAnnotationen und Containerfunktionen werden nur dort eingesetzt, wo sie eine konkrete technische Verantwortung übernehmen.
Abhängigkeiten1 direkte Dependencies1 direkte Dependencies0 neu, 0 entfernt; Versionen und transitive Auswirkungen im erfolgreichen Online-Build prüfen.
Öffentliche API3 erkannte Methoden4 erkannte MethodenMethoden werden nach fachlicher Rolle gemappt; reine Bootstrap- und Framework-Methoden sind kein fachlicher Vertrag.
Datenmodellclass LegacyInventoryclass InventoryFeldnamen, IDs, Null-Semantik, Gleichheit und Serialisierungsform werden separat regressionstestet.
FehlerverhaltenLegacy-Exceptions und Rückgabewerteexplizitere Fach-/Framework-FehlerabbildungFehler dürfen nicht nur technisch übersetzt werden; Status, Ursache, Retrybarkeit und Client-Vertrag müssen erhalten oder versioniert werden.
TestsBestands- und Golden-Master-TestsUnit-, Slice-, Contract- und IntegrationstestsDer Modern-Pfad wird zuerst gegen denselben fachlichen Vektor geprüft und danach um neue technische Risiken ergänzt.
BetriebLegacy-Start/Lifecyclemodernes Packaging, Health und externe KonfigurationUmstellung über kleine Adapter und Golden-Master-Tests statt Big Bang.
RollbackLegacy-Artefakt bleibt unverändertModern-Artefakt getrennt deploybarKein Rollback über Datenverlust: Schema, Nachrichten und verschlüsselte Daten müssen rückwärtslesbar oder durch Dual-Read abgesichert sein.

Fachlicher Vertrag: unverändert zu erhalten

  • Reihenfolge, Duplikat- und Null-Semantik sind dokumentiert.
  • Aufrufer erhalten keine veränderbare interne Collection.
  • Iteration bleibt deterministisch, wenn fachlich erforderlich.

Hauptrisiko und Testfokus

mutation leaks and ordering semantics

aliasing, null, duplicates and ordering tests

Die Modernisierung gilt erst als abgeschlossen, wenn der fachliche Vertrag automatisiert belegt ist.

Verbindliches Code- und Rollenmapping

Die Zuordnung ist semantisch: Eine Legacy-Klasse kann in mehrere moderne Rollen zerlegt werden.

Legacy-Rolle / DateiModern-Rolle / DateiBedeutung
LegacyInventory.javaInventory.javaLegacy Collections werden generisch und defensiv gekapselt.

Legacy-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
LegacyInventory.javaclass LegacyInventoryvoid add(String sku, int quantity)
int quantity(String sku)
Vector<String> orderedSkus()
Collection Wrapper22

Modern-Quellinventar

DateiTypAnnotationenöffentliche APIPatternZeilen
Inventory.javaclass Inventoryvoid add(String sku, int quantity)
int quantity(String sku)
Map<String, Integer> snapshot()
List<String> orderedSkus()
Snapshot26

Dependency- und Laufzeitmigration

StatusDependencyVersionScopePrüfung
BEIBEHALTENorg.junit.jupiter:junit-jupiterBOM/Parent → BOM/Parenttest → testGemeinsame Dependency; Version und Scope im effektiven POM prüfen.
Direkte POM-Daten ersetzen keinen erfolgreichen Online-Build mit transitiver SBOM- und CVE-Prüfung.

Vorher-/Nachher-Codebelege

Die folgenden Ausschnitte stammen direkt aus den enthaltenen Projekten. Dadurch ist sichtbar, welche Verantwortung tatsächlich verschoben wurde.

Legacy
LegacyInventory.java
Modern
Inventory.java

Migrationsbedeutung: Legacy Collections werden generisch und defensiv gekapselt.

Legacy-Code

projects/12-collections/legacy/src/main/java/at/aydin/lab/collections/legacy/LegacyInventory.java

package at.aydin.lab.collections.legacy;

import java.util.*;

// Design Pattern: Collection Wrapper
// Zweck: Kapselt alte Vector-/Hashtable-Strukturen hinter fachlichen Methoden.
public final class LegacyInventory {
    private final Vector<String> order = new Vector<>();
    private final Hashtable<String, Integer> stock = new Hashtable<>();
    public void add(String sku, int quantity) {
        if (!stock.containsKey(sku)) order.add(sku);
        stock.put(sku, stock.getOrDefault(sku, 0) + quantity);
    }

    public int quantity(String sku) {
        return stock.getOrDefault(sku, 0);
    }

    public Vector<String> orderedSkus() {
        return new Vector<>(order);
    }
}

Modern-Code

projects/12-collections/modern/src/main/java/at/aydin/lab/collections/modern/Inventory.java

package at.aydin.lab.collections.modern;

import java.util.*;

// Design Pattern: Snapshot
// Zweck: Gibt unveränderliche Momentaufnahmen statt interner mutabler Collections zurück.
public final class Inventory {
    private final LinkedHashMap<String, Integer> stock = new LinkedHashMap<>();
    public void add(String sku, int quantity) {
        Objects.requireNonNull(sku);
        if (quantity <= 0) throw new IllegalArgumentException("quantity");
        stock.merge(sku, quantity, Integer::sum);
    }

    public int quantity(String sku) {
        return stock.getOrDefault(sku, 0);
    }

    public Map<String, Integer> snapshot() {
        return Collections.unmodifiableMap(new LinkedHashMap<>(stock));
    }

    public List<String> orderedSkus() {
        return List.copyOf(stock.sequencedKeySet());
    }
}
Technischen Unified Diff öffnen
--- LegacyInventory.java
+++ Inventory.java
@@ -1,22 +1,26 @@
-package at.aydin.lab.collections.legacy;
+package at.aydin.lab.collections.modern;
 
 import java.util.*;
 
-// Design Pattern: Collection Wrapper
-// Zweck: Kapselt alte Vector-/Hashtable-Strukturen hinter fachlichen Methoden.
-public final class LegacyInventory {
-    private final Vector<String> order = new Vector<>();
-    private final Hashtable<String, Integer> stock = new Hashtable<>();
+// Design Pattern: Snapshot
+// Zweck: Gibt unveränderliche Momentaufnahmen statt interner mutabler Collections zurück.
+public final class Inventory {
+    private final LinkedHashMap<String, Integer> stock = new LinkedHashMap<>();
     public void add(String sku, int quantity) {
-        if (!stock.containsKey(sku)) order.add(sku);
-        stock.put(sku, stock.getOrDefault(sku, 0) + quantity);
+        Objects.requireNonNull(sku);
+        if (quantity <= 0) throw new IllegalArgumentException("quantity");
+        stock.merge(sku, quantity, Integer::sum);
     }
 
     public int quantity(String sku) {
         return stock.getOrDefault(sku, 0);
     }
 
-    public Vector<String> orderedSkus() {
-        return new Vector<>(order);
+    public Map<String, Integer> snapshot() {
+        return Collections.unmodifiableMap(new LinkedHashMap<>(stock));
+    }
+
+    public List<String> orderedSkus() {
+        return List.copyOf(stock.sequencedKeySet());
     }
 }

Umsetzungsplan mit Qualitäts-Gates

  1. Arbeitspaket 1
    Verwendung von Vector, Hashtable und Enumeration erfassen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  2. Arbeitspaket 2
    Generische Typen einführen und Casts entfernen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  3. Arbeitspaket 3
    Inventory mit defensiven Kopien/Views implementieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  4. Arbeitspaket 4
    Nebenläufigkeitsannahmen explizit prüfen; Vector-Synchronisierung nicht blind verlieren. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  5. Arbeitspaket 5
    Alias-, Reihenfolge- und Duplicate-Tests ergänzen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.
  6. Arbeitspaket 6
    Legacy Wrapper nach Aufrufermigration entfernen. Nachweis: Commit/PR, automatisierter Test und aktualisierte Betriebsdokumentation.

Konkreter Test- und Abnahmekatalog

IDEbenePrüfungerforderlicher Nachweis
12-COLLECTIONS-A01Integration/ContractKeine Raw Types oder unchecked Casts im Modern-Code.Automatisierter Test und CI-Protokoll
12-COLLECTIONS-A02Integration/ContractExterne Änderungen beeinflussen internen Zustand nicht.Automatisierter Test und CI-Protokoll
12-COLLECTIONS-A03Integration/ContractReihenfolge und Duplikate entsprechen Vertrag.Automatisierter Test und CI-Protokoll
12-COLLECTIONS-A04Integration/ContractNull-Verhalten ist explizit.Automatisierter Test und CI-Protokoll
12-COLLECTIONS-A05Integration/ContractNebenläufige Zugriffe sind entweder sicher oder verboten/dokumentiert.Automatisierter Test und CI-Protokoll
12-COLLECTIONS-T01UnitFachlogik ohne Container oder externen Dienst testen.Unit-Test
12-COLLECTIONS-T02RegressionLegacy- und Modern-Ergebnis für denselben Golden-Master-Vektor vergleichen.Vergleichsreport
12-COLLECTIONS-T03NegativeFehlerhafte, leere und grenzwertige Eingaben prüfen.Negativtest
12-COLLECTIONS-T04OperationsStart, Health, Shutdown und Konfigurationsfehler prüfen.Deployment-/Startprotokoll
12-COLLECTIONS-F01Fokusaliasing, null, duplicates and ordering testsModulspezifischer Testreport

Risikoregister des Moduls

RisikoAuswirkungGegenmaßnahmeGate
mutation leaks and ordering semanticsNIEDRIGaliasing, null, duplicates and ordering testsvor Cutover

Konfiguration und Ressourcen

Keine zusätzlichen Ressourcen.

Rollback und Koexistenz

LegacyInventory kann intern auf Inventory delegieren oder über einen Collection-Adapter kompatibel gehalten werden.

Abbruchkriterien

  • Fachlicher Golden-Master weicht ab.
  • Daten-, Nachrichten- oder API-Kompatibilität ist ungeklärt.
  • Fehlerquote, Latenz oder Ressourcenverbrauch überschreiten das vereinbarte Limit.
  • Monitoring oder Rückfallpfad ist nicht funktionsfähig.

Definition of Done

Direkte Arbeitslinks

⌂ Cockpit