In unseren meist großen Anwendungen haben wir normalerweise nur wenige Stellen für "Konstanten":
- Eine Klasse für GUI und interne Konstanten (Registerkartentitel, Gruppentitel, Berechnungsfaktoren, Aufzählungen)
- Eine Klasse für Datenbanktabellen und -spalten (dieser Teil ist generierter Code) sowie lesbare Namen für diese (manuell zugewiesen)
- Eine Klasse für Anwendungsnachrichten (Protokollierung, Nachrichtenboxen usw.)
Die Konstanten sind in diesen Klassen normalerweise in verschiedene Strukturen unterteilt. In unseren C ++ - Anwendungen werden die Konstanten nur in der .h-Datei definiert und die Werte in der .cpp-Datei zugewiesen.
Einer der Vorteile ist, dass sich alle Saiten usw. an einem zentralen Ort befinden und jeder weiß, wo er sie finden kann, wenn etwas geändert werden muss.
Dies scheint Projektmanagern besonders zu gefallen, wenn Leute kommen und gehen, und auf diese Weise kann jeder solche trivialen Dinge ändern, ohne sich in die Struktur der Anwendung einarbeiten zu müssen.
Sie können auch einfach den Titel ähnlicher Gruppenfelder / Registerkarten usw. auf einmal ändern. Ein weiterer Aspekt ist, dass Sie diese Klasse einfach ausdrucken und an einen Nicht-Programmierer weitergeben können, der prüfen kann, ob die Beschriftungen intuitiv sind und ob Nachrichten an den Benutzer zu detailliert oder zu verwirrend sind.
Ich sehe jedoch einige Nachteile:
- Jede einzelne Klasse ist eng mit den Konstantenklassen verbunden
- Das Hinzufügen / Entfernen / Umbenennen / Verschieben einer Konstante erfordert eine Neukompilierung von mindestens 90% der Anwendung (Hinweis: Das Ändern des Werts ist nicht erforderlich, zumindest für C ++). In einem unserer C ++ - Projekte mit 1500 Klassen bedeutet dies etwa 7 Minuten Kompilierungszeit (bei Verwendung von vorkompilierten Headern; ohne diese beträgt die Kompilierungszeit etwa 50 Minuten) plus etwa 10 Minuten für das Verknüpfen mit bestimmten statischen Bibliotheken.
- Das Erstellen einer geschwindigkeitsoptimierten Version mit dem Visual Studio Compiler dauert bis zu 3 Stunden. Ich weiß nicht, ob die große Menge an Klassenbeziehungen die Quelle ist, aber es könnte genauso gut sein.
- Sie werden in vorübergehend hartcodierte Zeichenfolgen direkt in den Code hineingefahren, weil Sie etwas sehr schnell testen möchten und nicht nur 15 Minuten auf diesen Test warten möchten (und wahrscheinlich auf jeden nachfolgenden). Jeder weiß, was mit den Gedanken "Ich werde das später beheben" passiert.
- Die Wiederverwendung einer Klasse in einem anderen Projekt ist nicht immer so einfach (hauptsächlich aufgrund anderer enger Kopplungen, aber die Handhabung von Konstanten macht es nicht einfacher.)
Wo würden Sie solche Konstanten speichern? Welche Argumente würden Sie mitbringen, um Ihren Projektleiter davon zu überzeugen, dass es bessere Konzepte gibt, die auch die oben genannten Vorteile erfüllen?
Fühlen Sie sich frei, eine C ++ - spezifische oder unabhängige Antwort zu geben.
PS: Ich weiß, dass diese Frage subjektiv ist, aber ich kenne ehrlich gesagt keinen besseren Ort als diese Seite für diese Art von Frage.
Update zu diesem Projekt
Ich habe Neuigkeiten zur Kompilierungszeit:
Nach den Beiträgen von Caleb und gbjbaanb habe ich meine Konstantendatei in mehrere andere Dateien aufgeteilt, als ich Zeit hatte. Schließlich habe ich mein Projekt auch in mehrere Bibliotheken aufgeteilt, was jetzt viel einfacher möglich war. Das Kompilieren im Release-Modus hat gezeigt, dass die automatisch generierte Datei, die die Datenbankdefinitionen (Tabelle, Spaltennamen und mehr - mehr als 8000 Symbole) enthält und bestimmte Hashes aufbaut, die riesigen Kompilierzeiten im Release-Modus verursacht.
Durch Deaktivieren des MSVC-Optimierers für die Bibliothek, die die DB-Konstanten enthält, konnten wir die Gesamtkompilierungszeit Ihres Projekts (mehrere Anwendungen) im Release-Modus von bis zu 8 Stunden auf weniger als eine Stunde reduzieren!
Wir müssen noch herausfinden, warum es MSVC so schwer fällt, diese Dateien zu optimieren, aber diese Änderung entlastet uns vorerst sehr, da wir uns nicht mehr nur auf nächtliche Builds verlassen müssen.
Diese Tatsache - und andere Vorteile wie weniger enge Kopplung, bessere Wiederverwendbarkeit usw. - haben auch gezeigt, dass das Aufteilen der "Konstanten" keine so schlechte Idee war ;-)
Update2
Da diese Frage noch einige Aufmerksamkeit erhält:
Hier ist, was ich in den letzten Jahren getan habe:
Platzieren Sie jede Konstante, Variable usw. genau in dem Bereich, der für sie relevant ist: Wenn Sie eine Konstante nur in einer einzelnen Methode verwenden, ist es in Ordnung, sie in dieser Methode zu definieren. Wenn eine einzelne Klasse daran interessiert ist, belassen Sie es als privates Implementierungsdetail dieser Klasse. Gleiches gilt für Namensraum, Modul, Projekt, Firmenumfang. Ich verwende das gleiche Muster auch für Hilfsfunktionen und dergleichen. (Dies gilt möglicherweise nicht zu 100%, wenn Sie ein öffentliches Framework entwickeln.)
Auf diese Weise werden Wiederverwendbarkeit, Testbarkeit und Wartbarkeit in einem Maße verbessert, in dem Sie nicht nur weniger Zeit für das Kompilieren (zumindest in C ++), sondern auch weniger Zeit für die Fehlerbehebung aufwenden müssen, sodass Sie mehr Zeit für die eigentliche Entwicklung neuer Funktionen haben. Gleichzeitig wird die Entwicklung dieser Funktionen beschleunigt, da Sie mehr Code leichter wiederverwenden können. Dies überwiegt den Vorteil, den die Datei mit den zentralen Konstanten haben könnte, um ein Vielfaches.
Schauen Sie sich insbesondere das Prinzip der Schnittstellentrennung und das Prinzip der Einzelverantwortung an, wenn Sie mehr wissen möchten.
Wenn Sie damit einverstanden sind, stimmen Sie Calebs Antwort zu, da dieses Update im Grunde eine allgemeinere Sicht dessen ist, was er gesagt hat.