Refactoring Before/After Katalog
Refactoring wird greifbar, wenn man Ausgangscode und Zielcode nebeneinander sieht.
Before/AfterLegacyClean CodePattern
Vorgehen
- Ist-Verhalten messen.
- Tests um kritische Pfade legen.
- Fachlichen Slice wählen.
- Use Case extrahieren.
- Ports einführen.
- Adapter nacheinander ersetzen.
Monster Service
Vorher: Monster-Methode
public void createOrder(Map<String, Object> input) {
// schlecht: Validierung, SQL, SOAP, Statuslogik und Eventing in einer Methode
if (input.get("customer") == null) throw new RuntimeException("missing");
jdbc.update("insert into orders ...");
soapClient.reserveInvoice(input);
jms.send("ORDER_CREATED", input);
}
Nachher: Use Case mit klarer Boundary
public OrderId handle(PlaceOrderCommand command) {
return tx.required(() -> {
Order order = Order.place(command.customerId(), command.lines());
orders.save(order);
outbox.appendAll(order.pullEvents());
return order.id();
});
}
JDBC Spaghetti
SQL darf im Adapter bleiben, aber nicht die Domain-Sprache ersetzen. Repository-Methoden sollen fachlich lesbar sein.
Mapping
Manuelles Ad-hoc-Mapping quer durch Services erzeugt Fehler. MapStruct oder explizite Mapper bündeln die Übersetzung.
Exception Handling
| Vorher | Nachher |
|---|---|
| RuntimeException ohne Code | DomainError + HTTP Problem Detail |
| Stacktrace im Response | TraceId + maschinenlesbarer Fehlercode |
| Fehler verschlucken | Retry/DLQ/Audit nach Fehlerart |
Check
Ein Refactoring ist erst fertig, wenn Tests, Betriebsmetrik, Rollback-Plan und Dokumentation aktualisiert sind.