Se você adicionar novas opções de configuração a um programa, ele poderá ter muitos efeitos colaterais em termos de levar as opções para onde elas precisam ser executadas. Existem três maneiras básicas de lidar com isso que eu conheço:
Passe todas as definições de configuração para as partes do seu programa que precisam delas explicitamente como primitivas. Essa é a maneira mais explícita e a que mais desacopla as coisas. A desvantagem é que isso é detalhado e quebradiço.
Torne as definições de configuração usadas com mais freqüência global / estáticas. Essa é a maneira mais simples, mas introduz ação à distância, dificulta a testabilidade e assume que a configuração é realmente global (que você deseja apenas uma configuração a qualquer momento).
Faça uma classe / estrutura de configuração que contenha todas as opções de configuração para todo o programa ou para cada preocupação principal do programa e repasse-a explicitamente. Isso é menos explícito que (1), mas mais explícito que (2). Se você deseja alterar uma configuração apenas para uma chamada de função, pode clonar o objeto de configuração e alterar esse valor. Isso é útil nos testes e na prática. No entanto, você ainda acaba potencialmente passando toneladas de informações para uma função que não precisa, e alterar um valor na classe / estrutura de configuração ainda pode causar ações à distância.
Você consideraria (3) um padrão ou um antipadrão? Se é um anti-padrão, o que você faz?
fonte
Respostas:
A melhor solução seria criar várias interfaces de configuração e implementá-las como desejar. Isso limita a acessibilidade e mantém as coisas localizadas. No entanto, é muito esforço valer a pena simplesmente jogar toda a configuração em uma única classe e passar para um problema com muito mais gravidade. Essa é a configuração, não a UtterlyCrucialAlwaysChangingClass - ela permanecerá praticamente a mesma. Contanto que você não faça tudo global e a implementação seja consistente, eu não me preocuparia.
fonte
Prefiro a sua opção 1 porque a dissociação permite testes mais fáceis, e as definições de configuração das quais o objeto depende são explicitadas. Se um objeto exigir uma configuração, forneça explicitamente ao objeto por um argumento construtor ou método setter. Reduza a verbosidade usando uma estrutura de injeção de dependência para injetar essas definições de configuração no objeto.
fonte
Imagine se o seu arquivo de configuração foi gravado em XML. Você pode simplesmente passar fragmentos desse XML para cada um dos seus componentes, para que eles obtenham seus dados de configuração.
Se você estiver usando o .NET, é possível criar classes com DataContracts que você pode usar o XmlSerialiser para criar uma hierarquia de objetos a partir do seu Xml de configuração e passar esses objetos como configuração.
Isso então apresenta o próximo problema. Seus dados de configuração possuem três partes diferentes. A configuração estrutural do aplicativo que organiza suas bibliotecas de códigos para se comportar como esse produto específico. As definições de configuração do site que contêm as configurações específicas da instalação e os dados de preferência / configurações do usuário que variam com cada usuário no seu sistema.
Saber qual parte é qual e manter essas configurações de dados separadas tornará a instalação das atualizações muito mais simples (sem perder as configurações dos clientes)
fonte
Eu tornaria a classe na opção 3 estática. Então, ao invés de
Você pode apenas ter:
Deixe os detalhes de carregamento / salvamento dos dados de configuração acontecerem dentro da
MyAppConfig
classe. E é claro que você pode ter variações mais complexas, como classes diferentes para diferentes propósitos.O único caso em que essa abordagem seria um problema seria se você, por algum motivo, precisasse trabalhar em várias instâncias de configurações diferentes ao mesmo tempo , embora eu ainda precise encontrar uma situação dessas.
fonte
Estou trabalhando em um projeto em que estamos usando a abordagem "3 camadas (interface, lógica de negócios, acesso a dados)". O aplicativo pode ser um servidor web multiusuário ou servidor cliente.
Trabalhamos com 3 configurações diferentes, a primeira específica para o PC, independentemente de o usuário estar trabalhando. O segundo específico para o usuário atual e uma terceira configuração global para todos os usuários e aplicativos clientes.
Cada configuração é representada em cada instância do aplicativo por um objeto.
Essa abordagem pode ajudar seu projeto.
fonte