Pergunta

Qual é a diferença básica entre os padrões Factory e Abstract Factory?

Foi útil?

Solução

Com o padrão de fábrica, você produz instâncias de implementações (Apple, Banana, Cherry, etc.) de uma interface específica - digamos, IFruit.

Com o padrão abstrato de fábrica, você fornece uma maneira de qualquer pessoa fornecer sua própria fábrica. Isso permite que seu armazém seja um IFruitFactory ou um IJuiceFactory, sem exigir que seu armazém saiba nada sobre frutas ou sucos.

Outras dicas

Fonte para essas informações obtidas de: http://java.dzone.com/news/intro-design-patterns-abstract

Método de fábrica abstrato vs. fábrica

Os métodos de uma fábrica abstrata são implementados como métodos de fábrica. Tanto o padrão abstrato de fábrica quanto o padrão de método da fábrica desompotam o sistema do cliente das classes de implementação reais através dos tipos e fábricas abstratas. O método da fábrica cria objetos através da herança, onde a fábrica abstrata cria objetos através da composição.

O padrão de fábrica abstrato consiste em um abstrato, concreto -fábrica, abstrato, product, concreto e cliente.

Como implementar

O padrão de fábrica abstrato pode ser implementado usando o padrão de método de fábrica, o padrão de protótipo ou o padrão de singleton. O objeto ConcreteFactory pode ser implementado como um singleton, pois apenas uma instância do objeto concreto é necessário.

O padrão de método da fábrica é uma versão simplificada do padrão de fábrica abstrato. O padrão de método da fábrica é responsável por criar produtos que pertencem a uma família, enquanto os padrões abstratos de fábrica lida com várias famílias de produtos.

O método da fábrica usa interfaces e classes abstratas para dissociar o cliente da classe geradora e dos produtos resultantes. A Factory Abstract possui um gerador que é um contêiner para vários métodos de fábrica, juntamente com as interfaces dissociando o cliente do gerador e dos produtos.

Quando usar o padrão de método da fábrica

Use o padrão de método de fábrica quando for necessário dissociar um cliente de um produto específico que ele usa. Use o método da fábrica para aliviar um cliente de responsabilidade por criar e configurar instâncias de um produto.

Quando usar o padrão de fábrica abstrato

Use o padrão abstrato de fábrica quando os clientes devem ser dissociados das classes de produtos. Especialmente útil para configuração e modificação do programa. O padrão de fábrica abstrato também pode aplicar restrições sobre quais classes devem ser usadas com outras pessoas. Pode ser muito trabalho fazer novas fábricas concretas.

Exemplos:

Exemplo de fábrica abstrata 1

Esta especificação para os discos prepararem diferentes tipos de massas em uma fabricante de massas é a fábrica abstrata, e cada disco específico é uma fábrica. Todas as fábricas (discos de fabricante de massas) herdam suas propriedades da fábrica abstrata. Cada disco individual contém as informações de como criar o macarrão, e o fabricante de massas não.

Exemplo de fábrica abstrata 2:

O equipamento de estampagem corresponde à fábrica abstrata, pois é uma interface para operações que criam objetos abstratos de produtos. As matrizes correspondem à fábrica de concreto, pois criam um produto de concreto. Cada categoria de peça (capô, porta, etc.) corresponde ao produto abstrato. Peças específicas (ou seja, porta lateral do motorista para 99 Camry) corresponde aos produtos de concreto.

Exemplo de método de fábrica:

A empresa de brinquedos corresponde ao Criador, pois pode usar a fábrica para criar objetos de produto. A divisão da empresa de brinquedos que fabrica um tipo específico de brinquedo (cavalo ou carro) corresponde ao concretecreador.

Padrão de fábrica: a fábrica produz implementação de iProduct

Padrão de fábrica abstrato: Uma fábrica de fábrica produz estatídicos, que por sua vez produz iprodutos :)

Atualizar de acordo com os comentários
O que escrevi anteriormente não está correto de acordo com 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 OS'es, fornecedores de SQL, drivers de middleware etc.

