Qual é a diferença entre os padrões de Fábrica e Estratégia?

Respostas:

226

Um padrão de fábrica é um padrão criacional. Um padrão de estratégia é um padrão operacional. Em outras palavras, um padrão de fábrica é usado para criar objetos de um tipo específico. Um padrão de estratégia é usado para executar uma operação (ou conjunto de operações) de uma maneira específica. No exemplo clássico, uma fábrica pode criar diferentes tipos de Animais: Cachorro, Gato, Tigre, enquanto um padrão de estratégia executaria ações específicas, por exemplo, Mover; usando estratégias Run, Walk ou Lope.

De fato, os dois podem ser usados ​​juntos. Por exemplo, você pode ter uma fábrica que cria seus objetos de negócios. Pode usar estratégias diferentes com base no meio de persistência. Se seus dados forem armazenados localmente em XML, eles usariam uma estratégia. Se os dados fossem remotos em um banco de dados diferente, eles usariam outro.

tvanfosson
fonte
1
`Um padrão de estratégia é usado para executar uma operação (ou conjunto de operações) de uma maneira específica 'Significa operações sobre objetos?
OPV
32

O padrão de estratégia permite alterar polimorficamente o comportamento de uma classe.

O padrão de fábrica permite encapsular a criação de objetos.

Gary faz um ótimo argumento. Se você estiver usando o princípio de codificar para abstrações, em vez de "concreções", muitos padrões começarão a parecer variações de um tema.

jlembke
fonte
25

Apenas para adicionar ao que o tvanfosson disse, muitos padrões têm a mesma aparência na implementação. Ou seja, muitas você criou uma interface em que talvez não houvesse uma antes em seu código e, em seguida, criou várias implementações dessa interface. A diferença está em seu propósito e como eles são usados.

Gary Kephart
fonte
13
  • O padrão de fábrica (método).

Crie apenas instâncias concretas. Argumentos diferentes podem resultar em objetos diferentes. Depende da lógica etc.

  • O padrão de estratégia.

Encapsule o algoritmo (etapas) para executar uma ação. Então você pode mudar a estratégia e usar outro algoritmo.

Embora ambos pareçam muito semelhantes, o objetivo é bastante diferente, um objetivo é criar o outro e executar uma ação.

Assim. Se o seu método de fábrica for fixo, você pode ter o seguinte:

 public Command getCommand( int operatingSystem ) { 
      switch( operatingSystem ) { 
           case UNIX    :
           case LINUX   : return new UnixCommand();
           case WINDOWS : return new WindowsCommand();
           case OSX     : return new OSXCommand();
       }
  }

Mas suponha que sua fábrica precise de uma criação mais avançada ou dinâmica. Você pode adicionar ao método de fábrica uma estratégia e alterá-la sem precisar recompilar, a estratégia pode mudar em tempo de execução.

OscarRyz
fonte
Eu não acho que você está fazendo o ponto certo aqui. Primeiro de tudo, uma das razões desses padrões é evitar condicionais em favor do polimorfismo. Antes de tudo, é preciso fazer uma diferença entre fábrica simples e fábrica abstrata.d O primeiro é uma fábrica simples, onde você só tem uma classe que atua como fábrica para criação de objetos, enquanto que no último você se conecta a uma interface e depois chama as diferentes fábricas que implementam essa interface que deveriam ter implementações diferentes do mesmo método com base em alguns critérios. (continuação)
interboy 27/01
4
Exatamente nesse caso, resulta em um tipo de padrão de estratégia, mas difere semanticamente porque é usado para criação de objetos e não para operações. Então, basicamente você tem a criação de objetos usando diferentes estratégias.
Interboy
2
@OscarRyz você pode por favor actualizar a sua resposta com um programa descrevendo tanto
Prakash Pandey
11

Antes de tudo, deve ser feita uma diferença entre fábrica simples e fábrica abstrata. O primeiro é uma fábrica simples, na qual você tem apenas uma classe que atua como fábrica para a criação de objetos, enquanto no último você se conecta a uma interface de fábrica (que define os nomes dos métodos) e depois chama as diferentes fábricas que implementam essa interface. devem ter implementações diferentes do mesmo método com base em alguns critérios. Por exemplo, temos uma interface ButtonCreationFactory, que é implementada por duas fábricas, o primeiro WindowsButtonCreationFactory (cria botões com aparência e sensação do Windows) e o segundo LinuxButtonCreationFactory (cria botões com aparência e sensação do Linux). Portanto, ambas as fábricas têm o mesmo método de criação com diferentes implementações (algoritmos).

Por exemplo, se você deseja que os botões com o Linux sejam visualizados:

ButtonCreationFactory myFactory = new LinuxButtonCreationFactory();
Button button1 = myFactory.createButton(...);

ou se você quiser botões do Windows

ButtonCreationFactory myFactory = new WindowsButtonCreationFactory();
Button button1 = myFactory.createButton(...);

Exatamente neste caso, resulta em um tipo de padrão de estratégia, pois diferencia algoritmos para fazer alguma criação. No entanto, ele difere semanticamente porque é usado para criação de objetos em vez de algoritmos operacionais. Portanto, basicamente na fábrica abstrata, você tem a criação de objetos usando estratégias diferentes, o que a torna muito semelhante ao padrão de estratégia. No entanto, o AbstractFactory é criacional, enquanto o padrão de estratégia está operacional. Em termos de implementação, eles resultam iguais.

interboy
fonte
10

Fábrica (e FactoryMethod retornado pela Fábrica) :

  1. Padrão criacional
  2. Baseado na herança
  3. Factory retorna um Método de Fábrica (interface) que, por sua vez, retorna Objeto Concreto
  4. É possível substituir novos objetos concretos pela interface e o cliente (responsável pela chamada) não deve estar ciente de todas as implementações concretas
  5. O cliente sempre acessa apenas a interface e você pode ocultar os detalhes da criação do objeto no método Factory

Dê uma olhada neste artigo da wikipedia e no artigo javarevisited

Padrão de estratégia:

  1. É um padrão comportamental
  2. É baseado em delegação
  3. Altera as tripas do objeto, modificando o comportamento do método
  4. É usado para alternar entre a família de algoritmos
  5. Altera o comportamento do objeto em tempo de execução

Exemplo:

Você pode configurar a estratégia de desconto para um item específico (bilhete AirFare ou item ShoppingCart). Neste exemplo, você oferecerá 25% de desconto em um item durante julho - dezembro e nenhum desconto no item durante o período de junho a junho.

Mensagens relacionadas:

Exemplo do mundo real do padrão de estratégia

Padrões de Design: Método Fábrica x Fábrica vs Fábrica Abstrata

Ravindra babu
fonte
3

Para estender o que Oscar disse e em referência ao seu código:

O getCommand é o Factory e as classes UnixCommand, WindowsCommand e OSXCommand são Strategies


fonte
3

O padrão de estratégia em termos simples é mais a criação de comportamentos em tempo de execução, nos quais você não está preocupado com a classe de implementação. Por outro lado, a fábrica tinha a criação em tempo de execução da instância de classe concreta e cabe a você usar qualquer comportamento (método) exposto pela interface implementada.

Gurum
fonte
2

Você não pode entender a diferença simplesmente observando o código ou a categorização. Para entender os padrões GoF corretamente, procure suas intenções:

Estratégia: "Defina uma família de algoritmos, encapsule cada um e torne-os intercambiáveis. A estratégia permite que o algoritmo varie independentemente dos clientes que o utilizam".

Método de Fábrica: "Defina uma interface para criar um objeto, mas deixe as subclasses decidirem qual classe instanciar. O Método de Fábrica permite que uma classe adie a instanciação para subclasses."

E aqui está uma explicação elaborada sobre as intenções e as diferenças entre esses dois padrões: Diferença entre os padrões de design do Método de Fábrica e da Estratégia

Cristik
fonte
1

Posso discordar de Oscar, pois seu exemplo de implementação de fábrica é bastante acoplado e muito fechado, não admira que sua escolha seja o padrão de estratégia. Uma implementação de fábrica não deve depender da instanciação de um número fixo de classes específicas. Por exemplo:

public Command getCommand( int operatingSystem ) {        
   return commandTable.get(operatingSystem); 
}

...

public class WindowsCommand implements Command {
    ...
    static {
        CommandTable.getInstance().registerCommand(WIN_COMMAND_ID, new WindowsCommand());
    }

}

Eu acho que o critério mais apropriado para escolher um ou outro é principalmente os termos que você emprega para nomear suas classes e métodos, levando em consideração que todos devemos tender a programar para interfaces e não para classes e também focar no objetivo: nosso objetivo é determinar qual código será executado em tempo de execução. Dito isto, podemos alcançar o objetivo usando qualquer um dos dois padrões.

Rick B.
fonte
1

Estratégia e Fábrica são propósitos diferentes. Na estratégia, você tem a abordagem definida; usando esse padrão, você pode trocar o comportamento (algoritmos). Chegando à fábrica, existem muitas variações. Mas o padrão original da fábrica de estados do GO4 deixa a criação do objeto na classe filho. Aqui na fábrica, você está substituindo a instância completa, não o comportamento em que está interessado. Com isso, você substituirá o sistema completo, e não o algoritmo.

Brainchild
fonte
0

Padrão de fábrica é um padrão de criação, criado com propriedades especificadas (comportamento). enquanto no tempo de execução após a criação, você não altera suas propriedades (comportamento). portanto, se você precisar de propriedades diferentes (comportamento), precisará excluir o objeto e criar um novo objeto com as propriedades necessárias (comportamento). o que não é gud. enquanto no caso do padrão de estratégia, você pode alterar as propriedades (comportamento) no tempo de execução.

user1808932
fonte