Frage

Ich habe immer gedacht, nur um die Haltekonstanten eine Klasse aufweist, ist ein schlechtes Design. Aber in letzter Zeit, ich habe es versucht, googeln und nur festgestellt, dass mit einer Schnittstelle als Konstanten ist schlecht ein Anti-Muster -. Nicht erwähnt, eine Klasse von Konstanten mit

Ich bin der Meinung, dass da eine Klasse von Konstanten wirklich nicht viel anders aus globalen Variablen ist, das ist, warum ich dagegen bin und neigen dazu, solche Klassen Refactoring entfernt. Es schafft eine Klasse von Daten, die absolut keinen Kontext hat. Diese Konstanten sind viel besser dran gebunden, was auch immer sie tatsächlich nutzen, ihnen Kontext und die Bedeutung zu geben, sowie so dass sie innerhalb einer Klasse gekapselt ist.

Was andere Leute denken?

War es hilfreich?

Lösung

Globale Konstanten sind nicht schlecht Praxis, so lange, wie sie sind ...

  1. ... unveränderlich -. Ein globaler, final / readonly Bezug auf ein veränderbares Objekt (wie ein Java ArrayList<T> oder ein C # List<T>) ist keine Konstante, sondern globaler Zustand
  2. ... von> 1 Klasse benötigt. Wenn nur eine Klasse Ihre Konstanten benötigt, legen Sie die Konstanten direkt in der Klasse. (Caveat. Balancieren DRY vs YAGNI entsprechend)

Bloch deckt die "konstante Schnittstelle" vs. "konstante Klasse" -Ausgabe in Effective Java, und setzt sich für die "konstante Class" -Ansatz. Der Grund, warum Sie ist nicht die Konstanten in einer Schnittstelle wollen, dass es Client-Klassen zu „implementieren“, die eine Schnittstelle verlockt (um die Konstanten zuzugreifen, ohne dass sie mit dem Schnittstellennamen voranstellen). Sie sollten sich nicht, obwohl - die Schnittstelle ist nicht wirklich eine Schnittstelle zu den Fähigkeiten des Objekts, sondern eine Kompilierung-Komfort in der Klasse externen Typ tief verwurzelt. Bedenken Sie:

interface C { public static final int OMGHAX = 0x539; }
class A implements C { ... }
class B { private A a; }

Klasse B jetzt hat unnötig eine Abhängigkeit C. Wenn die Implementierung von A Änderungen, so dass es nicht die Konstanten von C nicht benötigen, können Sie nicht implements C von ihm entfernen, ohne seine externe Schnittstelle zu brechen - jemand (wohl ein sehr dummer Mensch, aber solche Leute gibt es zuhauf) könnte ein A Objekt verweisen durch eine C Referenz!

Durch die Konstanten in einer Klasse setzen, und durch diese Klasse uninstantiable machen, Sie informieren Kunden, dass die konstante Klasse wirklich nur Funktionen als Teilnamespace. In C # markieren Sie die Klasse als static, in Java Sie es einem unerreichbaren Konstruktor machen wollen würden final und geben:

final class C { 
    private C() { throw new AssertionError("C is uninstantiable"); }
    public static final int OMGHAX = 0x539; 
}

Wenn Sie in Java programmieren und die Konstanten wollen, ohne sie mit dem konstanten Klassennamen voranstellen, können Sie die import static Funktionalität verwenden.

Und ja, es ist etwas überflüssig nur eine neue Art zu schaffen gezwungen zu werden, irgendwo, um Ihre Konstanten zu setzen, aber das ist eine Warze in Sprachen wie Java und C #, die wir zu bewältigen haben - wir wird setzen unsere Konstanten em <> irgendwo , und unsere beste Option geschieht eine nichtinstanziierbare Klasse.

Andere Tipps

Globale Konstanten sind in Ordnung.

Global (nicht konstante) Variablen sind das Werk des Teufels.

Globale Variablen sind problematisch, weil sie weitgehend unnötige Abhängigkeiten zwischen Modulen einführen. Diese Abhängigkeiten machen es schwieriger zu debuggen Probleme und Wiederverwendung Code.

Ich würde sagen, dass wirklich globale Konstanten sind auch problematisch aus dem gleichen Grunde, Anstatt also einen Singleton von mit MyGlobals genannt konstant wie MyGlobals.HTTP_SUCCESS_OK, Paket wie Konstanten zusammen in ihren eigenen Klassen enthält, wie HttpStatus.SUCCESS_OK.

Ich glaube, das globale Variablen Problem ist, dass sie global Staat zu schaffen. Globale Konstanten dies nicht tun, aber sie ist in der Tat verantwortlich für einige contextless Konstanten, die schlecht sein kann.

Was würde ich vorschlagen, wenn Sie Sachen benötigen, wie das ist Aufzählungen erstellen (falls Sie int Konstanten haben) oder statische Klassen für Konstanten, so dass Sie sie einige Kontext geben kann (Math.PI, zum Beispiel)

Ich nehme an einer Sache, die nicht erwähnt wird die pragmatischen Fragen. Wenn Sie eine kompilierte Sprache verwenden, beachten Sie, dass Sie neu kompilieren die Konstante den Wert zu ändern. Wenn es ein Wert ist können Sie häufig ändern möchten, können Sie auch eine Konfigurationsdatei betrachten.

In einigen Fällen globale Konstanten sind der perfekte Weg zu gehen, wenn sie wirklich konstant sind (nicht nur konstant für ein Build des Programms, aber angeblich während der gesamten Lebensdauer des Softwareproduktes und darüber hinaus).

Zum Beispiel, würden Sie nicht mehr Klassen haben wollen, um ihre eigene Konstante jeder erklären für pi, e oder HTTP_SUCCESS.

Auf der anderen Seite, globale Konstanten können viele der Probleme der globalen Variablen erstellen, wenn sie beliebige Werte sind, die beispielsweise geändert werden aufgrund der sich verändernden Anforderungen. D. h diese Konstanten in eine Konfigurationsdatei scheint wie eine vernünftige Option, wenn setzen, sollte es nicht eine globale Konstante sein.

Globale Variablen wurden als eine schlechte Sache allgemein anerkannt und in der Regel vermieden werden sollte. Dies ist, warum so viele Menschen ein Problem mit dem Singleton-Muster haben. Das Problem mit globalen Variablen ist, dass sie transitiv sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top