In solchen Situationen habe ich den Begriff "Kontext" mit manchmal mehreren Ebenen erfolgreich eingeführt (wiederverwendet).
Dies bedeutet einen Singleton, also einen "globalen" Objektspeicher, von dem diese Art von Objekten angefordert werden kann. Codes, die sie erfordern, enthalten den Header des Geschäfts und verwenden die globalen Funktionen, um ihre Objektinstanzen abzurufen (wie jetzt der Zinsanbieter).
Der Laden kann entweder sein:
- streng typisiert: Sie fügen die Header für alle bereitgestellten Typen ein und können so typisierte Accessoren wie InterestRate getCurrentInterestRate () erstellen.
- oder generisch: Object getObject (enum obType); und erweitern Sie die obType-Enumeration nur mit den neuen Arten (obtypeCurrentInterestRate).
Je größer das System ist, desto benutzerfreundlicher ist die letztere Lösung für ein recht geringes Risiko, die falsche Aufzählung zu verwenden. Auf der anderen Seite können Sie mit Sprachen, die Forward-Typdeklarationen ermöglichen, typisierte Accessoren verwenden, ohne alle Header im Store einzuschließen.
Noch ein Hinweis: Möglicherweise haben Sie mehrere Instanzen desselben Objekttyps für unterschiedliche Zwecke, z. B. manchmal unterschiedliche Sprachwerte für die GUI sowie für Ausdrucks-, globale und Protokolle auf Sitzungsebene usw., sodass der Name der Aufzählung / des Zugriffs NICHT den tatsächlichen Typ widerspiegeln sollte , aber die Rolle der angeforderten Instanz (CurrentInterestRate).
In der Store-Implementierung müssen Sie die Kontextebenen und Kontextinstanzsammlungen verwalten. Ein einfaches Beispiel ist der Webdienst, bei dem Sie den globalen Kontext (eine Instanz für alle Anforderungen für dieses Objekt - problematisch bei einer Serverfarm) und einen Kontext für jede Websitzung haben. Sie können auch Kontexte für jeden Benutzer haben, der mehrere parallele Sitzungen usw. haben kann. Bei mehreren Servern sollten Sie für solche Dinge eine Art verteilten Cache verwenden.
Wenn die Anforderung eingeht, entscheiden Sie, auf welcher Kontextebene sich das angeforderte Objekt befindet, und rufen diesen Kontext für den Aufruf ab. Wenn das Objekt vorhanden ist, senden Sie es zurück. Wenn nicht, erstellen und speichern Sie es auf dieser Kontextebene und geben es zurück. Synchronisieren Sie natürlich den Erstellungsabschnitt (und veröffentlichen Sie ihn im verteilten Cache). Die Erstellung kann wie ein Plugin konfiguriert werden, am besten mit Sprachen, die das Erstellen von Objektinstanzen anhand ihres Klassennamens (Java, Objective C, ...) ermöglichen. Sie können dies jedoch auch in C mit steckbaren Bibliotheken mit Factory-Funktionen tun.
Randnotiz: Der Aufrufer sollte NICHT zu viel über seine eigenen Kontexte und die Kontextebene des angeforderten Objekts wissen. Gründe: 1: Es ist leicht, Fehler (oder "clevere Tricks") zu machen, wenn man mit diesen Parametern spielt. 2: Die Kontextebene der angeforderten kann sich später ändern. Ich verbinde meistens Kontextinformationen mit dem Thread, sodass der Objektspeicher die Informationen ohne zusätzliche Parameter aus der Anforderung enthält.
Auf der anderen Seite kann die Anfrage einen Hinweis für die Instanz enthalten: wie das Abrufen des Zinssatzes für ein bestimmtes Datum. Es sollte derselbe "globale" Zugriff sein, aber je nach Datum mehrere Instanzen (und unterschiedliche Datumswerte zu derselben Instanz zwischen Ratenänderungen führen). Daher ist es ratsam, der Anforderung ein "Hinweis" -Objekt hinzuzufügen, das von der Instanz Fabrik und nicht das Geschäft; und einen KeyForHint zur Fabrik, der vom Geschäft verwendet wird. Sie können diese Funktionen später hinzufügen, wie ich gerade erwähnt habe.
Für Ihren Fall ist dies eine Art Overkill (nur ein Objekt wird auf globaler Ebene bereitgestellt), aber für einen recht kleinen und einfachen zusätzlichen Code erhalten Sie derzeit einen Mechanismus für weitere, möglicherweise komplexere Anforderungen.
Eine weitere gute Nachricht: Wenn Sie in Java sind, erhalten Sie diesen Service von Spring, ohne zu viel darüber nachzudenken. Ich wollte ihn nur im Detail erklären.