Ich habe festgestellt, dass fast jedes Mal, wenn ich Programmierer sehe, die statische Klassen in objektorientierten Sprachen wie C # verwenden, sie es falsch machen. Die Hauptprobleme sind offensichtlich der globale Zustand und die Schwierigkeit, Implementierungen zur Laufzeit oder mit Mocks / Stubs während der Tests auszutauschen.
Aus Neugier habe ich mir einige meiner Projekte angesehen und diejenigen ausgewählt, die gut getestet sind, und als ich mich bemühte, tatsächlich über Architektur und Design nachzudenken. Die zwei Verwendungen von statischen Klassen, die ich gefunden habe, sind:
Die Utility-Klasse - etwas, das ich lieber vermeiden würde, wenn ich diesen Code heute schreiben würde.
Der Anwendungscache: Die Verwendung einer statischen Klasse ist eindeutig falsch. Was ist, wenn ich es durch
MemoryCache
oder Redis ersetzen möchte ?
In .NET Framework sehe ich auch kein Beispiel für eine gültige Verwendung statischer Klassen. Zum Beispiel:
File
Die statische Klasse macht es wirklich schmerzhaft, zu Alternativen zu wechseln. Was ist beispielsweise, wenn Sie zu Isolated Storage wechseln oder Dateien direkt im Speicher speichern müssen oder einen Anbieter benötigen, der NTFS-Transaktionen unterstützt oder zumindest Pfade mit mehr als 259 Zeichen verarbeiten kann ? Nachdem eine gemeinsame Schnittstelle und mehrere Implementierungen erscheint so einfach wie mitFile
direkt, mit dem Vorteil nicht die meisten der Code - Basis , wenn Anforderungen ändern neu schreiben zu müssen.Console
Die statische Klasse macht das Testen zu kompliziert. Wie soll ich innerhalb eines Komponententests sicherstellen, dass eine Methode korrekte Daten an die Konsole ausgibt? Sollte ich die Methode ändern, um die Ausgabe an eine beschreibbare Datei zu senden, die zurStream
Laufzeit eingefügt wird? Es scheint, dass eine nicht statische Konsolenklasse wieder so einfach wie eine statische wäre, nur ohne alle Nachteile einer statischen Klasse.Math
Die statische Klasse ist auch kein guter Kandidat. Was ist, wenn ich auf Arithmetik mit beliebiger Genauigkeit umschalten muss? Oder zu einer neueren, schnelleren Implementierung? Oder zu einem Stub, der während eines Unit-Tests feststellt, dass eine bestimmte Methode einerMath
Klasse tatsächlich während eines Tests aufgerufen wurde?
Auf Programmer.SE habe ich gelesen:
Verwenden Sie nicht "statisch" in C #? Einige Antworten sind ziemlich gegen statische Klassen. Andere behaupten, dass „statische Methoden in Ordnung sind und einen rechtmäßigen Platz in der Programmierung haben.“, Backen sie jedoch nicht mit Argumenten.
Wann ein Singleton und wann eine statische Klasse verwendet werden soll . Dienstprogrammklassen werden erwähnt, da ich oben erwähnt habe, dass Dienstprogrammklassen problematisch sind.
Warum und wann sollte ich eine Klasse "statisch" machen? Was ist der Zweck des Schlüsselworts "statisch" für Klassen? Die einzige gültige Verwendung, die erwähnt wird, ist ein Container für Erweiterungsmethoden. Großartig.
Was sind neben den Erweiterungsmethoden die gültigen Verwendungszwecke statischer Klassen, dh Fälle, in denen Abhängigkeitsinjektion oder Singletons entweder unmöglich sind oder zu einem Design mit geringerer Qualität und einer schwierigeren Erweiterbarkeit und Wartung führen?
instanceof
), weil es in zwei Fällen IFoo
keine Garantie gibt, dass sie von derselben Klasse unterstützt werden.
YAGNI
, und akzeptieren , dass , wenn Sie jemals eine andere Art von String benötigen, Sie erhalten nur Ihre IDE jede Instanz zu ändern , com.lang.lib.String
um com.someones.elses.String
in der gesamten Codebasis.