Dans de telles situations, j'ai réussi à introduire (réutiliser) le terme "contexte" avec parfois plusieurs couches.
Cela signifie un magasin d'objets unique, donc "global", à partir duquel ce type d'objets peut être demandé. Les codes qui les nécessitent, incluent l'en-tête du magasin et utilisent les fonctions globales pour obtenir leurs instances d'objet (comme maintenant, le fournisseur de taux d'intérêt).
Le magasin peut être soit:
- strictement typé: vous incluez les en-têtes pour tous les types servis et vous pouvez donc créer des accesseurs typés, comme InterestRate getCurrentInterestRate ();
- ou générique: Object getObject (enum obType); et étendre uniquement l'énumération obType avec les nouveaux types (obtypeCurrentInterestRate).
Plus le système est grand, plus cette dernière solution est utilisable, pour un risque assez faible d'utiliser la mauvaise énumération. D'un autre côté, avec les langages qui autorisent les déclarations de type direct, je pense que vous pouvez utiliser des accesseurs typés sans inclure tous les en-têtes dans le magasin.
Encore une remarque: vous pouvez avoir plusieurs instances du même type d'objet pour différentes utilisations, comme parfois une valeur de langue différente pour l'interface graphique et pour l'impression, les journaux de niveau global et de session, etc., donc le nom de l'énumération / accesseur ne doit PAS refléter le type réel , mais le rôle de l'instance demandée (CurrentInterestRate).
Dans l'implémentation du magasin, vous devez gérer les niveaux de contexte et les collections d'instances de contexte. Un exemple simple est le service Web, où vous avez le contexte global (une instance pour toutes les demandes pour cet objet - problématique lors de la création d'une batterie de serveurs) et un contexte pour chaque session Web. Vous pouvez également avoir des contextes pour chaque utilisateur, qui peut avoir plusieurs sessions parallèles, etc. Avec plusieurs serveurs, vous devez utiliser une sorte de cache distribué pour de telles choses.
Lorsque la demande arrive, vous décidez du niveau de contexte de l'objet demandé, obtenez ce contexte pour l'appel. Si l'objet est là, vous le renvoyez; sinon, vous le créez et le stockez à ce niveau de contexte et le renvoyez. Bien sûr, synchronisez la section de création (et publiez-la dans le cache distribué). La création peut être configurable comme un plugin, mieux avec des langages permettant de créer des instances d'objet par leur nom de classe (Java, Objective C, ...), mais vous pouvez le faire en C également avec des bibliothèques pluggables ayant des fonctions d'usine.
Remarque: l'appelant ne doit PAS en savoir trop sur ses propres contextes et sur le niveau de contexte de l'objet demandé. Raisons: 1: il est facile de se tromper (ou "astuces astucieuses") en jouant avec ces paramètres; 2: le niveau de contexte du demandé pourrait changer ultérieurement. Je connecte principalement les informations de contexte au thread, de sorte que le magasin d'objets a les informations sans paramètres supplémentaires de la demande.
D'un autre côté, la demande peut contenir un indice pour l'instance: comme obtenir le taux d'intérêt pour une date spécifique. Il doit s'agir du même accès "global", mais de plusieurs instances en fonction de la date (et en menant différentes valeurs de date dans la même instance entre les changements de taux), il est donc conseillé d'ajouter un objet "hint" à la demande, utilisé par le par exemple l'usine et non le magasin; et un keyForHint à l'usine, utilisé par le magasin. Vous pouvez ajouter ces fonctions plus tard, je viens de le mentionner.
Dans votre cas, c'est une sorte de surpuissance (un seul objet est servi au niveau global), mais pour un code supplémentaire assez petit et simple en ce moment, vous obtenez un mécanisme pour des exigences supplémentaires, peut-être plus complexes.
Autre bonne nouvelle: si vous êtes en Java, vous obtenez ce service de Spring sans trop réfléchir, je voulais juste l'expliquer en détails.