Design de software

Diferenças entre Factory Method e Abstract Factory

O Factory Method do GoF delega às subclasses a decisão do tipo concreto de um objeto, enquanto o Abstract Factory cria uma família de objetos relacionados. Comparamos a intenção e os critérios de escolha dos dois padrões usando exemplos em Swift.

4 min de leitura
Imagem de capa de Diferenças entre Factory Method e Abstract Factory

Ao estudar padrões de projeto, existe um ponto em que quase todo mundo trava pelo menos uma vez.

É o Factory Method vs Abstract Factory. Os nomes são parecidos e ambos «criam objetos no nosso lugar», então é muito fácil confundir os dois.

Também é uma pergunta frequente em entrevistas, por isso deixei tudo resumido neste artigo.

Vamos direto ao ponto. Factory Method deixa a cargo das subclasses a decisão de qual classe usar para criar um objeto. Abstract Factory cria de uma vez vários objetos relacionados, ou seja, uma família de produtos.

Um factory estático que dá nome à criação, como static func make, é diferente do Factory Method do GoF. Se você quer entender o design de APIs na prática, vale separar primeiro esse conceito de Factory Method estático em Swift.

Um objeto ou um conjunto? Essa é a maior diferença.

O que é Factory Method?

Factory Method é um padrão que transfere para as subclasses a responsabilidade de criar objetos, em vez de deixá-la na superclasse.

A superclasse define apenas que um botão será criado; a subclasse decide qual botão criar.

Com código, fica muito mais fácil entender.

protocol Button { func render() }

class Dialog {
    // Factory Method: a subclasse decide o que criar
    func createButton() -> Button { fatalError("Implementação na subclasse") }

    func render() {
        let button = createButton()
        button.render()
    }
}

class IOSDialog: Dialog {
    override func createButton() -> Button { IOSButton() }
}

Dialog não precisa saber qual botão usa. Quando surge uma nova plataforma, basta adicionar mais uma subclasse.

O ponto central é a herança. A estrutura troca o ponto de criação por meio de subclasses.


Qual é a diferença do Abstract Factory?

Abstract Factory é um padrão que cria objetos relacionados como um único conjunto.

Ele não cuida de apenas um botão, mas de objetos que precisam andar juntos, como botões, caixas de seleção e barras de rolagem.

protocol GUIFactory {
    func createButton() -> Button
    func createCheckbox() -> Checkbox
}

class IOSFactory: GUIFactory {
    func createButton() -> Button { IOSButton() }
    func createCheckbox() -> Checkbox { IOSCheckbox() }
}

class MacFactory: GUIFactory {
    func createButton() -> Button { MacButton() }
    func createCheckbox() -> Checkbox { MacCheckbox() }
}

O mais importante é a consistência. Com uma factory de iOS, tanto o botão quanto a caixa de seleção seguem o estilo do iOS. Assim, não há risco de misturar um botão do iOS com uma caixa de seleção do Mac.

Normalmente, o Abstract Factory recebe o objeto factory por injeção externa. Ele funciona por composição, não por herança.

Seja iOS ou Mac, basta trocar a factory para mudar o conjunto inteiro
Seja iOS ou Mac, basta trocar a factory para mudar o conjunto inteiro

Factory Method resolve «o que criar» com herança,

enquanto Abstract Factory resolve «qual conjunto criar» com composição.


Comparação das diferenças em um só olhar

Como explicar só com palavras pode confundir, organizei tudo em uma tabela.

Categoria Factory Method Abstract Factory
Objetivo Delegar a criação de um objeto Criar uma família de objetos relacionados
Base Herança (subclassificação) Composição (configuração)
O que cria Um tipo de produto Vários produtos (família)
Como estender Adicionar uma nova subclasse Adicionar uma nova factory
Exemplo comum createButton() GUIFactory completo

O interessante é que, muitas vezes, o interior do Abstract Factory é preenchido por Factory Methods. Em vez de competirem, os dois são padrões de escopos diferentes.


Quando usar e quando evitar

Os critérios práticos são mais simples do que parecem.

  • Se só existe um tipo de objeto para criar, Factory Method é suficiente. Criar também uma interface de factory seria excesso de engenharia.
  • Se dois ou mais objetos precisam se mover juntos, considere Abstract Factory.
  • Se a família de produtos não deve crescer, muitas vezes uma simples condição é melhor.
Situação Decisão
Apenas um produto será criado Factory Method
Os produtos funcionam como um conjunto Abstract Factory
A família de produtos cresce com frequência Abstract Factory
Apenas 2 ou 3 ramificações Ramificação simples, sem padrão

Padrões são ferramentas, não objetivos. Adicionar abstrações antecipadamente a um código que não vai crescer só dificulta a leitura.

Padrões são apenas ferramentas; não há problema em usá-los quando forem necessários
Padrões são apenas ferramentas; não há problema em usá-los quando forem necessários

Na entrevista, podem perguntar assim

P. Explique a diferença entre Factory Method e Abstract Factory. R. Factory Method é um padrão baseado em herança que delega às subclasses a criação de um objeto. Abstract Factory é baseado em composição e cria de forma consistente uma família de objetos relacionados. A diferença principal é criar um objeto ou um conjunto.

P. Factory Method é usado dentro do Abstract Factory? R. Sim, com frequência. Cada método de criação do Abstract Factory costuma ser implementado internamente no formato de um Factory Method. Eles não são conceitos opostos, mas padrões com escopos diferentes.

Agora, basta olhar os nomes dos dois padrões e pensar «um objeto ou um conjunto?» para entender a ideia. Revise este artigo uma vez antes da entrevista e você estará mais preparado.