Em tais situações, introduzi (reutilizei) o termo "contexto" com êxito, às vezes com várias camadas.
Isso significa um singleton, portanto, um armazenamento de objetos "global", do qual esses tipos de objetos podem ser solicitados. Os códigos que os exigem, incluem o cabeçalho da loja e usam as funções globais para obter suas instâncias de objeto (como agora, o provedor de taxa de juros).
A loja pode ser:
- estritamente digitado: você inclui os cabeçalhos de todos os tipos atendidos e pode criar acessadores digitados, como InterestRate getCurrentInterestRate ();
- ou genérico: Objeto getObject (enum obType); e somente estenda a enum obType com os novos tipos (obtypeCurrentInterestRate).
Quanto maior o sistema, mais utilizável é a última solução, com um risco bem pequeno de usar a enumeração errada. Por outro lado, com idiomas que permitem declarações de tipo encaminhamento, acho que você pode usar acessadores digitados sem incluir todos os cabeçalhos da loja.
Mais uma observação: você pode ter várias instâncias do mesmo tipo de objeto para usos diferentes, como valor de idioma às vezes diferente para a GUI e para registros de impressão, globais e no nível da sessão, etc. , mas a função da instância solicitada (CurrentInterestRate).
Na implementação da loja, você precisa gerenciar os níveis de contexto e as coleções de instâncias de contexto. Um exemplo simples é o serviço web, onde você tem o contexto global (uma instância para todas as solicitações para esse objeto - problemático ao ter um farm de servidores) e um contexto para cada sessão da web. Você também pode ter contextos para cada usuário, que pode ter várias sessões paralelas, etc. Com vários servidores, você deve usar um tipo de cache distribuído para essas coisas.
Quando a solicitação é recebida, você decide qual nível de contexto é o objeto solicitado e obtém esse contexto para a chamada. Se o objeto estiver lá, você o envia de volta; caso contrário, crie e armazene-o nesse nível de contexto e retorne-o. Obviamente, sincronize a seção de criação (e publique-a no cache distribuído). A criação pode ser configurável como plug-in, melhor com linguagens que permitem criar instâncias de objetos pelo nome da classe (Java, Objective C, ...), mas você pode fazer isso em C, bem como em bibliotecas conectáveis com funções de fábrica.
Nota lateral: o chamador NÃO deve saber muito sobre seus próprios contextos e o nível de contexto do objeto solicitado. Razões: 1: é fácil cometer erros (ou "truques inteligentes") jogando com esses parâmetros; 2: o nível de contexto do solicitado pode mudar mais tarde. Eu conecto principalmente informações de contexto ao encadeamento, para que o armazenamento de objetos tenha as informações sem parâmetros extras da solicitação.
Por outro lado, a solicitação pode conter dicas para a instância: como obter taxa de juros para uma data específica. Deve ser o mesmo acesso "global", mas várias instâncias, dependendo da data (e levando valores diferentes de data para a mesma instância entre alterações de taxa), portanto, é recomendável adicionar um objeto "dica" à solicitação, usado pelo fábrica de instância e não a loja; e um keyForHint para a fábrica, usado pela loja. Você pode adicionar essas funções mais tarde, apenas mencionei.
Para o seu caso, isso é um tipo de exagero (apenas um objeto é servido no nível global), mas para um código extra bem pequeno e simples no momento, você obtém um mecanismo para requisitos adicionais, talvez mais complexos.
Outra boa notícia: se você está em Java, obtém esse serviço do Spring sem pensar muito, só queria explicar em detalhes.