O padrão de fábrica abstrato

  • Forneça uma interface para criar famílias de objetos relacionados ou dependentes sem especificar suas classes de concreto.

  • O padrão de fábrica abstrato é muito semelhante ao padrão de método da fábrica. Uma diferença entre os dois é que, com o padrão de fábrica abstrato, uma classe delega a responsabilidade da instanciação do objeto a outro objeto por composição, enquanto o padrão de método da fábrica usa herança e depende de uma subclasse para lidar com a instanciação do objeto desejado.

  • Na verdade, o objeto delegado freqüentemente usa métodos de fábrica para executar a instanciação!

Padrão de fábrica

  • Padrões de fábrica são exemplos de padrões criativos

  • Padrões de criação abstraem o processo de instanciação do objeto. Eles escondem 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 criativos de classe concentram -se no uso da herança para decidir que o objeto é um método de fábrica instanciado

  • Os padrões criativos de objetos se concentram na delegação da instanciação a outro objeto abstrato de fábrica

Referência:Fábrica vs fábrica abstrata

Método da fábrica: Você tem uma fábrica que cria objetos que derivam 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 das classes base. Você faz isso porque geralmente não deseja apenas criar um único objeto (como no método da fábrica) - em vez disso, deseja criar uma coleção de objetos relacionados.

A Factory Abstract é uma interface para a criação de objetos relacionados, mas o método da fábrica é um método. A fábrica abstrata é implementada pelo método da fábrica.

enter image description here

Diferença básica:

Fábrica: Cria objetos sem expor a lógica de instanciação ao cliente.

Método da fábrica: Defina uma interface para criar um objeto, mas deixe as subclasses decidirem qual classe instanciar. O método da fábrica 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 de concreto.

AbstractFactory o padrão usa a composição para delegar a responsabilidade de criar objeto para outra classe enquanto Método da fábrica Pattern usa herança e depende de classe ou sub -classe derivada para criar objeto

A partir de Oodesign Artigos:

Fábrica Diagrama de aula:

enter image description here

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 exemplo não estático de fábrica de fábrica está disponível neste post:

Padrões de design: Factory vs Factory Method vs Abstract Factory

Quando usar: O cliente só precisa de uma aula e não se importa com qual implementação concreta está obtendo.

Método da fábrica Diaram da classe:

enter image description here

Quando usar: O cliente não sabe quais classes concretas ele será necessário para criar em tempo de execução, mas apenas deseja obter uma aula que fará o trabalho.

Fábrica abstrata Diagrama de classe de dzone

enter image description here

Quando usar: Quando seu sistema precisar criar várias famílias de produtos ou você deseja fornecer uma biblioteca de produtos sem expor os detalhes da implementação.

Exemplos de código -fonte nos artigos acima são muito bons para entender claramente os conceitos.

Pergunta relacionada a se com exemplo de código:

Padrão de fábrica. Quando usar métodos de fábrica?

Diferenças:

  1. As aulas de fábrica abstratas são frequentemente implementadas com métodos de fábrica, mas também podem ser implementados usando protótipo
  2. Os projetos começam usando o método de fábrica (subclasses menos complicadas, mais personalizáveis, proliferam) e evoluem para outros padrões criativos (mais flexíveis, mais complexos), onde é necessária mais flexibilidade.
  3. Os métodos de fábrica geralmente são chamados dentro dos métodos de modelo.

Outros artigos úteis:

Factory_method da fabricação de fontes

Resumo_factory da fabricação de fontes

Padrão de design de fábrica abstrato de JournalDev

Exemplo/cenário para fábrica abstrata

