C# WinForms Refactoring — Ein tieferer Einblick mit Tim Corey
Refactoring ist eines jener Themen, das Code, der lediglich funktioniert, von Code trennt, der wartbar, flexibel und zukunftssicher ist. In Lektion 24 der "C# App From Start to Finish"-Serie geht Tim Corey durch eine reale, praktische Refactoring-Sitzung innerhalb einer WinForms-Anwendung. Anstatt Theorie zu erklären, refactort Tim ein bestehendes Projekt und erklärt, warum Änderungen erforderlich sind und wie man sie sicher angeht.
In diesem Artikel werden wir uns intensiv mit C# WinForms Refactoring befassen und strikt Tims Erklärungen aus dem Video folgen.
Was Refactoring in dieser Lektion bedeutet
Um 0:02 führt Tim Lektion 24 ein und erklärt, dass Refactoring bedeutet, Code so umzugestalten, dass er die gleiche Aufgabe erfüllt, aber auf eine bessere Weise. Er weist darauf hin, dass die Anwendung bereits funktioniert, aber "Müll" und Bereiche enthält, die nicht den Standards entsprechen. Laut Tim ist jetzt der richtige Zeitpunkt, um Dinge zu bereinigen, bevor das Projekt weiter wächst.
Er betont, dass Refactoring nicht darum geht, Funktionen hinzuzufügen – es geht darum, Struktur, Lesbarkeit und langfristige Wartbarkeit zu verbessern und gleichzeitig das Verhalten gleich zu halten.
Bereinigen von unnötigen Rückgabewerten in Schnittstellen
Ab 0:31 taucht Tim in den ersten Refactor ein: das Reparieren der Methodensignaturen in Schnittstellen. Er erklärt, dass früh im Projekt Methoden unnötigerweise Modelle zurückgegeben haben. Da Objekte bereits per Referenz übergeben werden, dient das einmalige Zurückgeben desselben Modells keinem wirklichen Zweck.
Tim zeigt, wie man diese Methoden zu void ändert, was sofort die Implementierungen bricht. Er erklärt, warum dies passiert: Wenn sich eine Schnittstelle ändert, müssen alle implementierenden Klassen die neue Signatur genau übernehmen. Er geht durch die Reparatur des SQL-Konnektors und Textkonnektors, um der aktualisierten Schnittstelle zu entsprechen.
Um 2:33 pausiert Tim, um zu zeigen, was passiert, wenn man Visual Studio das automatische Implementieren der Schnittstelle durchführen lässt. Er erklärt, warum doppelte Methodennamen auftreten und stellt klar, dass alleinige Rückgabetypen nicht ausreichen, um Methodensignaturen zu unterscheiden.
Baufehler durch Refactoring beheben
Um 4:00 baut Tim die Lösung und zeigt absichtlich die auftretenden Fehler. Er erklärt, dass diese Fehler erwartet und hilfreich sind. Zum Beispiel schlägt Code, der zuvor ein zurückgegebenes Modell erwartete, nun fehl, weil die Methode void zurückgibt.
Tim behebt dies, indem er unnötige Zuordnungen entfernt und die Lösung erneut erstellt. Er betont, dass Refactoring oft kurzfristige Unterbrechungen verursacht, aber jeder Fehler direkt auf Code hinweist, der verbessert werden muss.
Verschieben von Dateinamenkonstanten in GlobalConfig
Ab 5:25 refactort Tim, wie Dateinamen im Textkonnektor behandelt werden. Bisher wurden Dateipfade als private String-Konstanten innerhalb der Klasse gespeichert. Tim erklärt, dass diese nicht mehr benötigt werden, da Dateinamen bereits in GlobalConfig existieren.
Er ersetzt lokale Konstanten durch GlobalConfig.PeopleFile, GlobalConfig.PrizesFile und ähnliche Eigenschaften. Tim erklärt, dass diese Änderung die Konfiguration zentralisiert und sicherstellt, dass die gesamte Anwendung konsistente Dateipfade verwendet.
Er macht auch einen wichtigen Punkt: vermeiden Sie es, zu viele Dinge auf einmal zu refactorn. Als er zusätzliche Verbesserungen bemerkt, die vorgenommen werden könnten, sagt er ausdrücklich, dass er später darauf zurückkommen wird.
Refactoring des Text Connector Processors
Um 7:44 fährt Tim mit dem Refactor fort, indem er die Dateinamenparameter aus mehreren Methoden im Textkonnektor-Processor entfernt. Da Dateinamen jetzt in GlobalConfig leben, ist es redundant, sie weiterzureichen.
Tim aktualisiert sorgfältig die Methodensignaturen, ersetzt Parameter durch GlobalConfig-Referenzen und verlässt sich auf die Fehlerliste von Visual Studio, um ihn zu leiten. Er erklärt, dass es normal ist, viele Fehler auf einmal zu sehen, während man refaktoriert, und dass das kein Grund zur Panik ist.
Um 13:16 bemerkt er, wie hilfreich die Echtzeit-Fehlerverfolgung beim systematischen Bereinigen von Methodenaufrufen im gesamten Projekt ist.
Erkennen von UI-Logik, die zu viel tut
Um 15:24 hebt Tim ein großes Designproblem hervor: zu viel Logik in einem UI-Ereignis-Handler. Er scrollt durch ein Button-Klick-Ereignis und erklärt, dass es weit mehr Code enthält, als ein Ereignis haben sollte. In Windows Forms werden Benutzeraktionen wie Button-Klicks von Ereignis-Handlern bearbeitet, die die spezifische Aktion definieren, die ausgeführt werden soll, wenn das Ereignis eintritt.
Tim erklärt, dass sich der UI-Code nur auf Benutzerinteraktion konzentrieren sollte. Windows Forms verwendet ein ereignisgesteuertes Programmiermodell, bei dem Benutzeraktionen Ereignisse auslösen, die von Anwendungs-Code gehandhabt werden. Geschäftslogik - wie das Bewerten von Turnieren und das Vorankommen von Gewinnern - gehört in eine Klassenbibliothek. Diese Trennung ermöglicht es, dieselbe Logik später in einer Web-App oder WPF-Anwendung wiederzuverwenden.
Herauslösen der Turnierlogik in die Klassenbibliothek
Beginnend um 17:55 verschiebt Tim die Turnierbewertungslogik in eine neue öffentliche Methode innerhalb der Turnierlogik-Klasse. Er nennt sie UpdateTournamentResults und erklärt, warum sie das gesamte Turniermodell und nicht nur ein einzelnes Matchup akzeptiert.
Er kopiert die Logik aus dem Formular, fügt sie in die Klassenbibliothek ein und passt sie an, um unabhängig von UI-Elementen zu arbeiten. Diese Refaktorisierung stellt sicher, dass die Turnierregeln an einem Ort leben und überall wiederverwendet werden können.
Bewertung von Matchups und korrektes Behandeln von Freilosen
Um 21:37 refakturiert Tim, wie Matchups bewertet werden. Anstatt mit einem einzelnen Matchup zu arbeiten, geht er alle Runden und alle Matchups in einer Schleife durch und erstellt eine Liste von Matchups, die bewertet werden müssen.
Er erklärt die Logik zum Erkennen abgeschlossener Spiele und Freilose. Tim weist darauf hin, dass Freilose zuvor in einer "hacky" Weise behandelt wurden, indem falsche Punktzahlen zugewiesen wurden. Die Refaktorisierung ermöglicht, Freilose explizit und sauber zu behandeln.
Extrahieren der Bewertung in private Methoden
Um 28:17 extrahiert Tim die Bewertungslogik in eine private Methode. Er erklärt, dass kleinere, fokussierte Methoden den Code leichter verständlich und wartbar machen.
Er benennt auch Methoden um, um besser zu reflektieren, was sie tun, wie z. B. das Ändern der Bewertungslogik in etwas, das klar "Gewinner in Matchups markieren" bezeichnet.
Konfigurierbare Gewinnerermittlung
Ab 29:58 refakturiert Tim die Logik zur Gewinnerermittlung, sodass sie sowohl Szenarien mit "High-Score-wins" als auch "Low-Score-wins" verarbeiten kann. Er führt eine neue Anwendungseinstellung ein und erklärt, warum Konfiguration besser ist als fest codierte Regeln.
Tim diskutiert alternative Designs, einschließlich der Speicherung dieses Wertes im Turniermodell, erklärt jedoch, warum diese Änderung außerhalb des Umfangs dieser Lektion liegt.
Gewinner voranbringen und Ergebnisse speichern
Um 45:40 geht Tim weiter, um Gewinner in die nächste Runde voranzubringen. Er erklärt, wie Gewinner mit Eltern-Matchups abgeglichen werden und warum das Speichern von Daten zur richtigen Zeit entscheidend ist.
Später, um 52:10 herum, demonstriert er einen prägnanten ForEach-Ansatz zum Aktualisieren von Matchups und erklärt, wie er funktional einem traditionellen Loop entspricht, aber kompakter ist.
Beheben von Fehlern, die durch Refaktorisierung eingeführt wurden
Um 58:33 entdeckt Tim falsche Daten in der Datenbank und verfolgt das Problem zurück zum Aufruf der Logik, bevor das Turnier gespeichert wurde. Er erklärt, dass Refaktorisierung manchmal versteckte Fehler aufdeckt, anstatt neue zu schaffen.
Indem er die Aktualisierungslogik zur richtigen Stelle verschiebt - nach der Persistenz - löst Tim das Problem und testet die Anwendung erneut.
Abschließende Gedanken zur Refaktorisierung
Um 1:09:00 fasst Tim zusammen, was die Refaktorisierung in dieser Lektion erreicht hat. Er erklärt, dass es bei der Refaktorisierung nicht nur um einen saubereren Code geht. Es geht auch darum, Randfälle zu behandeln, Designfehler zu beheben und auf zukünftige Änderungen vorzubereiten.
Er betont, dass die Refaktorisierung ein fortlaufender Prozess ist und weist darauf hin, dass die nächste Lektion sich auf die Fehlerbehandlung konzentrieren wird.
Abschließende Notiz
Diese Lektion zeigt die Refaktorisierung genau so, wie sie in realen Projekten passiert: inkrementell, manchmal chaotisch, aber letztendlich lohnend. Indem Sie Tim Coreys schrittweisem Ansatz folgen, erhalten Sie einen praktischen Plan zur Verbesserung von WinForms-Anwendungen, ohne die Funktionalität zu zerstören - und ohne zu raten, was als nächstes zu tun ist.
