Best Practice zum Erstellen einer 'globalen' Konfigurationsklasse, die von zahlreichen Komponenten verwendet wird

11

Ich habe ein großes Projekt mit einem Treiberteil und ungefähr 5 Bibliotheken, die verschiedene zugehörige Aufgaben ausführen. Viele der Bibliotheken benötigen Zugriff auf 'globale' Konfigurationsdaten, die beim Start vom Treibercode aus einer Datenbank gelesen werden. Mit Treiber meine ich nur den Teil, der die Hauptfunktion enthält.

Meine Idee, wie ich damit umgehen soll, war, eine Konfigurationsklasse mit einer statischen Methode zu erstellen, um die Konfigurationselemente abzurufen. Ist das der beste Ansatz? Wie könnte dies sonst erreicht werden?

z.B:

class config {
 public:
   static get_item(key);

 private:
   static values;
};

Ist Singleton-Design hier angemessen?

user619818
quelle

Antworten:

14

Die Nicht-Singleton-Methode besteht darin, eine reguläre Konfigurationsklasse mit regulären Eigenschaften / Elementen zu erstellen, dieses Objekt mit den korrekten Einstellungen aus der Datenbank im Treiber zu instanziieren und die Instanz an alle Bibliotheken zu übergeben - wahrscheinlich über std :: shared_ptr. Dies ist ein gängiges Entwurfsmuster, das als Abhängigkeitsinjektion bezeichnet wird .

Auf diese Weise vermeiden Sie alle potenziellen Probleme des Singleton-Entwurfsmusters und Ihr Code ist besser testbar, da Sie eine Instanz Ihrer Konfigurationsklasse mit beliebigen Daten zum Testen instanziieren können.

Joris Timmermans
quelle
+1, wollte diese Sache über Testbarkeit zu meiner eigenen Antwort hinzufügen, aber Sie waren schneller.
Doc Brown
Etwas OT: Ist das nicht immer noch ein Singleton, nur anders implementiert?
Adhominem
1
@adhominem - nein, es ist ein Objekt, für das nur eine einzige Instanz existiert, aber es gibt keine spezielle Maschinerie.
Joris Timmermans
@OliverWeiler - richtig, und ich hätte in meiner Antwort wirklich auf diesen Namen des Entwurfsmusters verweisen sollen, also füge ich ihn jetzt hinzu.
Joris Timmermans
1

Ich denke, dies ist eine der Zeiten, in denen ein Singleton tatsächlich das Richtige ist.

In Bezug auf die Schnittstelle der Klasse selbst können Sie entweder Get-by-Key-Namen verwenden oder Accessoren für die einzelnen Konfigurationswerte haben. Das letztere Schema bietet eine gewisse Bequemlichkeit (IDE-Vervollständigung für einen) und ermöglicht es Ihnen, die Konfigurationswerte in ihre korrekten Datentypen umzuwandeln, bevor Sie sie verwenden. Außerdem wird eine gewisse Trennung zwischen den Benutzern der Konfigurationsklasse und ihrer internen Implementierung eingeführt (die Tatsache, dass alle Konfigurationswerte beispielsweise als Zeichenfolgen gespeichert werden, ist ein Implementierungsdetail, über das sich der Benutzer der Klasse keine Sorgen machen sollte).

adhominem
quelle