722 Stimmen

Warum werden statische Variablen als böse angesehen?

Ich bin ein Java-Programmierer, der neu in der Unternehmenswelt ist. Vor kurzem habe ich eine Anwendung entwickelt, die Groovy und Java. Der gesamte von mir geschriebene Code enthielt eine ganze Reihe von statischen Elementen. Ich wurde von den leitenden Technikern gebeten, die Anzahl der verwendeten statischen Elemente zu verringern. Ich habe darüber gegoogelt und festgestellt, dass viele Programmierer ziemlich gegen die Verwendung statischer Variablen sind.

Ich finde statische Variablen bequemer zu verwenden. Und ich nehme an, dass sie auch effizient sind (bitte korrigieren Sie mich, wenn ich falsch liege), denn wenn ich eine Funktion innerhalb einer Klasse 10.000 Mal aufrufen müsste, wäre ich froh, wenn ich die Methode statisch machen und ein einfaches Class.methodCall() zu verwenden, anstatt den Speicher mit 10.000 Instanzen der Klasse zu überladen, richtig?

Außerdem reduziert die Statik die Abhängigkeiten von anderen Teilen des Codes. Sie können als perfekte Zustandshalter fungieren. Darüber hinaus finde ich, dass Statik in einigen Sprachen wie Smalltalk y Scala . Warum also ist dieser Widerstand gegen die Statik unter Programmierern weit verbreitet (insbesondere in der Java-Welt)?

PS: Bitte korrigieren Sie mich, wenn meine Annahmen zur Statik falsch sind.

4voto

studgeek Punkte 13264

Meine $.02 ist, dass mehrere dieser Antworten sind verwirrend das Problem, anstatt zu sagen, "Statik sind schlecht" Ich denke, seine besser, über Scoping und Instanzen zu sprechen.

Ich würde sagen, dass eine statische Variable eine "Klassenvariable" ist - sie repräsentiert einen Wert, der von allen Instanzen dieser Klasse gemeinsam genutzt wird. Typischerweise sollte sie auch auf diese Weise skaliert werden (geschützt oder privat für die Klasse und ihre Instanzen).

Wenn Sie vorhaben, ein Verhalten auf Klassenebene zu implementieren und es anderen Codes zugänglich zu machen, dann ist ein Singleton möglicherweise die bessere Lösung, um Änderungen in der Zukunft zu unterstützen (wie @Jessica vorgeschlagen hat). Der Grund dafür ist, dass Sie Schnittstellen auf der Instanz-/Singleton-Ebene auf eine Art und Weise verwenden können, die Sie auf der Klassenebene nicht nutzen können - insbesondere die Vererbung.

Einige Gedanken dazu, warum ich denke, dass einige der Aspekte in anderen Antworten nicht zum Kern der Frage gehören...

Statiken sind nicht "global". In Java wird das Scoping getrennt von Statik/Instanz gesteuert.

Die Gleichzeitigkeit ist für statische Methoden nicht weniger gefährlich als für Instanzmethoden. Es ist immer noch ein Zustand, der geschützt werden muss. Sicher, Sie können 1000 Instanzen mit je einer Instanzvariable und nur eine statische Variable haben, aber wenn der Code, der auf eine der beiden Variablen zugreift, nicht thread-sicher geschrieben ist, sind Sie trotzdem aufgeschmissen - es kann nur etwas länger dauern, bis Sie es merken.

Die Verwaltung des Lebenszyklus ist ein interessantes Argument, aber ich denke, es ist weniger wichtig. Ich sehe nicht, warum es schwieriger sein sollte, ein Paar Klassenmethoden wie init()/clear() zu verwalten als die Erstellung und Zerstörung einer Singleton-Instanz. Man könnte sogar sagen, dass ein Singleton aufgrund von GC ein wenig komplizierter ist.

PS: In Bezug auf Smalltalk haben viele seiner Dialekte Klassenvariablen, aber in Smalltalk sind Klassen eigentlich Instanzen von Metaklassen, so dass sie wirklich Variablen der Metaklasseninstanz sind. Trotzdem würde ich die gleiche Faustregel anwenden. Wenn sie für einen gemeinsamen Zustand über Instanzen hinweg verwendet werden, dann ist das in Ordnung. Wenn sie öffentliche Funktionalität unterstützen, sollten Sie ein Singleton in Betracht ziehen. Seufz, ich vermisse wirklich Smalltalk....

4voto

Bryan Agee Punkte 4646

