Então, eu tenho uma fábrica que cria objetos de diferentes classes. As classes possíveis são todas derivadas de um ancestral abstrato. A fábrica possui um arquivo de configuração (sintaxe JSON) e decide qual classe criar, dependendo da configuração do usuário.
Para conseguir isso, a fábrica usa boost :: property_tree para análise JSON. Ele percorre a árvore e decide qual objeto concreto criar.
No entanto, os objetos do produto têm muitos campos (atributos). Dependendo da classe concreta, o objeto possui cerca de 5 a 10 atributos, no futuro talvez até mais.
Portanto, não tenho certeza de como deve ser o construtor dos objetos. Eu posso pensar em duas soluções:
1) O construtor do produto espera que cada atributo seja um parâmetro; portanto, o construtor terá mais de 10 parâmetros. Isso será feio e resultará em linhas de código longas e ilegíveis. No entanto, a vantagem é que a fábrica pode analisar o JSON e chamar o construtor com os parâmetros corretos. A classe do produto não precisa saber que foi criada devido à configuração JSON. Não é necessário saber se há JSON ou configuração envolvida.
2) O construtor do produto espera apenas um argumento, o objeto property_tree. Em seguida, ele pode analisar as informações necessárias. Se houver informações ausentes ou fora dos limites, cada classe de produto poderá reagir adequadamente. A fábrica não precisa saber quais argumentos são necessários para os vários produtos. A fábrica também não precisa saber como reagir em caso de configuração incorreta. E a interface do construtor é unificada e pequena. Mas, como desvantagem, o produto precisa extrair as informações necessárias do JSON, portanto, sabe como é construído.
Eu tendem a preferir a solução 2). No entanto, não tenho certeza se esse é um bom padrão de fábrica. De alguma forma, parece errado informar o produto que ele foi criado com a configuração JSON. Por outro lado, novos produtos podem ser introduzidos de maneira muito simples.
Alguma opinião sobre isso?
Respostas:
Eu não faria a opção 2, porque você sempre convolveu a construção do seu objeto com a análise de árvore de propriedades boost. Se você se sente confortável com uma classe que precisa de muitos parâmetros, deve se sentir confortável com um construtor que precisa de muitos parâmetros, como a vida!
Se sua principal preocupação é a legibilidade do código, você pode usar o padrão do construtor, é basicamente o código c ++ / java por falta de argumentos nomeados. Você acaba com coisas assim:
Então agora o MyObject terá um construtor privado, chamado em Builder :: build. O bom é que esse será o único lugar em que você precisará chamar um construtor com 10 parâmetros. A fábrica da árvore de propriedades boost usará o construtor e, subseqüentemente, se você desejar construir um MyObject diretamente ou de uma fonte diferente, passará pelo construtor. E o construtor basicamente permite que você nomeie claramente cada parâmetro à medida que o passa, para que fique mais legível. Obviamente, isso adiciona alguns clichês, então você terá que decidir se vale a pena em comparação com apenas chamar o construtor confuso ou agrupar alguns de seus parâmetros existentes em estruturas etc. Apenas jogando outra opção na mesa.
https://en.wikipedia.org/wiki/Builder_pattern#C.2B.2B_Example
fonte
NÃO use a segunda abordagem.
Definitivamente, não é a solução e levaria apenas a instanciar classes na lógica de negócios, em vez da parte do aplicativo em que as fábricas estão.
Ou:
A menos que o objeto que você esteja criando seja realmente uma classe responsável pela retenção de dados, tente refatorar o código e dividir a classe grande em outras menores.
fonte
new
ou construir objetos dentro da lógica de negócios, não é um design muito bom. Verifique o item Não procure coisas por Miško Hevery , que explica mais detalhadamente por que a abordagem de fábrica sugerida é ruim do ponto de vista de teste e leitura. Além disso, sua classe parece ser um objeto de dados e, para aqueles, geralmente é bom ter mais parâmetros do que a classe de serviço regular. Eu não ficaria muito incomodado.A opção 2 está quase certa.
Uma opção melhorada 2
Crie uma classe "de frente", cuja tarefa é pegar esse objeto de estrutura JSON e selecionar os bits e chamar o (s) construtor (es) da fábrica. É preciso o que a fábrica faz e o entrega ao cliente.
Basicamente, o "front end" está dizendo aos 2 Bobs: "Eu lido com os clientes redigidos para que os engenheiros não precisem! Eu tenho habilidades com as pessoas!" Pobre Tom. Se ele dissesse "eu separo o cliente da construção. Esse resultado é uma fábrica altamente coesa"; ele pode ter mantido seu emprego.
Muitos argumentos?
Não é para a comunicação front-end do cliente.
Front-end - fábrica? Se não forem 10 parâmetros, o melhor que você pode fazer é adiar a descompactação, se não a coisa original do JSON, então algum DTO. Isso é melhor do que passar o JSON para a fábrica? A mesma diferença que eu digo.
Eu consideraria fortemente passar parâmetros individuais. Atenha-se ao objetivo de uma fábrica limpa e coesa. Evite as preocupações da resposta do @DavidPacker.
Atenuando "muitos argumentos"
Construtores de fábrica ou classe
Agrupamento de argumentos de front-end
fonte