Eu estava escrevendo algum código no fim de semana e me vi querendo escrever uma fábrica como um método estático em uma classe base.
Minha pergunta é simplesmente saber se esta é uma abordagem ac # idomatic?
Minha sensação de que pode não ser deriva do fato de a classe base ter conhecimento da classe derivada.
Dito isto, não tenho certeza de uma maneira mais simples de obter o mesmo resultado. Toda uma outra classe de fábrica parece (pelo menos para mim) uma complexidade desnecessária (?)
Algo como:
class Animal
{
public static Animal CreateAnimal(string name)
{
switch(name)
{
case "Shark":
return new SeaAnimal();
break;
case "Dog":
return new LandAnimal();
break;
default:
throw new Exception("unknown animal");
}
}
}
class LandAnimal : Animal
{
}
class SeaAnimal : Animal
{
}
c#
class-design
Anodeto de Aaron
fonte
fonte
Respostas:
Bem, a vantagem de uma classe de fábrica separada é que ela pode ser ridicularizada em testes de unidade.
Mas se você não fizer isso ou torná-lo polimórfico de qualquer outra maneira, um método estático de Factory na própria classe é bom.
fonte
Você pode usar Generics para evitar a instrução switch e desacoplar as implementações downstream da classe base também:
Uso:
ou
fonte
Levada ao extremo, a fábrica também pode ser genérica.
Em seguida, pode-se criar qualquer tipo de fábrica de objetos, que, por sua vez, podem criar qualquer tipo de objeto. Não sei se isso é mais simples, é certamente mais genérico.
Não vejo nada de errado com uma instrução switch para uma pequena implementação de fábrica. Quando você estiver em um grande número de objetos ou em possíveis hierarquias de classe diferentes de objetos, acho que uma abordagem mais genérica é mais adequada.
fonte
Péssima ideia. Primeiro, viola o princípio de aberto-fechado. Para qualquer novo animal, você teria que mexer com sua classe base novamente e possivelmente a quebraria. As dependências seguiriam o caminho errado.
Se você precisar criar animais a partir de uma configuração, uma construção como essa seria uma espécie de OK, embora usar reflexão para obter o tipo que corresponde ao nome e instancia-lo usando as informações de tipo obtidas seria uma opção melhor.
Mas você deve criar uma classe de fábrica dedicada de qualquer maneira, desatada da hierarquia de classes de animais e retornar uma interface IAnimal em vez de um tipo base. Então isso se tornaria útil, você teria conseguido alguma dissociação.
fonte
Esta pergunta é oportuna para mim - eu estava escrevendo quase exatamente esse código ontem. Apenas substitua "Animal" pelo que for relevante em meu projeto, embora eu continue com "Animal" para fins de discussão aqui. Em vez de uma declaração 'switch', eu tinha uma série um pouco mais complexa de declarações 'if', envolvendo mais do que apenas comparar uma variável a certos valores fixos. Mas isso é um detalhe. Um método estático de fábrica parecia uma maneira elegante de projetar coisas, pois o design surgiu da refatoração de bagunças de código rápidas e sujas anteriores.
Rejeitei esse design com base na classe base que tinha conhecimento da classe derivada. Se as classes LandAnimal e SeaAnimal forem pequenas, organizadas e fáceis, elas poderão estar no mesmo arquivo de origem. Mas tenho grandes métodos confusos para ler arquivos de texto que não estão em conformidade com nenhum padrão oficialmente definido - quero minha classe LandAnimal em seu próprio arquivo de origem.
Isso leva à dependência do arquivo circular - o LandAnimal é derivado de Animal, mas o Animal precisa saber que LandAnimal, SeaAnimal e quinze outras classes existem. Peguei o método de fábrica, coloquei em seu próprio arquivo (no meu aplicativo principal, não na minha biblioteca Animals) Ter um método de fábrica estático parecia bonito e inteligente, mas percebi que ele realmente não resolveu nenhum problema de design.
Não tenho idéia de como isso se relaciona com o C # idiomático, já que mudo muito de idioma, geralmente ignoro idiomas e convenções peculiares a idiomas e pilhas de desenvolvimento fora do meu trabalho habitual. Se alguma coisa meu C # pode parecer "pitônico", se isso é significativo. Eu busco clareza geral.
Além disso, não sei se havia uma vantagem em usar o método estático de fábrica no caso de classes pequenas e simples que provavelmente não serão estendidas em trabalhos futuros - ter tudo em um arquivo de origem pode ser bom em alguns casos.
fonte