Das Thema "Statik ist böse" ist eher ein Thema des globalen Staates. Eine Variable ist dann statisch, wenn sie nie mehr als einen Zustand hat; IE-Tools, auf die das gesamte Framework zugreifen kann und die für dieselben Methodenaufrufe immer dieselben Ergebnisse liefern, sind als statische Variablen nie "böse". Zu Ihrem Kommentar:

Ich finde statische Variablen bequemer zu verwenden. Und ich nehme an, dass sie auch effizient sind

Statik ist die ideale und effiziente Wahl für Variablen/Klassen, die sich nie ändern .

Das Problem mit dem globalen Status ist die inhärente Inkonsistenz, die dadurch entstehen kann. In der Dokumentation über Unit-Tests wird dieses Problem oft angesprochen, da jedes Mal, wenn es einen globalen Zustand gibt, auf den mehr als nur mehrere nicht miteinander verbundene Objekte zugreifen können, Ihre Unit-Tests unvollständig und nicht "unit"-gerecht sein werden. Wie bereits in diesem Artikel über globaler Zustand und Singletons Wenn die Objekte A und B nicht miteinander verbunden sind (d. h. wenn das eine Objekt nicht ausdrücklich auf das andere verweist), dann sollte A den Zustand von B nicht beeinflussen können.

Es gibt einige Ausnahmen vom Verbot des globalen Zustands in gutem Code, wie zum Beispiel die Uhr. Die Zeit ist global, und - in gewissem Sinne - ändert sie den Zustand von Objekten, ohne dass eine kodierte Beziehung besteht.

4voto

Cygnusx1 Punkte 5191

Ich finde statische Variablen bequemer zu verwenden. Und ich nehme an, dass sie auch effizient sind (bitte korrigieren Sie mich, wenn ich falsch liege), denn wenn ich 10.000 Aufrufe einer Funktion innerhalb einer Klasse machen müsste, wäre ich froh, die Methode statisch zu machen und eine einfache class.methodCall() dafür zu verwenden, anstatt den Speicher mit 10.000 Instanzen der Klasse zu überladen, richtig?

Ich verstehe, was Sie denken, aber ein einfaches Singleton-Muster wird das Gleiche tun, ohne 10 000 Objekte instanziieren zu müssen.

statische Methoden können verwendet werden, aber nur für Funktionen, die sich auf die Objektdomäne beziehen und keine internen Eigenschaften des Objekts benötigen oder verwenden.

ex:

public class WaterContainer {
    private int size;
    private int brand;
    ...etc

    public static int convertToGallon(int liters)...

    public static int convertToLiters(int gallon)...

}

3voto

user unknown Punkte 33856

a) Begründen Sie die Programme.

Wenn man ein kleines bis mittelgroßes Programm hat, in dem auf die statische Variable Global.foo zugegriffen wird, kommt der Aufruf normalerweise aus dem Nichts - es gibt keinen Pfad und damit keine Zeitleiste, wie die Variable an den Ort kommt, an dem sie verwendet wird. Woher weiß ich nun, wer sie auf ihren tatsächlichen Wert gesetzt hat? Woher weiß ich, was passiert, wenn ich sie jetzt ändere? Ich habe grep über den gesamten Quelltext, um alle Zugriffe zu sammeln, um zu wissen, was da passiert.

Wenn Sie wissen, wie Sie es verwenden, weil Sie gerade den Code geschrieben haben, ist das Problem unsichtbar, aber wenn Sie versuchen, fremden Code zu verstehen, werden Sie verstehen.

b) Brauchen Sie wirklich nur einen?

Statische Variablen verhindern oft, dass mehrere gleichartige Programme in derselben JVM mit unterschiedlichen Werten laufen. Sie sehen oft keine Verwendungszwecke vor, bei denen mehr als eine Instanz Ihres Programms nützlich ist, aber wenn es sich weiterentwickelt oder wenn es für andere nützlich ist, könnten sie Situationen erleben, in denen sie mehr als eine Instanz Ihres Programms starten möchten.

Nur mehr oder weniger nutzloser Code, der nicht von vielen Menschen über einen längeren Zeitraum intensiv genutzt wird, könnte gut zu statischen Variablen passen.

2voto

Es gibt hier viele gute Antworten, die das Thema ergänzen,

Speicher: Statische Variablen sind so lange aktiv, wie der Klassenlader aktiv ist [im Allgemeinen bis die VM stirbt], aber dies gilt nur für Massenobjekte/Referenzen, die als statisch gespeichert sind.

Modularisierung: Konzepte wie IOC, dependencyInjection, Proxy etc. berücksichtigen. Alle sind völlig gegen eng gekoppelte/statische Implementierungen.

Andere Nachteile: Fadensicherheit, Prüfbarkeit

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X