Ich habe meine Gedanken zu statischen Klassen in einem früheren Thread geschrieben :
Früher liebte ich Utility-Klassen, die mit statischen Methoden gefüllt waren. Sie haben eine große Konsolidierung von Hilfsmethoden vorgenommen, die sonst Redundanz und Wartungsaufwand verursachen würden. Sie sind sehr einfach zu bedienen, keine Instantiierung, keine Entsorgung, nur Feuer und Vergessen. Ich denke, dies war mein erster unbeabsichtigter Versuch, eine serviceorientierte Architektur zu schaffen - viele zustandslose Services, die nur ihren Job gemacht haben und sonst nichts. Während ein System wächst, kommen jedoch Drachen.
Polymorphismus
Nehmen wir an, wir haben die Methode UtilityClass.SomeMethod, die glücklich mitschwirrt. Plötzlich müssen wir die Funktionalität etwas ändern. Der größte Teil der Funktionalität ist derselbe, aber wir müssen trotzdem einige Teile ändern. Wäre es keine statische Methode gewesen, könnten wir eine Derivate-Klasse erstellen und den Methodeninhalt nach Bedarf ändern. Da es eine statische Methode ist, können wir nicht. Klar, wenn wir nur Funktionalität vor oder nach der alten Methode hinzufügen müssen, können wir eine neue Klasse erstellen und die alte in ihr aufrufen - aber das ist nur eklatant.
Schnittstellenprobleme
Statische Methoden können aus logischen Gründen nicht über Schnittstellen definiert werden. Und da wir statische Methoden nicht überschreiben können, sind statische Klassen nutzlos, wenn wir sie über ihre Schnittstelle weitergeben müssen. Dies macht es uns unmöglich, statische Klassen als Teil eines Strategiemusters zu verwenden. Wir können einige Probleme beheben, indem wir Delegaten anstelle von Schnittstellen übergeben.
Testen
Dies geht im Wesentlichen mit den oben erwähnten Problemen der Benutzeroberfläche einher. Da wir nur sehr eingeschränkte Möglichkeiten haben, Implementierungen auszutauschen, können wir auch den Produktionscode nicht durch Testcode ersetzen. Wir können sie wieder einpacken, müssen jedoch große Teile unseres Codes ändern, um Wrapper anstelle der eigentlichen Objekte akzeptieren zu können.
Fördert Blobs
Da statische Methoden in der Regel als Dienstprogrammmethoden verwendet werden und Dienstprogrammmethoden in der Regel unterschiedliche Zwecke haben, erhalten wir schnell eine große Klasse mit nicht kohärenter Funktionalität - im Idealfall sollte jede Klasse einen einzigen Zweck innerhalb des Systems haben. Ich hätte viel lieber eine fünffache Klasse, solange ihre Ziele klar definiert sind.
Parameter Kriechen
Zunächst könnte diese kleine nette und unschuldige statische Methode einen einzigen Parameter annehmen. Mit zunehmender Funktionalität werden einige neue Parameter hinzugefügt. Bald werden weitere Parameter hinzugefügt, die optional sind, sodass wir Überladungen der Methode erstellen (oder einfach Standardwerte in Sprachen hinzufügen, die diese unterstützen). In Kürze haben wir eine Methode, die 10 Parameter akzeptiert. Nur die ersten drei sind wirklich erforderlich, Parameter 4-7 sind optional. Wenn jedoch Parameter 6 angegeben wird, müssen auch 7-9 ausgefüllt werden. Hätten wir eine Klasse mit dem einzigen Zweck erstellt, das zu tun, was diese statische Methode getan hat, könnten wir dies lösen, indem wir die erforderlichen Parameter in das Feld eingeben Der Benutzer kann optionale Werte über Eigenschaften oder Methoden festlegen, um mehrere voneinander abhängige Werte gleichzeitig festzulegen. Ebenfalls,
Fordern Sie die Konsumenten auf, ohne Grund eine Instanz von Klassen zu erstellen
Eines der häufigsten Argumente ist, warum von Verbrauchern unserer Klasse verlangt wird, eine Instanz zum Aufrufen dieser einzelnen Methode zu erstellen, ohne die Instanz danach zu verwenden. Das Erstellen einer Instanz einer Klasse ist in den meisten Sprachen eine sehr, sehr kostengünstige Operation, daher ist Geschwindigkeit kein Problem. Das Hinzufügen einer zusätzlichen Codezeile für den Verbraucher ist mit geringen Kosten verbunden, um den Grundstein für eine in Zukunft viel wartbarere Lösung zu legen. Wenn Sie keine Instanzen erstellen möchten, erstellen Sie einfach einen Singleton-Wrapper für Ihre Klasse, der eine einfache Wiederverwendung ermöglicht. Dies setzt jedoch voraus, dass Ihre Klasse statusfrei ist. Wenn es nicht zustandslos ist, können Sie dennoch statische Wrapper-Methoden erstellen, die alles verarbeiten und Ihnen auf lange Sicht dennoch alle Vorteile bieten. Endlich,
Nur ein Sith handelt absolut
Natürlich gibt es Ausnahmen von meiner Abneigung gegen statische Methoden. Echte Utility-Klassen, die kein Aufblähungsrisiko darstellen, eignen sich hervorragend für statische Methoden - am Beispiel von System.Convert. Wenn es sich bei Ihrem Projekt um ein Einzelprojekt handelt, für das keine zukünftigen Wartungsarbeiten erforderlich sind, spielt die Gesamtarchitektur keine große Rolle - statisch oder nicht statisch, spielt jedoch keine Rolle - die Entwicklungsgeschwindigkeit.
Standards, Standards, Standards!
Die Verwendung von Instanzmethoden hindert Sie nicht daran, auch statische Methoden zu verwenden und umgekehrt. Solange die Unterscheidung begründet und standardisiert ist. Es gibt nichts Schlimmeres, als einen Blick auf eine Business-Schicht zu werfen, die sich über verschiedene Implementierungsmethoden erstreckt.