{"id":329,"date":"2026-09-05T18:23:21","date_gmt":"2026-09-05T18:23:21","guid":{"rendered":"https:\/\/www.fabricioruch.ch\/?p=329"},"modified":"2026-09-05T18:23:21","modified_gmt":"2026-09-05T18:23:21","slug":"warum-der-zwoelfte-patch-kein-refactoring-ersetzt","status":"publish","type":"post","link":"https:\/\/www.fabricioruch.ch\/?p=329","title":{"rendered":"Warum der zw\u00f6lfte Patch kein Refactoring ersetzt"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Software wird selten auf einen Schlag unwartbar.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Meist passiert es schleichend.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein kleiner Fehler taucht auf.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Man behebt ihn.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Danach entsteht ein Sonderfall.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Auch der wird behoben.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dann ein weiterer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dann noch einer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Jeder einzelne Patch ist f\u00fcr sich betrachtet nachvollziehbar.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Und trotzdem wird das System mit jedem Schritt schwieriger zu verstehen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Gef\u00e4hrliche daran:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Lokale Korrektheit kann globale Verschlechterung erzeugen.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Genau deshalb ist nicht jeder weitere Fix automatisch die richtige Entscheidung.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Manchmal ist der n\u00e4chste Patch nur noch ein Symptom daf\u00fcr, dass die bestehende Struktur ihre Grenze erreicht hat.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Der erste Patch ist fast immer richtig<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Am Anfang ist das v\u00f6llig normal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Skript funktioniert nicht sauber mit Paging.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also erg\u00e4nzt man Paging.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein API-Call wird gelegentlich gedrosselt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also erg\u00e4nzt man Retry.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Unicode wird falsch dargestellt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also korrigiert man Encoding.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Progressbar-Index wird falsch berechnet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also korrigiert man die Formel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das sind sinnvolle \u00c4nderungen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Niemand sollte f\u00fcr jeden kleinen Bug sofort ein Refactoring starten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Problematisch wird es erst dann, wenn sich ein Muster bildet.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Das Muster hinter zu vielen Patches<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein typischer Verlauf sieht so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Bug\n\u2193\nlokaler Fix\n\u2193\nneuer Seiteneffekt\n\u2193\nlokaler Fix\n\u2193\nneue Sonderbedingung\n\u2193\nlokaler Fix\n\u2193\nnoch ein Sonderfall\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Irgendwann entsteht so etwas:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if ($x) {\n    ...\n}\nelseif ($y -and -not $z) {\n    ...\n}\nelseif ($retry -and $resume -and -not $quiet) {\n    ...\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann folgt vielleicht:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if ($null -ne $value) {\n    ...\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">und sp\u00e4ter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if ($propertyExists) {\n    ...\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">und irgendwann:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if ($isInteractive -and -not $NoAnimation -and $phase -eq 'Processing') {\n    ...\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Jede einzelne Bedingung kann berechtigt sein.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Problem ist nicht eine bestimmte <code>if<\/code>-Abfrage.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Problem ist, dass die Struktur immer mehr Sonderwissen aufnehmen muss.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Der entscheidende Punkt: Wechselwirkungen<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Technische Schuld zeigt sich oft nicht zuerst durch schlechten Code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sie zeigt sich durch <strong>Wechselwirkungen<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Eine \u00c4nderung an der Darstellung beeinflusst pl\u00f6tzlich die Logik.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Retry ver\u00e4ndert den Fortschrittsz\u00e4hler.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Checkpoint beeinflusst Resume.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Resume beeinflusst Verifikation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verifikation beeinflusst den Completion Screen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der Completion Screen greift wiederum auf Werte zu, die nur in bestimmten Codepfaden gesetzt wurden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pl\u00f6tzlich h\u00e4ngt alles an allem.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist ein sehr wichtiges Warnsignal.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Ein Bug ist nicht immer lokal<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Angenommen, eine Anwendung zeigt nach erfolgreicher Verarbeitung einen Fehler im finalen Screen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Technisch ist die Gesch\u00e4ftsoperation bereits erfolgreich abgeschlossen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der Fehler liegt nur in der Darstellung.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein schneller Fix k\u00f6nnte sein:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if ($null -ne $VerifiedRemaining) {\n    ...\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das behebt den Fehler.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber vielleicht zeigt der Bug etwas Gr\u00f6\u00dferes:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Warum kennt der Completion Screen \u00fcberhaupt Rohdaten aus der Verifikationslogik?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Vielleicht fehlt ein sauber definiertes Result-Objekt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$result = &#91;pscustomobject]@{\n    Status      = 'Completed'\n    Processed   = 56\n    Failed      = 0\n    Remaining   = 0\n    Verified    = $true\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann m\u00fcsste der Screen nicht mehr wissen, woher diese Werte kommen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist der Unterschied zwischen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Bug beheben\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">und:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Abstraktion korrigieren\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Symptome versus Ursache<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Patch reagiert h\u00e4ufig auf ein Symptom.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Refactoring reagiert auf die Ursache.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Symptom:\nUI flackert\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Patch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>weniger Clear-Host\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Neues Symptom:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>alte Zeilen bleiben stehen\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Patch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mehr manuelles Clearing\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Neues Symptom:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Transitions sehen falsch aus\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Patch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Sonderbehandlung f\u00fcr Zustandswechsel\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Irgendwann erkennt man:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Das Problem ist nicht <code>Clear-Host<\/code>.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Das Problem ist, dass kein Rendering-Modell existiert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dann ist die richtige L\u00f6sung:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>State Transition\n\u2192 Full Redraw\n\nSame State\n\u2192 In-place Redraw\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist Refactoring.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Refactoring ver\u00e4ndert die Struktur, nicht das Verhalten<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Das klassische Ziel von Refactoring ist:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Struktur verbessern, Verhalten erhalten.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Das bedeutet:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vorher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Input A\n\u2192 Output B\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nachher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Input A\n\u2192 Output B\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Aber intern ist der Code klarer aufgebaut.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel vorher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function Invoke-Tool {\n    Connect-Service\n    Get-Data\n    Process-Data\n    Save-Checkpoint\n    Render-Screen\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nachher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Orchestrator\n\u251c\u2500\u2500 API\n\u251c\u2500\u2500 Processing\n\u251c\u2500\u2500 Checkpoint\n\u251c\u2500\u2500 State\n\u2514\u2500\u2500 UI\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das sichtbare Verhalten bleibt gleich.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber \u00c4nderungen lassen sich k\u00fcnftig isolierter durchf\u00fchren.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Der Unterschied zwischen Patch und Refactoring<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Patch beantwortet:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Wie behebe ich diesen Fehler?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Refactoring beantwortet:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Warum konnte dieser Fehler hier \u00fcberhaupt entstehen?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist eine andere Ebene.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Fehler:\nFailed messages werden im Checkpoint als verarbeitet gespeichert.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Patch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if ($success) {\n    Add-ToCheckpoint\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das kann funktionieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber die tiefere Frage lautet:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Warum bekommt die Checkpoint-Funktion \u00fcberhaupt eine unscharfe Menge &#8222;Messages&#8220;?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Vielleicht sollte die Batch-Funktion stattdessen explizit liefern:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SucceededIds\nFailedIds\nRetryIds\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann wird die Checkpoint-Semantik klar.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist strukturell st\u00e4rker.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Fehler zeigen fehlende Abstraktionen<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Viele Bugs sind Hinweise darauf, dass ein Konzept im Code nicht sauber modelliert ist.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Paging Bug\n\u2192 fehlende zentrale Paging-Abstraktion\n\nResume Bug\n\u2192 unsauberes Zustandsmodell\n\nCompletion Bug\n\u2192 unsauberes Result-Modell\n\nTUI Flicker\n\u2192 fehlendes Rendering-Modell\n\nRetry Chaos\n\u2192 fehlende Fehlerklassifikation\n\nQuiet Mode Chaos\n\u2192 UI zu stark gekoppelt\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist eine n\u00fctzliche Denkweise:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Nicht nur fragen, welche Zeile falsch ist, sondern welches Konzept fehlt.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Wann sollte man noch patchen?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Nicht jeder Bug verlangt Refactoring.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Patchen ist v\u00f6llig sinnvoll, wenn:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ursache lokal ist<\/li>\n\n\n\n<li>keine neue Kopplung entsteht<\/li>\n\n\n\n<li>Verhalten klar bleibt<\/li>\n\n\n\n<li>keine neuen Sonderf\u00e4lle eingef\u00fchrt werden<\/li>\n\n\n\n<li>Struktur weiterhin verst\u00e4ndlich ist<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$index = &#91;Math]::Floor($value)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">statt einer falschen Berechnung.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist einfach ein Bugfix.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kein Architekturproblem.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Wann wird Refactoring wahrscheinlicher?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Refactoring ist angezeigt, wenn mehrere dieser Symptome auftreten:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>derselbe Zustand wird an mehreren Orten verwaltet<\/li>\n\n\n\n<li>mehrere Funktionen greifen auf globale Variablen zu<\/li>\n\n\n\n<li>neue Features ben\u00f6tigen immer neue Sonderbedingungen<\/li>\n\n\n\n<li>UI und Gesch\u00e4ftslogik beeinflussen sich gegenseitig<\/li>\n\n\n\n<li>Fehlerbehandlung ist \u00fcber den ganzen Code verteilt<\/li>\n\n\n\n<li>Tests ben\u00f6tigen gro\u00dfe Teile des Programms gleichzeitig<\/li>\n\n\n\n<li>derselbe Codepfad verh\u00e4lt sich je nach Modus v\u00f6llig anders<\/li>\n\n\n\n<li>\u00c4nderungen in einer Datei brechen unerwartet andere Bereiche<\/li>\n\n\n\n<li>Funktionen kennen mehr Kontext, als sie eigentlich brauchen<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Das sind strukturelle Probleme.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Der zw\u00f6lfte Patch ist kein magischer Wert<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Nat\u00fcrlich gibt es keine echte Regel:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Nach elf Patches muss refactored werden.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Der Titel ist bewusst zugespitzt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der Punkt ist:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn sich Fehler zunehmend <strong>zwischen bestehenden L\u00f6sungen<\/strong> bilden, ist das ein starkes Signal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Patch A behebt Paging.\nPatch B behebt Retry.\nPatch C behebt Resume.\n\nNeuer Bug:\nResume + Retry + Paging erzeugt falschen Zustand.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Jetzt liegt das Problem nicht mehr in einem einzelnen Feature.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Es liegt in deren Zusammenspiel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist der Moment, in dem weitere lokale Fixes teuer werden.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Technische Schuld ist Zins<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein bekanntes Bild f\u00fcr technische Schuld ist finanzielle Schuld.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein schneller Fix spart heute Zeit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Daf\u00fcr entstehen sp\u00e4ter Kosten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein bisschen Schuld ist v\u00f6llig normal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Manchmal sogar sinnvoll.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Heute:\nschnelle L\u00f6sung\n\nSp\u00e4ter:\nRefactoring\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Problematisch wird es, wenn der \u201eZins\u201c steigt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das merkt man daran, dass jede kleine \u00c4nderung immer mehr Aufwand verursacht.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Die \u00c4nderungssteuer ist ein gutes Ma\u00df<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Man kann technische Schuld sehr pragmatisch messen:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Wie teuer ist eine kleine \u00c4nderung?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn f\u00fcr eine kleine Funktion:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ein weiterer Statuswert anzeigen\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">pl\u00f6tzlich \u00c4nderungen n\u00f6tig sind in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>API\nState\nUI\nCheckpoint\nQuiet Output\nTests\nCompletion\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">dann ist die Kopplung hoch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein gutes Design versucht, die \u00c4nderungsfl\u00e4che klein zu halten.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Shotgun Surgery<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein klassischer Begriff daf\u00fcr ist <strong>Shotgun Surgery<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Eine kleine fachliche \u00c4nderung zwingt zu \u00c4nderungen an vielen Stellen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Neuer Status: Retrying\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">muss pl\u00f6tzlich erg\u00e4nzt werden in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Orchestrator\nUI\nLogging\nJSON\nCheckpoint\nAnimation\nTests\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das kann manchmal berechtigt sein.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber wenn es regelm\u00e4\u00dfig passiert, fehlt oft eine zentrale Abstraktion.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Divergent Change<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Das Gegenst\u00fcck ist <strong>Divergent Change<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Eine einzelne Datei muss aus v\u00f6llig unterschiedlichen Gr\u00fcnden ge\u00e4ndert werden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Main.ps1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u00e4ndert sich wegen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>API-Version<\/li>\n\n\n\n<li>UI-Design<\/li>\n\n\n\n<li>Retry-Verhalten<\/li>\n\n\n\n<li>Checkpoint-Format<\/li>\n\n\n\n<li>neue CLI-Parameter<\/li>\n\n\n\n<li>Verification<\/li>\n\n\n\n<li>JSON-Ausgabe<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Dann hat die Datei zu viele Verantwortlichkeiten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist ein starker Hinweis auf notwendige Trennung.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Refactoring ist Risikoreduktion<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Refactoring wird manchmal als Sch\u00f6nheitsarbeit betrachtet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist zu kurz gedacht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gutes Refactoring reduziert zuk\u00fcnftige Risiken.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vorher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>UI liest direkt API-Daten\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nachher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>API\n\u2193\nResult Object\n\u2193\nUI\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit reduziert man die Wahrscheinlichkeit, dass eine API-\u00c4nderung direkt den Renderer bricht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist kein kosmetischer Nutzen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist Risikomanagement.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Refactoring schafft Grenzen<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Eine gute Architektur besteht zu einem gro\u00dfen Teil aus Grenzen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>API Boundary\nState Boundary\nPersistence Boundary\nUI Boundary\nOutput Boundary\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Innerhalb einer Grenze darf sich Implementierung \u00e4ndern.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Andere Bereiche sollten davon m\u00f6glichst wenig merken.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Graph API\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">kann intern andere Paging-Logik bekommen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die UI sollte davon nichts wissen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn sie trotzdem angepasst werden muss, ist die Grenze schwach.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Gute Grenzen reduzieren den Radius eines Bugs<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist vielleicht der praktischste Vorteil.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn ein Bug in:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Graph.ps1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">liegt, sollte er m\u00f6glichst dort bleiben.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn ein UI-Bug sofort Checkpoint oder Verarbeitung beeinflusst, fehlt Isolation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Man spricht auch vom <strong>Blast Radius<\/strong> einer \u00c4nderung.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gute Architektur versucht, diesen Radius klein zu halten.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Nicht jedes Refactoring muss gro\u00df sein<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Refactoring bedeutet nicht automatisch:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>alles neu schreiben\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das w\u00e4re oft sogar gef\u00e4hrlicher.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gutes Refactoring kann sehr klein sein.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Step 1:\nPaging in eigene Funktion verschieben\n\nStep 2:\nResult-Objekt einf\u00fchren\n\nStep 3:\nUI aus Processing l\u00f6sen\n\nStep 4:\nCheckpoint isolieren\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Schrittweise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mit laufenden Tests.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ohne Big Bang.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Rewrite und Refactoring sind nicht dasselbe<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Rewrite bedeutet:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Wir werfen gro\u00dfe Teile weg und bauen neu.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Refactoring bedeutet:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Wir verbessern die Struktur des bestehenden Systems.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Rewrite ist verf\u00fchrerisch.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der alte Code wirkt schlecht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der neue Code beginnt sauber.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber ein Rewrite verliert oft implizites Wissen, das im alten Code steckt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Sonderf\u00e4lle<\/li>\n\n\n\n<li>API-Eigenheiten<\/li>\n\n\n\n<li>Fehlerf\u00e4lle<\/li>\n\n\n\n<li>Verhalten in realen Umgebungen<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Deshalb ist gezieltes Refactoring h\u00e4ufig sicherer.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Tests machen Refactoring m\u00f6glich<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ohne Tests ist Refactoring riskanter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Denn wenn Verhalten erhalten bleiben soll, muss man feststellen k\u00f6nnen, ob es sich ver\u00e4ndert hat.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein gutes Testset schafft Vertrauen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Paging\nBatching\nRetry\nCheckpoint\nResume\nVerification\nQuiet Output\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann kann man intern umbauen und pr\u00fcfen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Verhalten gleich?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn ja:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Refactoring erfolgreich.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Aber Tests k\u00f6nnen schlechte Architektur konservieren<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Auch das passiert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein gro\u00dfes Skript kann sehr viele Tests besitzen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Trotzdem bleibt es schlecht strukturiert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dann testen die Tests vielleicht Implementation statt Verhalten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Funktion X muss Funktion Y genau zweimal aufrufen.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann wird jede interne \u00c4nderung teuer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Besser ist oft:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Input\n\u2192 erwartetes Resultat\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Tests sollten Refactoring erm\u00f6glichen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nicht verhindern.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Ein gutes Result-Modell verhindert viele Patches<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein klassisches Beispiel ist die R\u00fcckgabe von Funktionen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Schlecht:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>return $true\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Was bedeutet <code>true<\/code>?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Request erfolgreich?\nAlle Items erfolgreich?\nVerifiziert?\nKeine Fehler?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Besser:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;pscustomobject]@{\n    Attempted = 20\n    Succeeded = 18\n    Failed    = 1\n    Retrying  = 1\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Noch besser, wenn Resume relevant ist:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;pscustomobject]@{\n    SucceededIds = @(...)\n    FailedIds    = @(...)\n    RetryIds     = @(...)\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Eine pr\u00e4zisere Datenstruktur beseitigt oft ganze Klassen sp\u00e4terer Patches.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Pr\u00e4zise Semantik ist Architektur<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Architektur klingt oft abstrakt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber manchmal besteht sie einfach darin, Begriffe sauber zu definieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zum Beispiel:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>processed\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Was bedeutet das?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>gesehen?\nversucht?\nerfolgreich ver\u00e4ndert?\nverifiziert?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn diese Bedeutung nicht klar ist, entstehen sp\u00e4ter Fehler.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Deshalb sind Namen wie:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Attempted\nSucceeded\nFailed\nRemaining\nVerified\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">st\u00e4rker.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gute Architektur beginnt oft bei pr\u00e4ziser Sprache.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Refactoring sollte Verhalten vereinfachen<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein guter Umbau reduziert nicht nur Code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Er reduziert Denkaufwand.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vorher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Wenn Quiet und nicht Audit und Resume,\naber nur falls Verification aktiviert...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nachher:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>RunMode\nRenderMode\nVerificationMode\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">oder klar getrennte Pfade.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Ziel ist nicht m\u00f6glichst wenig Code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Ziel ist m\u00f6glichst wenig mentale Zustandskombinationen.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Komplexit\u00e4t verschwindet nicht durch Aufteilen<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein wichtiger Gegenpunkt:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mehr Dateien allein sind noch kein Refactoring.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Main.ps1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">einfach wird:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Part1.ps1\nPart2.ps1\nPart3.ps1\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">aber alle weiterhin auf dieselben globalen Variablen zugreifen, wurde kaum etwas gewonnen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Physische Trennung ist nicht dasselbe wie logische Trennung.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Frage lautet immer:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Sind Verantwortlichkeiten wirklich isoliert?<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Module sind kein Selbstzweck<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Das Gleiche gilt f\u00fcr Module.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Modul kann sauber strukturiert sein.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Oder einfach eine gro\u00dfe Datei hinter einem anderen Dateinamen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Ziel sollte sein:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Public API\nPrivate Implementation\nklarer State\nklare Datenfl\u00fcsse\ngeringe Kopplung\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nicht:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>m\u00f6glichst viele Dateien\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Der richtige Zeitpunkt ist vor dem Schmerzpunkt<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Viele Teams refactoren erst, wenn:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Niemand will diesen Code mehr anfassen.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann ist es teuer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Besser ist fr\u00fcher.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein gutes Signal:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Die dritte \u00e4hnliche Sonderl\u00f6sung taucht auf.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Beispiel:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Erster Modus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Normal\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Audit\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Quiet\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Resume\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn jeder Modus neue <code>if<\/code>-Bl\u00f6cke quer durch den Code zieht, sollte man fr\u00fch ein Modusmodell oder klare Schichten einf\u00fchren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nicht erst beim zehnten Modus.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Rule of Three<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Eine bekannte Heuristik lautet:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Beim ersten Mal einfach machen.<br>Beim zweiten Mal beobachten.<br>Beim dritten Mal abstrahieren.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist keine harte Regel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber sie verhindert zwei Extreme:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>zu fr\u00fche Abstraktion\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">und:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>endloses Copy-Paste\/Patching\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Gerade bei kleinen Tools ist das sehr hilfreich.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Architektur sollte der tats\u00e4chlichen Komplexit\u00e4t folgen<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Ein kleines Skript braucht kein Domain-Driven Design.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Eine einmalige Datenmigration braucht vielleicht keine State Machine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Tool mit:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>API\nRetry\nResume\nCheckpoint\nTUI\nVerification\nQuiet Mode\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">braucht dagegen mehr Struktur.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Architektur sollte mit dem Problem wachsen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nicht davor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Aber auch nicht zehn Schritte dahinter.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Ein praktischer Refactoring-Check<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn ich heute ein gewachsenes Skript analysiere, w\u00fcrde ich diese Fragen stellen:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">1. Welche Verantwortlichkeiten existieren?<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>API\nState\nUI\nPersistence\nOutput\nError Handling\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2. Welche davon sind vermischt?<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">3. Welche Variable wird von vielen Bereichen ver\u00e4ndert?<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">4. Welche \u00c4nderung betrifft unerwartet viele Dateien oder Funktionen?<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">5. Welche Fehler treten nur durch Kombination mehrerer Features auf?<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">6. Welche Sonderf\u00e4lle wiederholen sich?<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\">7. Welche Funktion kennt Dinge, die sie eigentlich nicht kennen m\u00fcsste?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Diese Fragen zeigen meist ziemlich schnell, wo Refactoring sinnvoll ist.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Der wichtigste Indikator: Erkl\u00e4rbarkeit<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Eine \u00fcberraschend gute Messgr\u00f6\u00dfe ist:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Kann ich den Ablauf in wenigen S\u00e4tzen erkl\u00e4ren?<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn die Erkl\u00e4rung lautet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Wir verbinden uns,\nlesen Daten,\nbauen eine Work Queue,\nverarbeiten sie in Batches,\nspeichern erfolgreiche IDs,\nverifizieren den Endzustand.\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ist das gut.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn sie lautet:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Also zuerst ruft das Main Script Funktion A auf,\nau\u00dfer bei Quiet,\ndann setzt Funktion B eine Script-Variable,\ndie Funktion C sp\u00e4ter liest,\naber nur wenn Resume nicht aktiv ist...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">dann beschreibt man nicht mehr das System.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Man beschreibt seine Zuf\u00e4lligkeiten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das ist ein starkes Warnsignal.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Der beste Refactoring-Effekt<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Der beste Effekt eines guten Refactorings ist nicht:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>weniger Zeilen\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Es ist:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>weniger \u00dcberraschungen\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Eine \u00c4nderung an Retry ver\u00e4ndert nicht pl\u00f6tzlich das UI.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Eine \u00c4nderung am UI ver\u00e4ndert nicht den Checkpoint.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Eine \u00c4nderung am Checkpoint ver\u00e4ndert nicht die API.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das System wird vorhersehbarer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Und Vorhersehbarkeit ist ein zentraler Wert in Software Engineering.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Was wir aus kleinen Tools lernen k\u00f6nnen<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Interessanterweise sind kleine Skripte perfekte Lernobjekte.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Architekturprobleme sind dieselben wie bei gro\u00dfen Systemen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nur kleiner.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Man sieht sehr deutlich:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>globale Zust\u00e4nde\nenge Kopplung\nunklare Verantwortlichkeiten\nfehlende Fehlersemantik\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Bei einem gro\u00dfen Enterprise-System verschwinden diese Probleme oft hinter Frameworks und Infrastruktur.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bei einem 2&#8217;000-Zeilen-PowerShell-Tool liegen sie offen da.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das macht solche Projekte erstaunlich lehrreich.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Der eigentliche Fehler ist nicht der Patch<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Patches sind notwendig.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Softwareentwicklung besteht zu einem gro\u00dfen Teil aus Ver\u00e4nderungen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Das Problem ist nur:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Ein Patch sollte nicht automatisch die Default-Antwort auf jedes neue Problem sein.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Manchmal sollte die Frage lauten:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Wo ist der Bug?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Manchmal aber:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Warum ist dieser Bug \u00fcberhaupt m\u00f6glich?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Und manchmal sogar:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Welche Abstraktion fehlt uns?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Das sind unterschiedliche Ebenen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Gute Softwareentwicklung erkennt, wann man die Ebene wechseln muss.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Fazit<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Der zw\u00f6lfte Patch ist nicht falsch, weil zw\u00f6lf eine magische Zahl w\u00e4re.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Er ist ein Symbol.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Symbol f\u00fcr den Moment, in dem ein System bereits so viele lokale Korrekturen tr\u00e4gt, dass neue Fehler zunehmend aus deren Wechselwirkungen entstehen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dann reicht es nicht mehr, nur die n\u00e4chste Zeile zu korrigieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Man muss die Struktur betrachten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die entscheidenden Fragen lauten dann:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Welche Verantwortung ist hier vermischt?\nWelcher Zustand ist implizit?\nWelche Datenstruktur ist zu unscharf?\nWelche Grenze fehlt?\nWelche \u00c4nderung hat einen zu gro\u00dfen Blast Radius?\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Refactoring ist genau daf\u00fcr da.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nicht um Code sch\u00f6ner aussehen zu lassen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sondern um die Struktur wieder an die tats\u00e4chliche Komplexit\u00e4t anzupassen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die wichtigste Erkenntnis lautet deshalb:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Wenn Fehler zunehmend aus den L\u00f6sungen fr\u00fcherer Fehler entstehen, ist der n\u00e4chste Patch wahrscheinlich nicht mehr die richtige Abstraktionsebene.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Dann ist es Zeit, nicht nur den Fehler zu beheben.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sondern das System wieder verst\u00e4ndlich zu machen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Software wird selten auf einen Schlag unwartbar. Meist passiert es schleichend. Ein kleiner Fehler taucht auf. Man behebt ihn. Danach entsteht ein Sonderfall. Auch der wird behoben. Dann ein weiterer. Dann noch einer. Jeder einzelne Patch ist f\u00fcr sich betrachtet nachvollziehbar. Und trotzdem wird das System mit jedem Schritt schwieriger zu verstehen. Das Gef\u00e4hrliche daran: [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":337,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[60,27,8,25,59],"tags":[],"class_list":["post-329","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-automation","category-programming-principles","category-software-architecture","category-software-engineering","category-system-engineering"],"_links":{"self":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/329","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=329"}],"version-history":[{"count":1,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/329\/revisions"}],"predecessor-version":[{"id":330,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/posts\/329\/revisions\/330"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=\/wp\/v2\/media\/337"}],"wp:attachment":[{"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=329"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=329"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fabricioruch.ch\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=329"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}