Eu moro em um lugar onde chove na estação das chuvas, neve no inverno e quente e ensolarado nos verões. 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 goleiro da loja me dá o item apropriado de acordo com o ambiente e a profundidade do meu bolso. Os itens que ele me dá são do mesmo nível de qualidade e faixa de preço. Como ele está ciente dos meus padrões, é fácil para ele fazê -lo. Mas quando um cara rico do outro lado da rua apresenta os mesmos requisitos, ele recebe um item caro e de marca. Uma coisa perceptível é que todos os itens que ele me dá se complementam em qualidade, padrão e custo de termo. 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 goleiro da loja. Posso substituir este lojista por uma loja abstrata. Os itens que recebemos 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 a seus numerosos clientes. Cada cliente pertence a um dos três grupos. Quando um usuário do grupo premium abre o site, ele recebe ótimo interface do usuário, painel de propaganda altamente personalizado, mais opções nos menus etc. Esse mesmo conjunto de recursos é apresentado ao usuário de ouro, mas a funcionalidade no menu é menor, os anúncios são principalmente relevantes, e uma interface do usuário egronômica um pouco menos. O último é o meu tipo de usuário, um usuário de 'grupo livre'. Estou apenas servido o suficiente para não ficar ofendido. A interface do usuário é um mínimo, os anúncios estão muito fora do caminho que eu não sei o que vem, por fim, o menu só está logofado.

Se eu tiver a chance de construir algo como este site, eu definitivamente consideraria um padrão abstrato de fábrica.

Produtos abstratos: painel de propaganda, menu, pintor da interface do usuário.
Resumo da fábrica: experiência do usuário da loja da web
Fábrica de concreto: experiência premium do usuário, experiência do usuário de ouro, experiência geral do usuário.

Muitas pessoas talvez se sintam surpresas, mas esta questão é incorreta.Se você ouvir essa pergunta durante uma entrevista, você precisa ajudar o entrevistador a entender onde está a confusão.

Vamos começar pelo fato de que não existe um padrão concreto que se chame apenas de “Fábrica”.Existe um padrão chamado "Fábrica Abstrata" e existe um padrão chamado "Método de Fábrica".

Então, o que significa "Fábrica"?uma das seguintes (todas podem ser consideradas corretas, dependendo do escopo da referência):

  • Algumas pessoas o usam como um alias (atalho) para "Fábrica Abstrata".
  • Algumas pessoas o usam como um alias (atalho) para "Método de fábrica".
  • Algumas pessoas o usam como um nome mais geral para todos os padrões de fábrica/criação.Por exemplo.tanto "Fábrica Abstrata" quanto "Método de Fábrica" ​​são Fábricas.

E, infelizmente, muitas pessoas usam "Fábrica" ​​para denotar outro tipo de fábrica, que cria fábrica ou fábricas (ou suas interfaces).Com base em sua teoria:

O produto implementa o iProduct, criado pela fábrica, que implementa o IfActory, que é criado pelo AbstractFactory.

Para entender o quão bobo isso é, vamos continuar nossa equação:

AbstractFactory implementa IAbstractFactory, que é criado por...ResumoResumoFábrica???

Espero que você entenda o ponto.Não se confunda e, por favor, não invente coisas que não existem por razão.

-

P.S.:Factory for Products é AbstractFactory, e Factory for Abstract Factories também seria apenas outro 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. Eu pensei em dar um exemplo disso também.

Então aqui o PizzaIngredientsFactory é um Fábrica abstrata como fornece métodos para criar família de produtos relacionados.

Observe que cada método na fábrica abstrata é um Método da fábrica nele mesmo. Curti createDough() é por si só um método de fábrica cujas implementações concretas serão fornecidas por subclasses como NYPizzaIngredientsFactory. Portanto, usar isso cada local diferente pode criar instâncias de ingredientes concretos que pertencem à sua localização.

Método da fábrica

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

Fábrica abstrata

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, fornece um método de fábrica.

Exemplo de Padrões de design da primeira cabeça

Tenho alguns pontos para contribuir com a resposta de John da seguinte forma:

A fábrica abstrata é uma fábrica de fábricas!

Com o "Método de Fábrica" ​​(porque apenas "Fábrica" ​​é ambíguo), você produz implementações (Lemon, Orange, etc.) de uma interface específica - digamos, IFruit.Esta fábrica poderia ser chamada CitricFruitFactory.

