Sei que existem muitos posts sobre as diferenças entre esses dois padrões, mas há algumas coisas que não consigo encontrar.
Pelo que tenho lido, vejo que o padrão do método de fábrica permite definir como criar um único produto concreto, mas ocultando a implementação do cliente, pois eles verão um produto genérico. Minha primeira pergunta é sobre a fábrica abstrata. Seu papel é permitir que você crie famílias de objetos concretos (que podem depender de qual fábrica específica você usa), em vez de apenas um único objeto concreto? A fábrica abstrata retorna apenas um objeto muito grande ou muitos objetos, dependendo de quais métodos você chama?
Minhas duas perguntas finais são sobre uma única citação que não consigo entender completamente que já vi em vários lugares:
Uma diferença entre os dois é que, com o padrão Abstract Factory, uma classe delega a responsabilidade da instanciação de objeto para outro objeto por meio de composição, enquanto o padrão Factory Method usa herança e depende de uma subclasse para lidar com a instanciação de objeto desejada.
Meu entendimento é que o padrão do método de fábrica possui uma interface Creator que fará com que o ConcreteCreator se encarregue de saber qual produto concreto instanciar. É isso o que significa usar herança para manipular instanciação de objeto?
Agora, com relação a essa citação, como exatamente o padrão Abstract Factory delega a responsabilidade da instanciação do objeto para outro objeto via composição? O que isto significa? Parece que o padrão Abstract Factory também usa herança para fazer o processo de construção também aos meus olhos, mas, novamente, ainda estou aprendendo sobre esses padrões.
Qualquer ajuda, especialmente com a última pergunta, seria muito apreciada.
Respostas:
A diferença entre os dois
A principal diferença entre um "método de fábrica" e uma "fábrica abstrata" é que o método de fábrica é um método único e uma fábrica abstrata é um objeto. Acho que muitas pessoas confundem esses dois termos e começam a usá-los de forma intercambiável. Lembro que tive dificuldade em encontrar exatamente qual era a diferença quando as aprendi.
Como o método factory é apenas um método, ele pode ser substituído em uma subclasse, daí a segunda metade da sua citação:
A cotação assume que um objeto está chamando seu próprio método de fábrica aqui. Portanto, a única coisa que poderia alterar o valor de retorno seria uma subclasse.
A fábrica abstrata é um objeto que possui vários métodos de fábrica. Olhando para a primeira metade da sua citação:
O que eles estão dizendo é que existe um objeto A, que quer fazer um objeto Foo. Em vez de criar o objeto Foo em si (por exemplo, com um método de fábrica), ele obterá um objeto diferente (a fábrica abstrata) para criar o objeto Foo.
Exemplos de código
Para mostrar a diferença, aqui está um método de fábrica em uso:
E aqui está uma fábrica abstrata em uso:
fonte
SpecialFoo
para ficar mais claro.Abstract factory cria uma classe base com métodos abstratos que definem métodos para os objetos que devem ser criados. Cada classe de fábrica que deriva da classe base pode criar sua própria implementação de cada tipo de objeto.
O método Factory é apenas um método simples usado para criar objetos em uma classe. Geralmente é adicionado à raiz agregada (a
Order
classe tem um método chamadoCreateOrderLine
)Fábrica abstrata
No exemplo abaixo, projetamos uma interface para poder dissociar a criação de filas de um sistema de mensagens e, portanto, criar implementações para diferentes sistemas de filas sem precisar alterar a base de código.
Método de fábrica
O problema nos servidores HTTP é que sempre precisamos de uma resposta para cada solicitação.
Sem o método de fábrica, os usuários do servidor HTTP (ou seja, programadores) seriam forçados a usar classes específicas de implementação que anulam o objetivo da
IHttpRequest
interface.Portanto, introduzimos o método factory para que a criação da classe de resposta também seja abstraída.
Sumário
A diferença é que o objetivo pretendido da classe que contém um método factory não é criar objetos , enquanto uma fábrica abstrata deve ser usada apenas para criar objetos.
Deve-se tomar cuidado ao usar métodos de fábrica, pois é fácil quebrar o LSP ( princípio de substituição de Liskov ) ao criar objetos.
fonte
Button()
para criar uma "família de produtos relacionados". Por exemplo, o exemplo canônico do GoF criaScrollBar()
eWindow()
. A vantagem é que a Abstract Factory pode aplicar um tema comum em seus múltiplos produtos.As diferenças entre os padrões de design AbstractFactory e Factory são as seguintes:
Implementação de padrão de método de fábrica:
Implementação abstrata de padrão de fábrica:
fonte
A principal diferença entre Abstract Factory e Factory Method é que Abstract Factory é implementado pela Composition ; mas o Método de Fábrica é implementado pela Herança .
Sim, você leu corretamente: a principal diferença entre esses dois padrões é o antigo debate sobre composição versus herança .
Os diagramas UML podem ser encontrados no livro (GoF). Desejo fornecer exemplos de código, porque acho que a combinação dos exemplos das duas principais respostas neste segmento fornecerá uma demonstração melhor do que qualquer uma das respostas. Além disso, usei a terminologia do livro nos nomes de classe e método.
Fábrica abstrata
Método de fábrica
ConcreteCreator
é o cliente. Em outras palavras, o cliente é uma subclasse cujo pai define ofactoryMethod()
. É por isso que dizemos que o Método de Fábrica é implementado pela Herança.Creator
classe (pai) invoca a sua própriafactoryMethod()
. Se removermosanOperation()
da classe pai, deixando apenas um único método para trás, ele não será mais o padrão Factory Method. Em outras palavras, o Método de Fábrica não pode ser implementado com menos de dois métodos na classe pai; e um deve invocar o outro.Misc. E padrões de fábricas diversas
Esteja ciente de que, embora o GoF defina dois padrões de fábrica diferentes, esses não são os únicos padrões de fábrica existentes. Eles não são necessariamente os padrões de fábrica mais usados. Um terceiro exemplo famoso é o Static Factory Pattern de Josh Bloch da Effective Java. O livro Head First Design Patterns inclui ainda outro padrão que eles chamam de Simple Factory.
Não caia na armadilha de assumir que todos os padrões de fábrica devem corresponder a um do GoF.
fonte
factoryMethod()
Sempre deve ser oprotected
método no padrão "Factory Method"? (Eu acho que sim)public
métodos de fábrica, e o método nem precisa serabstract
; mas o ponto crítico é que o método é destinado à herança; portanto, não pode (por exemplo) serstatic
oufinal
. Eu criei o métodoprotected
eabstract
aqui para destacar a extensibilidade (necessária).Resumo O Factory é uma interface para a criação de produtos relacionados, mas o Factory Method é apenas um método. Resumo O Factory pode ser implementado por vários métodos de Factory.
fonte
Considere este exemplo para facilitar o entendimento.
O que as empresas de telecomunicações fornecem? Banda larga, linha telefônica e celular, por exemplo, e você é solicitado a criar um aplicativo para oferecer seus produtos a seus clientes.
Geralmente, o que você faria aqui é criar produtos, como banda larga, linha telefônica e celular, através do seu Método de Fábrica, onde você sabe quais propriedades possui para esses produtos e é bem direto.
Agora, a empresa deseja oferecer a seus clientes um pacote de seus produtos, como banda larga, linha telefônica e celular, e aqui vem a Abstract Factory para jogar.
A Abstract Factory é, em outras palavras, a composição de outras fábricas responsáveis pela criação de seus próprios produtos e a Abstract Factory sabe como colocar esses produtos em mais significado em relação às suas próprias responsabilidades.
Nesse caso, o
BundleFactory
é a Fábrica abstrataBroadbandFactory
,PhonelineFactory
eMobileFactory
é oFactory
. Para simplificar mais, essas fábricas terão o Método de Fábrica para inicializar os produtos individuais.Veja o exemplo de código abaixo:
Espero que isto ajude.
fonte
static
métodos no padrão de fábrica GoF. Isto está errado.Exemplo da vida real. (Fácil de lembrar)
Fábrica
Imagine que você está construindo uma casa e se aproxima de um carpinteiro em busca de uma porta. Você dá a medida da porta e seus requisitos, e ele construirá uma porta para você. Nesse caso, o carpinteiro é uma fábrica de portas. Suas especificações são entradas para a fábrica e a porta é a saída ou produto da fábrica.
Fábrica abstrata
Agora, considere o mesmo exemplo da porta. Você pode ir a um carpinteiro ou a uma loja de portas de plástico ou a uma loja de PVC. Todos eles são fábricas de portas. Com base na situação, você decide que tipo de fábrica precisa abordar. Isto é como uma fábrica abstrata.
Expliquei aqui o padrão do método Factory e o padrão abstrato de fábrica, começando por não usá-los, explicando problemas e resolvendo problemas usando os padrões acima https://github.com/vikramnagineni/Design-Patterns/tree/master
fonte
Vamos deixar claro que na maioria das vezes no código de produção, usamos o padrão abstrato de fábrica porque a classe A é programada com a interface B. E A precisa criar instâncias de B. Portanto, A precisa ter um objeto de fábrica para produzir instâncias de B Portanto, A não depende de nenhuma instância concreta de B. Espero que ajude.
fonte
Entenda as diferenças nas motivações:
Suponha que você esteja construindo uma ferramenta na qual tenha objetos e uma implementação concreta das inter-relações dos objetos. Como você prevê variações nos objetos, criou um indireto atribuindo a responsabilidade de criar variantes dos objetos para outro objeto ( chamamos de fábrica abstrata ). Essa abstração encontra um grande benefício, pois você prevê futuras extensões que precisam de variantes desses objetos.
Outra motivação bastante intrigante nessa linha de pensamento é um caso em que todos ou nenhum dos objetos de todo o grupo terá uma variante correspondente. Com base em algumas condições, qualquer uma das variantes será usada e, em cada caso, todos os objetos devem ser da mesma variante. Isso pode ser um pouco contra-intuitivo de entender, pois costumamos pensar que - desde que as variantes de um objeto sigam um contrato uniforme comum ( interface em sentido mais amplo ), o código de implementação concreto nunca deve quebrar. O fato intrigante aqui é que, nem sempre isso é verdade, especialmente quando o comportamento esperado não pode ser modelado por um contrato de programação.
Um simples ( emprestando a idéia do GoF ) é qualquer aplicativo GUI, como um monitor virtual que simula a aparência de MS ou Mac ou Fedora OS. Aqui, por exemplo, quando todos os objetos de widget, como janela, botão, etc. possuem variante MS, exceto uma barra de rolagem derivada da variante MAC, o objetivo da ferramenta falha muito.
Esses casos acima formam a necessidade fundamental do Abstract Factory Pattern .
Por outro lado, imagine que você esteja escrevendo uma estrutura para que muitas pessoas possam criar várias ferramentas ( como a dos exemplos acima ) usando sua estrutura. Pela própria idéia de uma estrutura, você não precisa, embora não possa usar objetos concretos em sua lógica. Você prefere colocar alguns contratos de alto nível entre vários objetos e como eles interagem. Enquanto você ( como desenvolvedor de estrutura ) permanece em um nível muito abstrato, cada construtor da ferramenta é forçado a seguir suas construções de estrutura. No entanto, eles ( os construtores de ferramentas ) têm a liberdade de decidir qual objeto será construído e como todos os objetos que eles criarão interagirão. Diferentemente do caso anterior ( do Abstract Factory Pattern ), você ( como criador da estrutura) não precisa trabalhar com objetos concretos nesse caso; e, em vez disso, pode permanecer no nível de contrato dos objetos. Além disso, diferentemente da segunda parte das motivações anteriores, você ou os fabricantes de ferramentas nunca têm a situação de misturar objetos de variantes. Aqui, enquanto o código da estrutura permanece no nível do contrato, todo construtor de ferramentas fica restrito ( pela natureza do caso ) a usar seus próprios objetos. Neste caso, as criações de objetos são delegadas a cada implementador e provedores de estrutura apenas fornecem métodos uniformes para criar e retornar objetos. Tais métodos são inevitáveis para o desenvolvedor da estrutura prosseguir com seu código e tem um nome especial chamado método Factory ( Factory Method Pattern para o padrão subjacente ).
Algumas notas:
Código de amostra:
fonte
Sim. A intenção da Abstract Factory é:
Idealmente, ele deve retornar um objeto por cada método que o cliente está chamando.
Sim. O método de fábrica usa herança.
AbstractFactory define um FactoryMethod e ConcreteFactory é responsável pela construção de um ConcreteProduct. Basta seguir o exemplo de código deste artigo .
Você pode encontrar mais detalhes nas postagens relacionadas do SE:
Qual é a diferença básica entre os padrões de fábrica e abstrato de fábrica?
Padrões de Design: Método Fábrica x Fábrica vs Fábrica Abstrata
fonte
O método Factory depende da herança: a criação de objetos é delegada às subclasses, que implementam o método factory para criar objetos.
Resumo O Factory depende da composição do objeto: a criação do objeto é implementada nos métodos expostos na interface do factory.
Diagrama de alto nível de fábrica e padrão de fábrica abstrata,
Para mais informações sobre o método Factory, consulte este artigo .
Para obter mais informações sobre o método abstrato de fábrica, consulte este artigo .
fonte
Para torná-lo muito simples, com interface mínima, focalize "// 1":
Aqui pontos importantes: 1. Os mecanismos Factory & AbstractFactory devem usar herança (System.Object-> byte, float ...); portanto, se você tiver herança no programa, o Factory (Abstract Factory provavelmente não estaria lá) provavelmente já existe por design 2. O Creator (MyFactory) conhece o tipo concreto, então retorna o objeto do tipo concreto ao responsável pela chamada (Principal); Em resumo, o tipo de retorno de fábrica seria uma interface.
Pontos importantes: 1. Requisito: a Honda criaria "Regular", "Sports", mas o Hero criaria "DarkHorse", "Sports" e "Scooty". 2. por que duas interfaces? Um para o tipo de fabricante (IVehicleFactory) e outro para a fábrica do produto (IVehicle); outra maneira de entender duas interfaces é que a fábrica abstrata tem tudo a ver com a criação de objetos relacionados. então eu recebo a variável pai (IVehicle); então, crio o tipo concreto real chamando CreateSingleVehicle e, em seguida, convertendo o objeto pai para o objeto filho real. O que aconteceria se eu fizesse
RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
; você obterá ApplicationException e é por isso que precisamos de uma fábrica abstrata genérica que eu explicaria se necessário.fonte
Fábrica abstrata : Uma fábrica de fábricas; uma fábrica que agrupa as fábricas individuais, mas relacionadas / dependentes, sem especificar suas classes concretas. Exemplo abstrato de fábrica
Fábrica : fornece uma maneira de delegar a lógica da instanciação para classes filho. Exemplo de padrão de fábrica
fonte
Eu preferiria o Abstract Factory sobre o Factory Method a qualquer momento. A partir do exemplo de Tom Dalling (ótima explicação), podemos ver que o Abstract Factory é mais compostável, pois tudo o que precisamos fazer é passar um Factory diferente para o construtor (injeção de dependência do construtor em uso aqui). Mas o Factory Method exige que introduzamos uma nova classe (mais coisas para gerenciar) e use subclassificação. Sempre prefira composição ao invés de herança.
fonte
permita-me colocá-lo com precisão. a maioria das respostas já foi explicada, fornecendo diagramas e exemplos também. então minha resposta seria apenas um forro. minhas próprias palavras: - “o padrão abstrato de fábrica adiciona a camada abstrata em várias implementações de métodos de fábrica. significa que a fábrica abstrata contém ou compõe um ou mais de um padrão de método de fábrica "
fonte
Muitas das respostas acima não fornecem comparações de código entre o padrão Abstract Factory e o Factory Method. A seguir, minha tentativa de explicá-lo via Java. Espero que ajude alguém que precise de uma explicação simples.
fonte