Quando é uma boa ideia usar métodos de fábrica dentro de um objeto em vez de uma classe Factory?
design-patterns
factory
factory-pattern
factory-method
Ravindra babu
fonte
fonte
Respostas:
Gosto de pensar em pais de design em termos de minhas pessoas serem 'pessoas', e os padrões são as maneiras pelas quais as pessoas conversam entre si.
Então, para mim, o padrão de fábrica é como uma agência de contratação. Você tem alguém que precisará de um número variável de trabalhadores. Essa pessoa pode conhecer algumas informações de que precisa nas pessoas que contrata, mas é isso.
Portanto, quando precisam de um novo funcionário, ligam para a agência contratada e dizem o que precisam. Agora, para contratar alguém, você precisa conhecer muitas coisas - benefícios, verificação de elegibilidade etc. Mas a pessoa que contrata não precisa saber nada disso - a agência de contratação lida com tudo isso.
Da mesma forma, o uso de uma fábrica permite que o consumidor crie novos objetos sem precisar saber os detalhes de como eles são criados ou quais são suas dependências - eles só precisam fornecer as informações que realmente desejam.
Portanto, agora o consumidor da ThingFactory pode obter uma coisa, sem ter que saber sobre as dependências da coisa, exceto os dados da cadeia de caracteres que vem do consumidor.
fonte
within an object instead of a Factory class
. Eu acho que ele quis dizer o cenário em que você torna o ctor privado e usa um método estático para instanciar a classe (criar um objeto). Mas, para seguir este exemplo, é preciso instanciar aThingFactory
classe primeiro para obterThing
objetos, o que torna issoFactory class
efetivo.Os métodos de fábrica devem ser considerados como uma alternativa aos construtores - principalmente quando os construtores não são expressivos o suficiente, ou seja.
não é tão expressivo quanto:
As classes de fábrica são úteis quando você precisa de um processo complicado para construir o objeto, quando a construção precisa de uma dependência que você não deseja para a classe real, quando você precisa construir objetos diferentes, etc.
fonte
Uma situação em que pessoalmente encontro classes de fábrica separadas para fazer sentido é quando o objeto final que você está tentando criar se baseia em vários outros objetos. Por exemplo, no PHP: suponha que você tenha um
House
objeto, que por sua vez tenha umKitchen
e umLivingRoom
objeto, e oLivingRoom
objeto também tenha umTV
objeto dentro.O método mais simples para conseguir isso é fazer com que cada objeto crie seus filhos em seu método de construção, mas se as propriedades estiverem relativamente aninhadas, quando você
House
falhar na criação, provavelmente passará algum tempo tentando isolar exatamente o que está falhando.A alternativa é fazer o seguinte (injeção de dependência, se você gosta do termo sofisticado):
Aqui, se o processo de criação de uma
House
falha falhar, há apenas um lugar para procurar, mas ter que usar essa parte toda vez que alguém quiser um novoHouse
está longe de ser conveniente. Entre nas fábricas:Graças à fábrica aqui, o processo de criação de um
House
é abstraído (pois você não precisa criar e configurar todas as dependências quando deseja apenas criar umHouse
) e ao mesmo tempo centralizado, o que facilita a manutenção. Há outras razões pelas quais usar Fábricas separadas pode ser benéfico (por exemplo, testabilidade), mas acho esse caso de uso específico para ilustrar melhor como as classes Factory podem ser úteis.fonte
HouseFactory
classe?create
método. Por exemplo, se vocêHouse
sempre tiver o mesmo tipoLivingRoom
, pode fazer sentido ter seus parâmetros codificados na classe factory em vez de passar como argumentos. Ou você pode fornecer umtype
argumento para o seuHouseFactory::create
método se tiver alguns tipos de se houverLivingRoom
uma opção interna com os parâmetros codificados para cada tipo.É importante diferenciar claramente a idéia por trás do uso de fábrica ou método de fábrica. Ambos destinam-se a abordar diferentes tipos de problemas de criação de objetos, mutuamente exclusivos.
Vamos ser específicos sobre o "método de fábrica":
A primeira coisa é que, quando você estiver desenvolvendo bibliotecas ou APIs que, por sua vez, serão usadas para desenvolvimento adicional de aplicativos, o método factory será uma das melhores opções para o padrão de criação. Razão para trás; Sabemos que, quando criar um objeto com a (s) funcionalidade (s) necessária (s), o tipo de objeto permanecerá indeciso ou será decidido pelos parâmetros dinâmicos passados .
Agora, o ponto é que aproximadamente o mesmo pode ser alcançado usando o próprio padrão de fábrica, mas uma grande desvantagem será introduzida no sistema se o padrão de fábrica for usado para o problema destacado acima, é que sua lógica de criar objetos diferentes (objetos de subclasses) seja específico a alguma condição de negócios; portanto, no futuro, quando você precisar estender a funcionalidade da sua biblioteca para outras plataformas (em mais tecnicamente, você precisará adicionar mais subclasses de interface básica ou abstrata, para que o factory retorne esses objetos, além do existente) com base em alguns parâmetros dinâmicos), toda vez que você precisar alterar (estender) a lógica da classe de fábrica, que será uma operação dispendiosa e não boa da perspectiva do projeto. Por outro lado, se "método de fábrica"
fonte
Eles também são úteis quando você precisa de vários "construtores" com o mesmo tipo de parâmetro, mas com comportamento diferente.
fonte
É uma boa idéia usar métodos de fábrica dentro do objeto quando:
É uma boa idéia usar a classe abstrata de fábrica quando:
fonte
UML de
Produto: define uma interface dos objetos que o método Factory cria.
ConcreteProduct: Implementa a interface do produto
Criador: declara o método Factory
ConcreateCreator: implementa o método Factory para retornar uma instância de um ConcreteProduct
Declaração do problema: Crie um Factory of Games usando o Factory Methods, que define a interface do jogo.
Fragmento de código:
resultado:
Este exemplo mostra uma
Factory
classe implementando aFactoryMethod
.Game
é a interface para todos os tipos de jogos. Ele define um método complexo:createGame()
Chess, Ludo, Checkers
são diferentes variantes de jogos, que fornecem implementação paracreateGame()
public Game getGame(String gameName)
estáFactoryMethod
naIGameFactory
aulaGameFactory
pré-cria diferentes tipos de jogos no construtor. Implementa oIGameFactory
método de fábrica.O nome do jogo é passado como argumento de linha de comando para
NotStaticFactoryDemo
getGame
inGameFactory
aceita um nome de jogo e retorna oGame
objeto correspondente .Fábrica:
FactoryMethod
Caso de uso:
Quando usar:
Client
não sabe quais classes concretas serão necessárias para criar em tempo de execução, mas apenas deseja obter uma classe que fará o trabalho.fonte
getArea()
não é um método de fábrica em tudo .É realmente uma questão de gosto. As classes de fábrica podem ser abstraídas / com interface, conforme necessário, enquanto os métodos de fábrica são mais leves (e também tendem a ser testáveis, pois não têm um tipo definido, mas exigem um ponto de registro conhecido, semelhante a um serviço localizador, mas para localizar métodos de fábrica).
fonte
As classes de fábrica são úteis para quando o tipo de objeto que eles retornam possui um construtor privado, quando diferentes classes de fábrica definem propriedades diferentes no objeto de retorno ou quando um tipo de fábrica específico é associado ao seu tipo de concreto de retorno.
O WCF usa as classes ServiceHostFactory para recuperar objetos ServiceHost em diferentes situações. O ServiceHostFactory padrão é usado pelo IIS para recuperar instâncias do ServiceHost para arquivos .svc , mas um WebScriptServiceHostFactory é usado para serviços que retornam serializações para clientes JavaScript. O ADO.NET Data Services possui seu próprio DataServiceHostFactory e o ASP.NET possui seu ApplicationServicesHostFactory, pois seus serviços possuem construtores particulares.
Se você tiver apenas uma classe que está consumindo a fábrica, basta usar um método de fábrica nessa classe.
fonte
Considere um cenário em que você deve criar uma classe de Pedido e Cliente. Por questões de simplicidade e requisitos iniciais, você não sente necessidade de fábrica para a classe Order e preenche seu aplicativo com muitas instruções 'new Order ()'. As coisas estão funcionando bem.
Agora, surge um novo requisito: o objeto Order não pode ser instanciado sem a associação do Cliente (nova dependência). Agora você tem as seguintes considerações.
1- Você cria sobrecarga de construtor que funcionará apenas para novas implementações. (Não aceitável). 2- Você altera as assinaturas de Order () e altera cada invocação. (Não é uma boa prática e muita dor).
Em vez disso, se você criou uma fábrica para a classe de pedidos, é necessário alterar apenas uma linha de código e pronto. Sugiro classe Factory para quase todas as associações agregadas. Espero que ajude.
fonte
se você deseja criar um objeto diferente em termos de uso. É útil.
fonte
Qualquer classe que adie a criação do objeto para sua subclasse para o objeto com o qual ele precisa trabalhar pode ser vista como um exemplo do padrão Factory.
Mencionei em detalhes em outra resposta em https://stackoverflow.com/a/49110001/504133
fonte
Eu acho que vai depender do grau de acoplamento solto que você deseja trazer para o seu código.
O método de fábrica desacopla as coisas muito bem, mas a classe de fábrica não.
Em outras palavras, é mais fácil mudar as coisas se você usar o método de fábrica do que se usar uma fábrica simples (conhecida como classe de fábrica).
Veja este exemplo: https://connected2know.com/programming/java-factory-pattern/ . Agora, imagine que você quer trazer um novo animal. Na classe Factory, você precisa alterar a Factory, mas no método factory, não, você só precisa adicionar uma nova subclasse.
fonte
As classes de fábrica são mais pesadas, mas oferecem algumas vantagens. Nos casos em que você precisa construir seus objetos a partir de várias fontes de dados brutas, elas permitem que você encapsule apenas a lógica da construção (e talvez a agregação dos dados) em um único local. Lá, ele pode ser testado em abstrato sem se preocupar com a interface do objeto.
Eu achei esse um padrão útil, particularmente onde não consigo substituir e ORM inadequado e quero instanciar com eficiência muitos objetos de junções de tabela de DB ou procedimentos armazenados.
fonte
Eu comparo as fábricas ao conceito de bibliotecas. Por exemplo, você pode ter uma biblioteca para trabalhar com números e outra para trabalhar com formas. Você pode armazenar as funções dessas bibliotecas em diretórios nomeados logicamente como
Numbers
ouShapes
. Estes são tipos genéricos que podem incluir números inteiros, flutuadores, dobules, compridos ou retângulos, círculos, triângulos, pentágonos no caso de formas.O petter de fábrica usa polimorfismo, injeção de dependência e inversão de controle.
O objetivo declarado dos Padrões de Fábrica é:
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Então, digamos que você esteja construindo um sistema operacional ou estrutura e todos os componentes discretos.
Aqui está um exemplo simples do conceito do Factory Pattern em PHP. Posso não estar 100% em tudo isso, mas pretende servir como um exemplo simples. Eu não sou um especialista.
fonte
NumbersFactory::makeNumber( 'float', 12.5 );
me deixando apenas dizendonew Float(12.5);
se eu sei que preciso de umFloat
? É isso que eu não entendo sobre as fábricas ... qual é o objetivo?