Quando o código do cliente pode saber sobre implementações de padrão de estratégia?

5

Estou pensando em usar um padrão de estratégia para o gerenciamento de arquivos de configuração. Dessa forma, posso suportar algumas configurações herdadas. Eu me sinto bastante sólido no design geral (como seu padrão de estratégia padrão), mas estou curioso para saber se o cliente deve saber o tipo de estratégia que está sendo implementada ou se isso viola o padrão de estratégia. Especificamente, o construtor ConfigurationParser requer um istream e uma string (ou talvez enum) do tipo de fluxo (xml, json, ini, etc.) para saber qual estratégia concreta instanciar.

Idealmente, gostaria apenas de passar o istream, mas se eu fizer isso, então eu provavelmente tenho que colocar em código no ConfigurationParser para discernir o tipo de fluxo, procurando por colchetes angulares vs colchetes ou algo do tipo.

Eu decidi não passar um caminho de arquivo de string e determinar o tipo de extensão porque o material legado não é sempre consistente na nomenclatura de extensão e torna meu código muito mais fácil de testar se eu passar fluxos em vez de caminhos de arquivo de codificação rígidos. p>     

por ÁEDÁN 10.07.2017 / 17:44
fonte

1 resposta

4

Eu vejo que você tem dois problemas diferentes. O problema A é fácil de resolver. Mas o problema B é mais difícil.

O problema A é chamar dinamicamente uma dada estratégia, dado um configString. Isso pode ser resolvido criando um mapa e emparelhando uma instância de cada analisador com uma string que o identifica. Dessa forma, basta buscar no Mapa o analisador de que você precisa. Se o analisador for muito caro para instanciar, você poderá colocar o construtor Mapear para esse analisador. Esta solução assume que o usuário final (ou você) sabe que tipo de arquivo de configuração será analisado.

Obviamente, para atingir o desacoplamento total, uma fábrica deve configurar todo o Mapa de analisadores (ou construtor de analisador) e o cliente deve ter este Mapa passado para ele. Dessa forma, apenas a fábrica é strongmente acoplada aos analisadores de concreto.

O problema B é que você quer determinar automaticamente que tipo de arquivo (ou istream) você está lendo para usar o analisador apropriado , ou seja, o usuário final (ou você) não selecionará o arquivo e diga ao aplicativo o tipo de arquivo conf.

Uma solução para o problema B é ter todos os analisadores em uma lista e iterar por ela. Quando um analisador falhar em analisar o fluxo, vá para o próximo analisador e assim por diante. Se um analisador analisar com êxito o fluxo, fim da história (você pode relatar qual analisador você finalmente usou se você adicionar um campo de nome aos analisadores). Se todo analisador falhar, o arquivo não será suportado por nenhum analisador. Você não precisa investigar dentro do fluxo para adivinhar o formato, deixe os analisadores tentar analisá-lo. Um problema em potencial que vejo com essa solução é que é possível que dois analisadores diferentes possam interpretar o mesmo formato de entrada de maneiras diferentes sem falhar. Nesse caso, o primeiro analisador que faz sempre fará o trabalho e pode não ser o que você esperava.

Uma saída de log pode ter esta aparência:

Parsing: unknown_config_file
..not XML
..not JSON
..successfully parsed using "ini" parser.

ou

Parsing: unknown_config_file
..not XML
..not JSON
..not ini
..unsuported config file.
    
por 10.07.2017 / 20:23
fonte