2008-12-17 12 views
26

In allen meinen Projekten verwende ich bisher Singleton-Muster, um auf Anwendungskonfiguration in der gesamten Anwendung zuzugreifen. In letzter Zeit sehe ich viele Artikel, die davon ausgehen, kein Singleton-Muster zu verwenden, da dieses Muster die Testbarkeit nicht fördert und auch die Komponentenabhängigkeit verbirgt. Meine Frage ist, was ist der beste Weg, um Anwendungskonfiguration zu speichern, die in der gesamten Anwendung leicht zugänglich ist, ohne das Konfigurationsobjekt über die gesamte Anwendung zu übergeben?Singleton für Anwendungskonfiguration

Vielen Dank im Voraus

Madhu

Antwort

21

Ich denke, eine Anwendungskonfiguration eine hervorragende Nutzung des Singleton-Musters ist. Ich neige dazu, es selbst zu verwenden, um zu verhindern, dass ich die Konfiguration jedes Mal neu lesen muss, wenn ich darauf zugreifen möchte, und weil ich möchte, dass die Konfiguration stark typisiert wird (d. H. Nicht Nicht-String-Werte jedes Mal konvertieren müssen). Ich verwende gewöhnlich einige Backdoor-Methoden für mein Singleton, um die Testbarkeit zu unterstützen - d. H. Die Fähigkeit, eine XML-Konfiguration zu injizieren, sodass ich sie in meinem Test einstellen kann und den Singleton so zerstören kann, dass er bei Bedarf neu erstellt wird. Typischerweise sind dies private Methoden, auf die ich über Reflektion zugreife, so dass sie von der öffentlichen Schnittstelle verborgen sind.

BEARBEITEN Wir leben und lernen. Während ich denke, dass die Anwendungskonfiguration einer der wenigen Orte ist, an denen ein Singleton verwendet werden kann, mache ich das nicht mehr. In der Regel werde ich jetzt eine Schnittstelle und eine Standardklassenimplementierung unter Verwendung von statischen Lazy<T> Hintergrundfeldern für die Konfigurationseigenschaften erstellen. Dies ermöglicht mir, das Verhalten "Einmal initialisieren" für jede Eigenschaft mit einem besseren Design für die Testbarkeit zu haben.

+3

+1, die Menschen lieben ihre kleine Regeln wie „nur einen Ausgang aus einer Schleife“ oder „keine Singletons erlaubt“ zu erstellen. Ich wäre lieber pragmatisch als dogmatisch, da das Dogma dazu führt, dass Menschen nicht für sich selbst denken können. Wenn Sie nur ein X-Objekt haben können, sollten Sie nur ein XConfig-Objekt haben. – paxdiablo

+2

Eine einzelne Instanz eines Konfigurationsobjekts ist in Ordnung und wünschenswert, aber es macht nicht die Verwendung eines Singleton, um es gut zu bekommen.Die Verwendung von Hacks wie testspezifische Methoden in Ihrer tatsächlichen Klasse sind auch nicht für sauberen Code oder Tests geeignet. – ColinD

1

Für diese spezielle Situation würde ich ein Konfigurationsobjekt erstellen und es an diejenigen weitergeben, die es brauchen.

Da es die Konfiguration ist, sollte es nur in bestimmten Teilen der App verwendet werden und nicht unbedingt Omnipräsent sein.

Wenn Sie jedoch keine Probleme hatten, sie zu verwenden, und nicht so hart testen möchten, sollten Sie so weitermachen wie bis heute.

Lesen Sie die Diskussion darüber, warum sie als schädlich angesehen werden. Ich denke, dass die meisten Probleme auftreten, wenn der Singleton viele Ressourcen hält.

Für die App-Konfiguration denke ich, es wäre sicher, es so zu behalten, wie es ist.

5

Verwenden Sie Dependency Injection, um das einzelne Konfigurationsobjekt in alle Klassen zu injizieren, die es benötigen. Auf diese Weise können Sie eine Testkonfiguration zum Testen oder was auch immer Sie wollen verwenden ... Sie gehen nicht explizit aus und holen etwas, das mit Konfigurationsdateien initialisiert werden muss. Bei der Abhängigkeitsinjektion übergeben Sie das Objekt nicht.

+0

Also in diesem Fall wird das Konfigurationsobjekt noch ein Singleton sein, aber der Code wird eine Schnittstelle verwenden, anstatt direkt die Klasse, und die tatsächliche Implementierung wird von Spring injiziert werden? So könnten wir ein Mock-Objekt zum Testen injizieren. Ist das richtig? – stivlo

+0

@stivlo: Richtig, die einzelne Instanz würde vom Dependency-Injektionscontainer verwaltet (sei es Spring, Guice oder was auch immer) und der Code könnte vielleicht eine Schnittstelle verwenden, die es ermöglicht, eine Implementierung mit den gewünschten Einstellungen zu übergeben testen. Es muss nicht unbedingt ein Mock sein ... es könnte die echte Implementierung sein, nur mit Einstellungen, die Sie selbst hinzufügen, anstatt aus einer Datei zu lesen. – ColinD

+0

Also, @ColinD, bitte ertragen Sie mit mir, der ganze Fokus hier ist nicht, dass Singleton schlecht für sich ist, könnte es angemessen sein, vor allem für die Anwendungskonfiguration oder vielleicht um einen Pool von Verbindungen zu pflegen würde ich sagen, aber es kann schlecht werden Wenn die Abhängigkeit ausgeblendet ist, werden die Codeabhängigkeiten nicht angezeigt. Wenn Sie diese Abhängigkeit mit einem Container für Abhängigkeitsinjektionen festlegen, wird dies explizit gemacht. Diese Schlussfolgerung ist etwas anders als das Dogma "singletons vermeiden". Würdest du dem zustimmen? – stivlo

0

Das Singleton-Muster scheint der Weg zu sein. Hier ist eine Setting class, die ich geschrieben habe, die gut für mich funktioniert.

Verwandte Themen