Ich reichte einen Antrag ein, den ich an einige andere Architekten zur Codeüberprüfung schrieb. Einer von ihnen schrieb mir fast sofort zurück und sagte: "Verwenden Sie nicht" statisch ". Sie können keine automatisierten Tests mit statischen Klassen und Methoden schreiben." Statisch "ist zu vermeiden."
Ich habe geprüft, und 1/4 meiner Klassen sind mit "statisch" gekennzeichnet. Ich verwende static, wenn ich keine Instanz einer Klasse erstellen möchte, da die Klasse eine einzelne globale Klasse ist, die im gesamten Code verwendet wird.
Er fuhr fort, etwas zu erwähnen, das Spott, IOC / DI-Techniken beinhaltet, die mit statischem Code nicht verwendet werden können. Er sagt, es sei bedauerlich, wenn Bibliotheken von Drittanbietern aufgrund ihrer Unprüfbarkeit statisch sind.
Ist dieser andere Architekt richtig?
Update: Hier ist ein Beispiel:
APIManager - In dieser Klasse werden Wörterbücher von Drittanbieter-APIs gespeichert, die ich zum nächsten zulässigen Zeitpunkt aufrufe. Es erzwingt API-Nutzungsbeschränkungen, die viele Drittanbieter in ihren Nutzungsbedingungen haben. Ich benutze es überall dort, wo ich einen Drittanbieter-Dienst anrufe, indem ich Thread.Sleep (APIManager.GetWait ("ProviderXYZ")) aufrufe. bevor Sie den Anruf tätigen. Alles hier ist threadsicher und es funktioniert hervorragend mit der TPL in C #.
quelle
static
ist gut;static
Felder müssen sehr sorgfältig behandelt werdenAntworten:
Es hängt davon ab, ob die statischen Klassen den Status beibehalten oder nicht. Persönlich habe ich kein Problem mit statusfreien Funktionen, die in einer statischen Klasse zusammengefasst sind.
quelle
Er ist zu allgemein. Er hat recht, es behindert das Testen. Allerdings
static
Klassen und Methoden haben ihren Platz und es hängt wirklich vom Kontext ab . Ohne Codebeispiele kann man das nicht wirklich sagen.Dies kann ein schwerer Codegeruch sein. Wofür benutzt du die Klassen? Daten speichern? Auf eine Datenbank zugreifen? Dann ist er richtig. In diesem Fall sollten Sie die Abhängigkeitsinjektion berücksichtigen, da eine solche statische Klasse praktisch ein impliziter Singleton ist.
Wenn Sie sie für Erweiterungsmethoden oder Hilfsprogramme verwenden, die den Status nicht ändern und nur die von Ihnen angegebenen Parameter verwenden, sind diese in der Regel in Ordnung.
quelle
Das Beste, was Sie tun können, ist, Ihren Code zu testen und zu testen. Versuchen Sie, wiederholbare, unabhängige und einfache Tests zu entwerfen, und testen Sie jeweils nur eine Methode. Versuchen Sie, Ihre Tests in einer anderen zufälligen Reihenfolge durchzuführen. Kannst du einen stabilen "grünen" Build bekommen?
Wenn ja, ist dies ein gültiger Punkt, um Ihren Code zu verteidigen. Wenn Sie jedoch Schwierigkeiten haben, sollten Sie sich für instanzbasierte Methoden entscheiden.
quelle
Die bereits geposteten Antworten decken viele wirklich gute Punkte ab, aber es gibt einen, der zu fehlen scheint:
Statische Felder werden niemals über den Müll gesammelt.
Dies ist sehr wichtig, wenn Sie eine App mit vielen Speicherbeschränkungen haben. Dieses Muster kann sehr häufig auftreten, wenn Benutzer versuchen, einen Cache zu implementieren.
Statische Funktionen sind bei weitem nicht so schlecht, aber alle anderen haben dies bereits ausführlich genug behandelt.
quelle
Einer der Vorteile von IoC / DI besteht darin, dass die meisten Interaktionen zwischen Klassen zwischen Schnittstellen ausgehandelt werden. Dies erleichtert das Testen von Einheiten, da die Schnittstellen automatisch oder halbautomatisch nachgeahmt werden können und daher jedes der Teile auf Ein- und Ausgänge getestet werden kann. Über die Testbarkeit hinaus können Sie durch das Einfügen von Schnittstellen den modularsten Code erhalten - Sie können problemlos eine Implementierung ersetzen, ohne sich Sorgen machen zu müssen, dass Sie Abhängigkeiten vermasseln.
Da in C # keine Metaklassen vorhanden sind, kann eine Klasse keine Schnittstelle mit statischen Features implementieren, sodass statische Features von Klassen keine Anstrengungen unternehmen, um ein reines IoC / DI-Objektmodell zu implementieren. Das heißt, Sie können kein Mock erstellen, um sie zu testen, und Sie müssen echte Abhängigkeiten erstellen.
Wenn Ihr Unternehmen / Projekt stark in die Durchführung von IoC investiert ist, ist dies natürlich ein vernünftiges Anliegen, und der Schmerz, den Sie durchmachen, ist für den Gewinn aller. Vom architektonischen Standpunkt aus glaube ich jedoch nicht, dass man einem Modell bis ins Grab folgen sollte. Es gibt einige Dinge, die für die Implementierung mit statischen Methoden sinnvoll sind, z. B. die Singleton-Entwurfsstrategie. Ich selbst neige weniger zu statischen Klassen, weil ich glaube, dass sie die Vorteile von OO allmählich verlieren, aber manchmal ist eine Bibliotheksklasse wahrscheinlich ein natürlicherer Ausdruck von etwas als einer Engine.
Commenter erinnert mich an Erweiterungsmethoden, die sich in C # natürlich in statischen Klassen befinden müssen. Das ist legitim und ein Beispiel dafür, dass reines IoC in C # nicht besonders gut funktioniert, zumindest wenn Sie versuchen, die Breite der Sprache auszunutzen.
quelle
Statische Klassen werden manchmal missbraucht und sollten sein:
Es kann sich auch um eine sogenannte Utility-Funktion handeln, die Teil einer Utility-Klasse ist. Utility-Klassen sind Klassen, die nur statische Methoden enthalten und als Hilfsfunktionen ohne Kontext dienen.
quelle
Statische Methoden sind in Ordnung und haben einen angemessenen Platz in der Programmierung. Es hört sich so an, als ob Ihr Architekt über ein Test-Framework verfügt, das statische Methoden nicht vollständig unterstützt. Wenn Ihr Code Teil eines größeren Projekts ist, ist es wichtig, die Architektenrichtlinien einzuhalten. Lassen Sie sich jedoch von diesem Projekt nicht davon abhalten, statische Methoden zu verwenden, wenn dies angemessen ist.
quelle
Ich habe statische Eigenschaften für Dinge verwendet, die allen Instanzen einer Klasse gemeinsam sind. Und ich habe statische Methoden verwendet, um Gruppen von Klassenobjekten zu erhalten. Ich bin kein Experte, aber das hat bisher für mich funktioniert.
PHP Beispiel:
quelle
Ich sage, die Prinzipien, die sie haben, sind in Ordnung, aber die Aussage (verwenden Sie keine Statik) kann falsch sein. Wie hoch ist Ihre Codeabdeckung? Wenn die Anzahl hoch ist und Sie mit dem Komponententest Ihrer App vertraut sind, sind Sie in Ordnung. Wenn nicht, würde ich vorschlagen, den Code zu überprüfen. Sie können feststellen, dass statische Klassen der Grund sind oder nicht, es wird von vielen Dingen abhängen.
quelle
Klassen mit statischen Methoden missbrauchen die Prinzipien von OOP. Es ist noch kein OOP, es ist COP - Klassenorientierte Programmierung.
Sie haben selten eine klare "Persönlichkeit" (ich verwende meine menschliche Lieblingsmetapher) hier) oder Identität. Sie wissen also nicht, wer sie sind. Dieser Punkt allein reicht aus, um dieses Konzept in OOP loszuwerden, aber es gibt noch mehr davon.
Der nächste ist eine Konsequenz des ersten Punktes. Da solche Klassen nicht wissen, wer sie sind, tendieren sie dazu, von groß bis riesig zu sein.
Dritte macht Ihren Code absolut nicht wartbar. Die Verwendung statischer Methoden führt zu versteckten Abhängigkeiten . Sie tauchen überall auf und Sie wissen nie, was in Ihrer Klasse passiert. Sie können sich nicht sicher sein, wenn Sie sich nur die Konstruktorsignatur ansehen.
Langsam, aber unvermeidlich, wird Ihr Code immer weniger zusammenhängend, da versteckte Abhängigkeiten schlecht kontrolliert werden. Sie scheinen unsichtbar zu sein. Und es ist so einfach, einen weiteren hinzuzufügen! Sie müssen die Signatur einer Methode nicht ändern. Sie müssen lediglich eine statische Methode aufrufen. Und was für ein hässlicher Code folgt ...
Ok, du hast es wahrscheinlich schon erraten. Eine enge Kopplung ist häufig mit einer geringen Kohäsion verbunden. Wenn viele Clients eine Klasse verwenden, wird die Kopplung enger. Und es ist eine große Verführung, eine bereits geschriebene Klasse oder Methode zu verwenden, die nur eine winzige Korrektur erfordert. Nur ein Methodenflag-Parameter.
Was anstelle von statischen Methoden verwenden? Nun, mein Vorschlag ist OOP. Warum nicht mal ausprobieren?
quelle