Qual é a diferença básica entre os padrões de fábrica e abstrato de fábrica?
createThing()
) e Resumo da fábrica usa composição (indirecta é por exemplo, horizontal getFactory().createThing()
)
Qual é a diferença básica entre os padrões de fábrica e abstrato de fábrica?
createThing()
) e Resumo da fábrica usa composição (indirecta é por exemplo, horizontal getFactory().createThing()
)
Respostas:
Com o padrão Factory, você produz instâncias de implementações (Apple
, Banana
, Cherry
, etc.) de uma interface particular - digamos, IFruit
.
Com o padrão Abstract Factory, você fornece uma maneira de qualquer pessoa fornecer sua própria fábrica. Isso permite que seu armazém seja um IFruitFactory
ou umIJuiceFactory
, sem exigir que ele saiba algo sobre frutas ou sucos.
IFruit
- instancia as coisas que implementam IFruit
. Obviamente, ele não precisa produzir instâncias de coisas que implementam uma interface específica, mas provavelmente é um cheiro de código se você tiver um Factory que produz coisas totalmente não relacionadas umas às outras.
Fonte para essas informações: http://java.dzone.com/news/intro-design-patterns-abstract
Os métodos de uma fábrica abstrata são implementados como métodos de fábrica. O Abstract Factory Pattern e o Factory Method Pattern separam o sistema do cliente das classes de implementação reais por meio dos tipos e fábricas abstratos. O método Factory cria objetos por herança, onde o Abstract Factory cria objetos por composição.
O Abstract Factory Pattern consiste em um AbstractFactory, ConcreteFactory, AbstractProduct, ConcreteProduct e Client.
O Abstract Factory Pattern pode ser implementado usando o Factory Method Pattern, o Prototype Pattern ou o Singleton Pattern. O objeto ConcreteFactory pode ser implementado como um Singleton, pois apenas uma instância do objeto ConcreteFactory é necessária.
O padrão Factory Method é uma versão simplificada do padrão Abstract Factory. O padrão Factory Method é responsável por criar produtos que pertencem a uma família, enquanto o padrão Abstract Factory lida com várias famílias de produtos.
O Método de Fábrica usa interfaces e classes abstratas para separar o cliente da classe do gerador e dos produtos resultantes. Abstract Factory possui um gerador que é um contêiner para vários métodos de fábrica, juntamente com interfaces que separam o cliente do gerador e dos produtos.
Use o padrão Factory Method quando houver necessidade de dissociar um cliente de um produto específico que ele usa. Use o Método de Fábrica para aliviar a responsabilidade do cliente de criar e configurar instâncias de um produto.
Use o padrão Abstract Factory quando os clientes tiverem que ser dissociados das classes de produtos. Especialmente útil para configuração e modificação de programas. O padrão Abstract Factory também pode impor restrições sobre quais classes devem ser usadas com outras. Pode ser muito trabalho para fazer novas fábricas de concreto.
Essa especificação para os discos para preparar diferentes tipos de massas em uma máquina de fazer massas é a Abstract Factory, e cada disco específico é uma fábrica. todas as fábricas (discos de fabricação de massas) herdam suas propriedades da fábrica abstrata. Cada disco individual contém as informações de como criar a massa, e o fabricante da massa não.
O equipamento de estampagem corresponde à fábrica abstrata, pois é uma interface para operações que criam objetos abstratos do produto. As matrizes correspondem à Fábrica de Concreto, pois criam um produto concreto. Cada categoria de peça (capô, porta, etc.) corresponde ao produto abstrato. Peças específicas (por exemplo, porta do lado do motorista para 99 camry) correspondem aos produtos de concreto.
A empresa de brinquedos corresponde ao Criador, pois pode usar a fábrica para criar objetos de produtos. A divisão da empresa de brinquedos que fabrica um tipo específico de brinquedo (cavalo ou carro) corresponde ao ConcreteCreator.
Padrão de fábrica: a fábrica produz implementações de produtos IP
Resumo Padrão de fábrica: uma fábrica produz IFactories, que por sua vez produz IProducts :)
[Atualize de acordo com os comentários]
O que escrevi anteriormente não está correto, de acordo com a Wikipedia, pelo menos. Uma fábrica abstrata é simplesmente uma interface de fábrica. Com ele, você pode mudar suas fábricas em tempo de execução, para permitir diferentes fábricas em diferentes contextos. Exemplos podem ser fábricas diferentes para diferentes sistemas operacionais, provedores SQL, drivers de middleware etc.
Forneça uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.
O padrão Abstract Factory é muito semelhante ao padrão Factory Method. 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.
Na verdade, o objeto delegado freqüentemente usa métodos de fábrica para executar a instanciação!
Padrões de fábrica são exemplos de padrões criacionais
Os padrões criacionais abstraem o processo de instanciação do objeto. Eles ocultam como os objetos são criados e ajudam a tornar o sistema geral independente de como seus objetos são criados e compostos.
Os padrões de criação de classe se concentram no uso da herança para decidir o objeto a ser instanciado.
Os padrões de criação de objetos se concentram na delegação da instanciação para outro objeto Abstract Factory
Referência: Fábrica vs Fábrica Abstrata
Método de fábrica: você tem uma fábrica que cria objetos derivados de uma classe base específica
Fábrica abstrata: você tem uma fábrica que cria outras fábricas , e essas fábricas, por sua vez, criam objetos derivados de classes base. Você faz isso porque geralmente não deseja apenas criar um único objeto (como no método Factory). Em vez disso, deseja criar uma coleção de objetos relacionados.
Diferença básica:
Fábrica: cria objetos sem expor a lógica da instanciação ao cliente.
Método de Fábrica : Defina uma interface para criar um objeto, mas deixe as subclasses decidirem qual classe instanciar. O método Factory permite que uma classe adie a instanciação para subclasses
Fábrica abstrata : fornece uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes concretas.
O padrão AbstractFactory usa a composição para delegar a responsabilidade de criar objetos para outra classe enquanto o método Factory padrão de usa herança e depende da classe ou subclasse derivada para criar o objeto
De artigos de design próprio :
Diagrama de classe de fábrica :
Exemplo: StaticFactory
public class ShapeFactory {
//use getShape method to get object of type shape
public static Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
O Non-Static Factory que implementa o exemplo FactoryMethod está disponível nesta postagem:
Padrões de Design: Método Fábrica x Fábrica vs Fábrica Abstrata
Quando usar: O cliente precisa apenas de uma classe e não se importa com a implementação concreta que está recebendo.
Classe de Método de Fábrica digaram:
Quando usar: O cliente 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.
Diagrama de classe de fábrica abstrata de dzone
Quando usar: quando o sistema precisar criar várias famílias de produtos ou você desejar fornecer uma biblioteca de produtos sem expor os detalhes da implementação.
Os exemplos de código fonte nos artigos acima são muito bons para entender claramente os conceitos.
Pergunta SE relacionada com o exemplo de código:
Padrão de fábrica. Quando usar métodos de fábrica?
Diferenças:
Outros artigos úteis:
factory_method da produção de fontes
abstract_factory da produção de fontes
abstract-factory-design-pattern de journaldev
Exemplo / cenário para Abstract Factory
Eu moro em um lugar onde chove na estação chuvosa, neva no inverno e quente e ensolarado no verão. Eu preciso de diferentes tipos de roupas para me proteger dos elementos. Para fazer isso, vou à loja perto da minha casa e peço roupas / itens para me proteger. O dono da loja me fornece o item apropriado, de acordo com o ambiente e a profundidade do meu bolso. Os itens que ele me fornece são do mesmo nível de qualidade e faixa de preço. Como ele conhece os meus padrões, é fácil para ele fazê-lo. Mas quando um cara rico do outro lado da rua tem os mesmos requisitos, recebe um item caro e de marca. Uma coisa notável é que todos os itens que ele me fornece se complementam em termos de qualidade, padrão e custo. Pode-se dizer que eles vão um com o outro. O mesmo acontece com os itens que esse cara rico recebe.
Então, olhando para o cenário acima, agora aprecio a eficiência do lojista. Eu posso substituir esse lojista por uma loja abstrata. Os itens que obtemos com itens abstratos e eu e os ricos como clientes em perspectiva. Tudo o que precisamos é do produto / item que atenda às nossas necessidades.
Agora posso me ver facilmente considerando uma loja on-line que fornece um conjunto de serviços para seus inúmeros clientes. Cada cliente pertence a um dos três grupos. Quando um usuário do grupo premium abre o site, ele obtém uma excelente interface do usuário, painel de anúncios altamente personalizado, mais opções nos menus etc. Esses mesmos conjuntos de recursos são apresentados ao usuário gold, mas a funcionalidade no menu é menor, os anúncios são principalmente relevantes, e interface do usuário um pouco menos econômica. O último é o meu tipo de usuário, um usuário de 'grupo livre'. Sou apenas servido o suficiente para não ficar ofendido. A interface do usuário é um mínimo, os anúncios estão muito fora dos trilhos, de modo que eu não sei o que está nele; por fim, o menu só sai.
Se eu tiver a chance de criar algo como este site, eu definitivamente consideraria o Abstract Factory Pattern.
Produtos abstratos: Painel de propaganda, Menu, pintor de interface do usuário.
Abstract Factory: Experiência do Usuário da Web Store
Factory de Concreate: Experiência Premium do Usuário, Experiência do Usuário Gold, Experiência Geral do Usuário.
Muitas pessoas talvez se sintam surpresas, mas esta pergunta está incorreta . Se você ouvir essa pergunta durante uma entrevista, precisará ajudar o entrevistador a entender onde está a confusão.
Vamos começar pelo fato de que não existe um padrão concreto chamado apenas "Fábrica". Há um padrão que é chamado de "Fábrica Abstrata" e há um padrão que é chamado de "Método de Fábrica".
Então, o que significa "Fábrica" então? uma das seguintes opções (todas podem ser consideradas corretas, dependendo do escopo da referência):
E, infelizmente , muitas pessoas usam "Factory" para denotar outro tipo de fábrica, que cria fábricas ou fábricas (ou suas interfaces). Com base em sua teoria:
O produto implementa o IProduct, criado pela Factory, que implementa o IFactory, criado pelo AbstractFactory.
Para entender como isso é bobagem, vamos continuar nossa equação:
AbstractFactory implementa IAbstractFactory, criado por ... AbstractAbstractFactory ???
Espero que você entenda o ponto. Não fique confuso e, por favor, não invente coisas que não existem pela razão.
-
PS : Fábrica de produtos é AbstractFactory, e Fábrica de fábricas abstratas seria apenas mais um exemplo de AbstractFactory.
//Abstract factory - Provides interface to create factory of related products
interface PizzaIngredientsFactory{
public Dough createDough(); //Will return you family of Dough
public Clam createClam(); //Will return you family of Clam
public Sauce createSauce(); //Will return you family of Sauce
}
class NYPizzaIngredientsFactory implements PizzaIngredientsFactory{
@Override
public Dough createDough(){
//create the concrete dough instance that NY uses
return doughInstance;
}
//override other methods
}
As definições do livro de texto já são fornecidas por outras respostas. Também pensei em fornecer um exemplo disso.
Então aqui PizzaIngredientsFactory
está uma fábrica abstrata , pois fornece métodos para criar uma família de produtos relacionados.
Observe que cada método na fábrica abstrata é um método de fábrica em si. O Like createDough()
é em si um método de fábrica cujas implementações concretas serão fornecidas por subclasses do tipo NYPizzaIngredientsFactory
. Portanto, usar isso em cada local diferente pode criar instâncias de ingredientes concretos que pertencem ao local.
Fornece instância de implementação concreta
No exemplo:
- createDough()
- fornece implementação concreta para massa. Então este é um método de fábrica
Fornece interface para criar família de objetos relacionados
No exemplo:
- PizzaIngredientsFactory
é uma fábrica abstrata, pois permite criar um conjunto relacionado de objetos como Dough
, Clams
, Sauce
. Para criar cada família de objetos, ele fornece um método de fábrica.
Exemplo dos padrões de design do Head First
Tenho alguns pontos para contribuir com a resposta de John da seguinte forma:
Com o "Factory Method" (porque apenas "Factory" é ambígua), você produz implementações ( Lemon
, Orange
, etc.) de uma interface particular - digamos, IFruit
. Esta fábrica pode ser chamada CitricFruitFactory
.
Mas agora você deseja criar outros tipos de frutas que o CitricFruitFactory não pode criar. Talvez o código de CitricFruitFactory
não faça sentido se você criar um Strawberry
(o morango não é uma fruta cítrica!).
Assim, você poderá criar uma nova fábrica chamado RedFruitFactory
que produz Strawberry
, Raspberry
etc.
Como John Feminella disse:
"Com o padrão Abstract Factory, você produz implementações de uma interface Factory específica - por exemplo IFruitFactory
,. Cada um deles sabe como criar diferentes tipos de frutas".
Que implementatios de IFruitFactory
são CitricFruitFactory
e RedFruitFactory
!
Minhas fontes são: StackOverflow
, tutorialspoint.com
, programmers.stackexchange.com
e CodeProject.com
.
Factory Method
(também chamado Factory
) é para desacoplar o cliente de uma Interface
implementação. Por exemplo, temos uma Shape
interface com dois Circle
e Square
implementações. Definimos uma classe de fábrica com um método de fábrica com um parâmetro determinante, como uma Type
nova implementação de Shape
interface relacionada .
Abstract Factory
contém vários métodos de fábrica ou uma interface de fábrica por várias implementações de fábrica. Para o próximo exemplo acima, temos uma Color
interface com dois Red
e Yellow
implementações. Nós definimos uma ShapeColorFactory
interface com dois RedCircleFactory
e YellowSquareFactory
. O código a seguir para explicar esse conceito:
interface ShapeColorFactory
{
public Shape getShape();
public Color getColor();
}
class RedCircleFactory implements ShapeColorFactory
{
@Override
public Shape getShape() {
return new Circle();
}
@Override
public Color getColor() {
return new Red();
}
}
class YellowSquareFactory implements ShapeColorFactory
{
@Override
public Shape getShape() {
return new Square();
}
@Override
public Color getColor() {
return new Yellow();
}
}
Aqui diferença entre FactoryMethod
e AbstractFactory
. Factory Method
simplesmente retorne uma classe concreta de uma interface, mas Abstract Factory
retorne factory of factory
. Em outras palavras, Abstract Factory
retornam combinações diferentes de uma série de interfaces.
Espero que minha explicação seja útil.
A principal diferença nessas fábricas é quando o que você quer fazer com as fábricas e quando deseja usá-las.
Às vezes, quando você está executando o IOC (inversão de controle, por exemplo, injeção de construtor), sabe que pode criar objetos sólidos. Como mencionado no exemplo acima de frutas, se você estiver pronto para criar objetos de frutas, poderá usar um padrão de fábrica simples .
Mas muitas vezes, você não deseja criar objetos sólidos, eles virão mais tarde no fluxo do programa. Mas a configuração informa o tipo de fábrica que você deseja usar no início. Em vez de criar objetos, você pode passar fábricas derivadas de uma classe de fábrica comum para o construtor no IOC.
Então, acho que é também sobre o tempo de vida e a criação do objeto.
Ambos Factory Method
e Abstract Factory
manter os clientes dissociados dos tipos de concreto. Ambos criam objetos, mas o Factory
método usa herança enquanto Abstract Factory
usa composição.
O Factory Method
é herdado nas subclasses para criar objetos concretos (produtos), enquanto Abstract Factory
fornece interface para criar a família de produtos relacionados e a subclasse dessa interface define como criar produtos relacionados.
Em seguida, essas subclasses, quando instanciadas, são passadas para as classes de produtos onde são usadas como tipo abstrato. Os produtos relacionados em um Abstract Factory
são frequentemente implementados usando Factory Method
.
Estendendo a resposta de John Feminella:
Apple
, Banana
, Cherry
Implementos FruitFactory
e que tem um método chamado Create
, que é o único responsável de criação de maçã ou banana ou cereja. Você terminou, com seu Factory
método.
Agora, você quer Create
uma salada especial de suas frutas e aí chega a sua Abstract Factory . Abstract Factory sabe como criar sua salada especial com maçã, banana e cereja.
public class Apple implements Fruit, FruitFactory {
public Fruit Create() {
// Apple creation logic goes here
}
}
public class Banana implements Fruit, FruitFactory {
public Fruit Create() {
// Banana creation logic goes here
}
}
public class Cherry implements Fruit, FruitFactory {
public Fruit Create() {
// Cherry creation logic goes here
}
}
public class SpecialSalad implements Salad, SaladFactory {
public static Salad Create(FruitFactory[] fruits) {
// loop through the factory and create the fruits.
// then you're ready to cut and slice your fruits
// to create your special salad.
}
}
Por definição, podemos extrair as diferenças de dois:
Fábrica: Uma interface é usada para criar um objeto, mas a subclasse decide qual classe instanciar. A criação do objeto é feita quando necessário.
Fábrica abstrata: O padrão de fábrica abstrata atua como uma super-fábrica que cria outras fábricas. No padrão Abstract Factory, uma interface é responsável por criar um conjunto de objetos relacionados ou objetos dependentes sem especificar suas classes concretas.
Portanto, nas definições acima, podemos enfatizar uma diferença específica. isto é, o padrão Factory é responsável por criar objetos e o Abstract Factory é responsável por criar um conjunto de objetos relacionados; obviamente ambos através de uma interface.
Padrão de fábrica:
public interface IFactory{
void VehicleType(string n);
}
public class Scooter : IFactory{
public void VehicleType(string n){
Console.WriteLine("Vehicle type: " + n);
}
}
public class Bike : IFactory{
public void VehicleType(string n) {
Console.WriteLine("Vehicle type: " + n);
}
}
public interface IVehicleFactory{
IFactory GetVehicleType(string Vehicle);
}
public class ConcreteVehicleFactory : IVehicleFactory{
public IFactory GetVehicleType(string Vehicle){
switch (Vehicle){
case "Scooter":
return new Scooter();
case "Bike":
return new Bike();
default:
return new Scooter();
}
}
class Program{
static void Main(string[] args){
IVehicleFactory factory = new ConcreteVehicleFactory();
IFactory scooter = factory.GetVehicleType("Scooter");
scooter.VehicleType("Scooter");
IFactory bike = factory.GetVehicleType("Bike");
bike.VehicleType("Bike");
Console.ReadKey();
}
}
Teste padrão abstrato da fábrica:
interface IVehicleFactory{
IBike GetBike();
IScooter GetScooter();
}
class HondaFactory : IVehicleFactory{
public IBike GetBike(){
return new FZS();
}
public IScooter GetScooter(){
return new FZscooter();
}
}
class HeroFactory: IVehicleFactory{
public IBike GetBike(){
return new Pulsur();
}
public IScooter GetScooter(){
return new PulsurScooter();
}
}
interface IBike
{
string Name();
}
interface IScooter
{
string Name();
}
class FZS:IBike{
public string Name(){
return "FZS";
}
}
class Pulsur:IBike{
public string Name(){
return "Pulsur";
}
}
class FZscooter:IScooter {
public string Name(){
return "FZscooter";
}
}
class PulsurScooter:IScooter{
public string Name(){
return "PulsurScooter";
}
}
enum MANUFACTURERS
{
HONDA,
HERO
}
class VehicleTypeCheck{
IBike bike;
IScooter scooter;
IVehicleFactory factory;
MANUFACTURERS manu;
public VehicleTypeCheck(MANUFACTURERS m){
manu = m;
}
public void CheckProducts()
{
switch (manu){
case MANUFACTURERS.HONDA:
factory = new HondaFactory();
break;
case MANUFACTURERS.HERO:
factory = new HeroFactory();
break;
}
Console.WriteLine("Bike: " + factory.GetBike().Name() + "\nScooter: " + factory.GetScooter().Name());
}
}
class Program
{
static void Main(string[] args)
{
VehicleTypeCheck chk = new VehicleTypeCheck(MANUFACTURERS.HONDA);
chk.CheckProducts();
chk= new VehicleTypeCheck(MANUFACTURERS.HERO);
chk.CheckProducts();
Console.Read();
}
}
Verifique aqui: http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm parece que o método Factory usa uma classe específica (não abstrata) como classe base, enquanto o Abstract factory usa uma classe abstrata para isso. Além disso, se usar uma interface em vez da classe abstrata, o resultado será uma implementação diferente do padrão Abstract Factory.
: D
Abstract Factory é um modelo para criar diferentes tipos de interfaces. Suponha que você tenha um projeto que exija a análise de diferentes tipos de arquivos csv que contêm informações específicas sobre quantidade, preço e item, como alguns contêm dados sobre frutas e outros sobre chocolates e, após a análise, é necessário atualizar essas informações no banco de dados correspondente para que você possa ter uma fábrica abstrata retornando sua fábrica de analisadores e modificadores e, em seguida, essa fábrica de analisadores pode devolver o objeto Analisador de Chocolate, o Objeto Analisador de Frutas etc.
Acho que podemos entender a diferença entre esses dois vendo um código de exemplo Java8:
interface Something{}
interface OneWhoCanProvideSomething {
Something getSomething();
}
interface OneWhoCanProvideCreatorsOfSomething{
OneWhoCanProvideSomething getCreator();
}
public class AbstractFactoryExample {
public static void main(String[] args) {
//I need something
//Let's create one
Something something = new Something() {};
//Or ask someone (FACTORY pattern)
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;
//Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;
//Same thing, but you don't need to write you own interfaces
Supplier<Something> supplierOfSomething = () -> null;
Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
}
}
Agora, a pergunta é qual o caminho de criação que você deve usar e por quê: O primeiro caminho (sem padrão, apenas construtor simples): criar sozinho não é uma boa ideia, você deve fazer todo o trabalho e o código do cliente está vinculado a a implementação específica.
A segunda maneira (usando o padrão de fábrica): fornece o benefício de que você pode passar qualquer tipo de implementação, o que pode fornecer um tipo diferente de algo com base em alguma condição (talvez um parâmetro passado para o método criacional).
A terceira maneira (usando o padrão Abstract Factory): isso oferece mais flexibilidade. Você pode encontrar diferentes tipos de criadores de algo com base em alguma condição (talvez um parâmetro tenha sido passado).
Observe que você sempre pode se safar do padrão Factory combinando duas condições (o que aumenta levemente a complexidade do código e o acoplamento); acho que é por isso que raramente vemos casos de uso na vida real do padrão Abstract Factory.