Wenn Sie einem Programm neue Konfigurationsoptionen hinzufügen, kann dies häufig zu erheblichen Welligkeitseffekten führen, wenn Sie die Optionen dahin bringen, wo sie bearbeitet werden müssen. Es gibt drei grundlegende Möglichkeiten, um damit umzugehen, die mir bekannt sind:
Übergeben Sie alle Konfigurationseinstellungen an die Teile Ihres Programms, die sie explizit als Grundelemente benötigen. Dies ist der expliziteste Weg und der Weg, der die Dinge am meisten entkoppelt. Der Nachteil ist, dass dies sowohl ausführlich als auch spröde ist.
Nehmen Sie die am häufigsten verwendeten Konfigurationseinstellungen global / statisch vor. Dies ist der einfachste Weg, führt jedoch Aktionen aus der Ferne ein, behindert die Testbarkeit und setzt voraus, dass die Konfiguration wirklich global ist (Sie möchten jeweils nur eine Konfiguration).
Erstellen Sie eine Konfigurationsklasse / -struktur, die alle Konfigurationsoptionen für das gesamte Programm oder für jedes Hauptproblem innerhalb des Programms enthält, und geben Sie diese dann explizit weiter. Dies ist weniger explizit als (1), aber expliziter als (2). Wenn Sie eine Einstellung nur für einen Funktionsaufruf ändern möchten, können Sie das Konfigurationsobjekt klonen und diesen einen Wert ändern. Dies ist sowohl beim Testen als auch in der Praxis nützlich. Am Ende übergeben Sie jedoch möglicherweise Tonnen von Informationen an eine Funktion, die nicht benötigt wird, und das Ändern eines Werts in der Konfigurationsklasse / -struktur kann immer noch zu Aktionen in der Ferne führen.
Würden Sie (3) ein Muster oder ein Anti-Muster in Betracht ziehen? Was machen Sie stattdessen, wenn es sich um ein Anti-Pattern handelt?
quelle
Antworten:
Die beste Lösung wäre, mehrere Konfigurationsschnittstellen zu erstellen und diese nach Ihren Wünschen zu implementieren. Dies schränkt sowohl die Zugänglichkeit ein als auch hält die Dinge lokalisiert. Es ist jedoch viel zu viel Aufwand, um es sich zu lohnen, einfach die gesamte Konfiguration in einer einzigen Klasse zu speichern und sich einem Problem mit viel mehr Gravitas zuzuwenden. Dies ist die Konfiguration, nicht die UtterlyCrucialAlwaysChangingClass - sie wird so ziemlich gleich bleiben. Solange Sie nicht alles global gestalten und die Implementierung konsistent ist, würde ich mir darüber keine Sorgen machen.
quelle
Ich bevorzuge Ihre Option 1, da die Entkopplung ein einfacheres Testen ermöglicht und die Konfigurationseinstellungen, von denen das Objekt abhängt, explizit angegeben werden. Wenn für ein Objekt eine Konfigurationseinstellung erforderlich ist, stellen Sie diese dem Objekt explizit durch ein Konstruktorargument oder eine Setter-Methode zur Verfügung. Reduzieren Sie die Ausführlichkeit, indem Sie ein Abhängigkeitsinjektionsframework verwenden, um diese Konfigurationseinstellungen in das Objekt einzufügen.
quelle
Stellen Sie sich vor, Ihre Konfigurationsdatei wurde in XML geschrieben. Sie können dann einfach Fragmente dieses XML an jede Ihrer Komponenten übergeben, damit diese ihre Konfigurationsdaten erhalten.
Wenn Sie .NET verwenden, können Sie mit DataContracts Klassen erstellen, mit denen Sie mit dem XmlSerialiser eine Objekthierarchie aus Ihrer Konfigurations-XML erstellen und diese Objekte als Konfiguration weitergeben können.
Dies führt Sie dann zum nächsten Problem. Ihre Konfigurationsdaten bestehen aus drei verschiedenen Teilen. Die strukturelle Anwendungskonfiguration, die Ihre Codebibliotheken so organisiert, dass sie sich wie dieses spezifische Produkt verhalten. Standortkonfigurationseinstellungen, die Ihre installationsspezifischen Einstellungen und Benutzereinstellungen / Einstellungsdaten enthalten, die von Benutzer zu Benutzer auf Ihrem System variieren.
Wenn Sie wissen, welcher Teil welcher ist, und diese Dateneinstellungen getrennt halten, wird die Installation von Updates viel einfacher (ohne die Kundeneinstellungen zu verlieren).
quelle
Ich würde die Klasse in Option 3 statisch machen. Also statt
Sie können einfach haben:
Lassen Sie die Details zum Laden / Speichern von Konfigurationsdaten innerhalb der
MyAppConfig
Klasse geschehen . Und natürlich können Sie komplexere Variationen haben, z. B. verschiedene Klassen für verschiedene Zwecke.Der einzige Fall , in dem dieser Ansatz ein Problem sein würde , aus irgendeinem Grund , wenn Sie an die Arbeit auf mehrere Instanzen von verschiedenen Konfigurationen erforderlich wäre zugleich , obwohl ich noch in einer solchen Situation kommen müssen.
quelle
Ich arbeite an einem Projekt, bei dem wir den Ansatz "3 Ebenen (Schnittstelle, Geschäftslogik, Datenzugriff)" verwenden. Die Anwendung kann ein Mehrbenutzer-Webserver oder ein Client-Server sein.
Wir arbeiten mit 3 verschiedenen Konfigurationen, die erste spezifisch für den PC, unabhängig davon, ob der Benutzer arbeitet. Die zweite ist spezifisch für den aktuellen Benutzer und eine dritte globale Konfiguration für alle Benutzer und Client-Apps.
Jede Konfiguration wird in jedem Instanz der Anwendung durch ein Objekt dargestellt.
Dieser Ansatz kann Ihrem Projekt helfen.
quelle