Mas agora você deseja criar outro tipo de fruta que o CitricFruitFactory não consegue criar.Talvez o código de CitricFruitFactory não faria sentido se você criasse um Strawberry nele (morango não é fruta cítrica!).

Então você poderia criar uma nova fábrica chamada 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 implementações 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 o cliente de decompar um Interface implementação. Para amostra, temos um 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 Type e nova implementação relacionada de Shape interface.


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 a próxima amostra acima, temos um Color Interface com dois Red e Yellow implementações. Nós definimos um ShapeColorFactory Interface com dois RedCircleFactory e YellowSquareFactory. Seguindo o código para explicar este 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 a diferença entre FactoryMethod e AbstractFactory. Factory Method como basta retornar uma classe concreta de uma interface, mas Abstract Factory Retorna factory of factory. Em outras palavras Abstract Factory Retorne diferentes combinações de uma série de interface.


Espero que minha explicação seja útil.

A principal diferença nessas fábricas é quando você deseja fazer com as fábricas e quando deseja usá -las.

Às vezes, quando você está realizando o COI (Inversão da injeção de construtor de controle), você sabe que pode criar objetos sólidos. Como mencionado no exemplo acima das frutas, se você estiver pronto para criar objetos de frutas, você pode usar simples padrão de fábrica.

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 transmitir fábricas derivadas de uma classe de fábrica comum para o construtor no COI.

Então, acho que também é sobre a vida e a criação do objeto.

Ambos Factory Method e Abstract Factory Mantenha os clientes dissociados dos tipos de concreto. Ambos criam objetos, mas Factory o método usa herança, enquanto Abstract Factory use composição.

o Factory Method é herdado em subclasses para criar os objetos concretos (produtos), enquanto Abstract Factory Forneça interface para criar a família de produtos relacionados e subclasse dessas interface, defina como criar produtos relacionados.

Em seguida, essas subclasses, quando instanciadas, são transmitidas para 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 John Feminella Resposta:

Apple, Banana, Cherry implementos FruitFactory E isso tem um método chamado Create O que é o único responsável por criar maçã ou banana ou cereja. Você terminou com o seu Factory método.

Agora você quer Create uma salada especial de suas frutas e lá vem o seu Fábrica abstrata. A fábrica abstrata sabe como criar sua salada especial a partir da 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 arrastar 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.

Resumo Fábrica: O padrão de fábrica abstrato atua como uma superfactory que cria outras fábricas. No padrão abstrato de fábrica, 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 em uma diferença específica. Ou seja, o padrão de fábrica é responsável por criar objetos e a fábrica abstrata é responsável por criar um conjunto de objetos relacionados; Obviamente, tanto 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();
 }
}

Padrão de fábrica abstrato:

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();
        }
    }

Check here: http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm it seems that Factory method uses a particular class(not abstract) as a base class while Abstract factory uses an abstract class for this. Also if using an interface instead of abstract class the result will be a different implementation of Abstract Factory pattern.

:D

Abstract Factory is template for creating different type of interfaces. Suppose you have project that requires you to parse different types of csv files containing quantity, price and item specific information like some contain data about fruits other about chocolates and then after parsing you need to update this information in their corresponding database so now you can have one abstract factory returning you parser and modifier factory and then this parser factory can return you Chocolate parser object,Fruit Parser Object etc. and similarly Modifier Factory can return Chocolate modifier object , Fruit Modifier object etc.

I think we can understand the difference between these two by seeing a Java8 example code:

  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;
    }

}

Now the question is which way of creation should you use and why: The first way (no pattern, just plain constructor): creating by yourself is not a good idea, you have to do all the work, and your client code is tied to the particular implementation.

The second way (using Factory pattern): provides you the benefit that you can pass any type of implementation, which can provide different type of something based on some condition (maybe a parameter passed to creational method).

The third way (using Abstract Factory pattern): This gives you more flexibility. You can find different types of creators of something based on some condition (maybe a parameter passed).

Note that you can always get away with Factory pattern by combining two conditions together (which slightly increases code complexity, and coupling), I guess that's why we rarely see real life use cases of Abstract Factory pattern.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top