Ich arbeite an einer Anwendung mit vielen Konstanten. Bei der letzten Codeüberprüfung stellte sich heraus, dass die Konstanten zu verstreut sind und alle in einer einzigen "Master" -Konstanten-Datei organisiert werden sollten. In der Meinungsverschiedenheit geht es darum, wie man sie organisiert. Die Mehrheit ist der Meinung, dass die Verwendung des Konstantennamens gut genug sein sollte, aber dies führt zu Code, der so aussieht:
public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";
Ich finde diese Art der Namenskonvention umständlich. Ich dachte, es könnte einfacher sein, eine öffentliche verschachtelte Klasse zu verwenden und so etwas zu haben:
public class IntegrationSystemConstants
{
public class CreditCard
{
public static final String UI_EXPIRY_MONTH = "3524";
public static final String UI_ACCOUNT_ID = "3524";
...
}
public class BankAccount
{
public static final String UI_ACCOUNT_ID = "9987";
...
}
}
Diese Idee wurde nicht gut aufgenommen, weil sie "zu kompliziert" war (ich habe nicht viele Details darüber erhalten, warum dies zu kompliziert sein könnte). Ich denke, dies führt zu einer besseren Aufteilung zwischen Gruppen verwandter Konstanten, und die automatische Vervollständigung erleichtert das Auffinden dieser Konstanten. Ich habe dies jedoch noch nie gesehen und frage mich, ob dies eine akzeptierte Praxis ist oder ob es bessere Gründe gibt, warum dies nicht getan werden sollte.
quelle
Antworten:
Ich stimme keinem der beiden Vorschläge zu.
Konstanten sollten in ihren jeweiligen Klassen und nicht in einer allkonstanten Klasse in einer der beiden vorgeschlagenen Formen sein .
Es sollte keine Klassen / Interfaces nur mit Konstanten geben.
Eine Klasse
CreditCard
(keine interne Klasse) sollte existieren. Diese Klasse / Schnittstelle hat Methoden in Bezug auf Kreditkarten sowie die KonstantenUI_EXPIRY_MONTH
undUI_ACCOUNT_ID
.Es sollte eine Klasse / Schnittstelle geben
BankAccount
(keine interne Klasse). Diese Klasse / Schnittstelle hat Methoden, die sich sowohl auf Bankkonten als auch auf Konstanten beziehenUI_ACCOUNT_ID
.Beispielsweise hat in der Java-API jede Klasse / Schnittstelle ihre Konstanten. Sie befinden sich nicht in einer Konstantenklasse / -schnittstelle mit Hunderten von Konstanten, die entweder in innere Klassen gruppiert sind oder nicht.
Diese Konstanten für Ergebnismengen befinden sich beispielsweise in der Schnittstelle
ResultSet
:Diese Schnittstelle verfügt über Methodensignaturen in Bezug auf Ergebnismengen, und implementierende Klassen implementieren dieses Verhalten. Sie sind nicht nur Konstantenhalter.
Diese Konstanten für UI-Aktionen befinden sich in der Schnittstelle
javax.swing.Action
:Implementierende Klassen verhalten sich relativ zu UI-Aktionen, sie sind nicht nur konstante Halter.
Ich kenne mindestens eine "Konstanten" -Schnittstelle (
SwingConstants
) ohne Methoden, aber sie hat nicht Hunderte von Konstanten, nur einige wenige, und sie hängen alle mit Richtungen und Positionen von UI-Elementen zusammen:Ich denke, nur Konstanten-Klassen sind kein gutes OO-Design.
quelle
Dies ist die 100% falsche Lösung für das Problem, dass Konstanten "schwer zu finden" sind. Es ist ein grundlegender Fehler (der leider nur allzu häufig von Programmierern begangen wird), Dinge nach technischen Kriterien wie Konstanten, Aufzählungen oder Schnittstellen zu gruppieren.
Mit Ausnahme von Ebenenarchitekturen sollten die Dinge nach ihrer Domäne gruppiert werden , und dies gilt umso mehr, als es sich um sehr einfache Elemente handelt. Konstanten sollten Teil der Klassen oder Schnittstellen sein, die sie als Teil ihrer API verwenden. Wenn Sie keinen natürlichen Ort zum Leben finden, müssen Sie Ihr API-Design bereinigen.
Darüber hinaus beeinträchtigt eine einzige große Konstantendatei die Entwicklungsgeschwindigkeit in Java, da Konstanten in die Klassen eingefügt werden, die sie zur Kompilierungszeit verwenden. Jede Änderung erzwingt daher eine Neukompilierung aller dieser und aller von ihnen abhängigen Dateien. Wenn Sie eine Datei mit Konstanten haben, die überall verwendet werden, verlieren Sie weitgehend den Vorteil der inkrementellen Kompilierung: Beobachten Sie, wie Eclipse 15 Minuten lang blockiert, während es Ihr gesamtes Projekt für jede Änderung an dieser Datei neu kompiliert. Und da diese Datei alle überall verwendeten Konstanten enthält, werden Sie sie ziemlich oft ändern. Ja, ich spreche aus eigener Erfahrung.
quelle
Du hast recht. Ihr Vorschlag ermöglicht es einem Programmierer,
import static Constants.BankAccount.*
unzählige Wiederholungen von 'BANKACCOUNT_' zu vermeiden. Verkettung ist ein schlechter Ersatz für das tatsächliche Scoping. Trotzdem hoffe ich nicht sehr, dass Sie die Teamkultur ändern. Sie kennen die richtigen Praktiken und werden sich wahrscheinlich auch dann nicht ändern, wenn Sie ihnen 100 Experten zeigen, die sagen, dass sie falsch sind.Ich frage mich auch, warum Sie überhaupt eine einzige "Konstanten" -Datei haben. Dies ist eine sehr schlechte Praxis, es sei denn, diese Konstanten hängen alle irgendwie zusammen und sind sehr stabil. Typischerweise wird es zu einer Art Spültischklasse, die sich ständig ändert und von allem abhängig ist.
quelle
Beide Ansätze funktionieren, und das ist am Ende des Tages wichtig.
Das heißt, Ihr Ansatz ist weit genug verbreitet, um als Muster oder genauer gesagt als eine hinreichende Verbesserung gegenüber dem Antimuster der konstanten Grenzfläche angesehen zu werden . Ich verstehe nicht, was daran kompliziert ist, aber das ist eine Diskussion, die Sie mit Ihrem Team führen sollten.
quelle
Eine der Herausforderungen bei der langen Liste von Konstanten besteht darin, die zu verwendende "richtige" Konstante zu finden. Ausnahmslos fügt jemand eine Konstante am Ende der Zeile hinzu, anstatt sie der Gruppe hinzuzufügen, zu der sie gehört.
Was einen weiteren Punkt zur Diskussion mit Ihrem Team aufwirft: Es gibt bereits eine tatsächliche Kategorisierung der Konstanten anhand ihrer Namen. Es sollte für sie also keine große Verschiebung vom aktuellen Stand zu dem sein, was Sie vorschlagen. Durch die Verwendung der automatischen Vervollständigung wird die ständige Suche noch einfacher.
Wenn überhaupt, hilft Ihr Vorschlag dabei, von der Verwendung der "falschen" Konstante abzuraten, auch wenn sie in eine bestimmte Situation passt. Indem die Konstanten in eine repräsentative Klasse eingeschlossen werden, werden die Entwickler angeregt, darüber nachzudenken, ob sie sie verwenden sollten. Wenn ich zum Beispiel
CreditCard.SomeConstant
für den allgemeinen Gebrauch ziehe, sollte ich mich wirklich fragen, warum es keine gibtGeneral.SomeConstant
stattdessen für diese Situation gibt.Ich war in Projekten mit Monstermengen an Konstanten und hätte es vorgezogen, die von Ihnen vorgeschlagene Methode zu haben. Es ist sauberer, direkter und vermeidet unbeabsichtigten Gebrauch.
quelle
Ich mache das gelegentlich (in C #), besonders wenn ich eine bekannte und feste XML-Struktur oder etwas ähnlich verschachteltes und stringlastiges programmieren muss ... zum Beispiel einen benutzerdefinierten Konfigurationsblock-Parser.
Ich baue eine verschachtelte Klassenstruktur auf, die mit der hierarchischen Struktur des XML übereinstimmt, wobei die Klassennamen den Elementen entsprechen, die eine konstante Zeichenfolge "ElementName" und eine ähnliche Eigenschaft für jedes Attribut enthalten (falls vorhanden).
Es macht es sehr einfach, gegen die entsprechende XML zu programmieren.
quelle