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?

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.


+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).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.