Padrão Criacional: Método de Fábrica
Este artigo discute como classes derivadas podem usar seus construtores para criar objetos apropriados.

O que é isso?
Uma fábrica de software cria objetos, e uma fábrica que produz bens do mundo real produz bens. Por exemplo, a criação de objetos em Java geralmente acontece assim:

O problema com essa abordagem é que, de repente, o código que usa o objeto SomeClass se torna dependente da implementação concreta de SomeClass . Não há nada de errado com new para criar objetos, mas essa abordagem pode levar a um acoplamento rígido de nosso código à classe de implementação concreta. Isso viola código para uma interface e não para uma implementação.
O método de fábrica é um padrão de design de classe que fornece uma interface para criar objetos, mas permite que as subclasses decidam qual classe instanciar.
Diagrama de classe
O diagrama de classes inclui os seguintes elementos:
- produtos
- Produto Concreto
- O Criador
- Criador Concreto

Continuando com nosso exemplo de aeronave, vamos supor que estamos tentando modelar o caça F-16. O código do cliente precisa construir um objeto de motor para este avião e pilotá-lo. Uma implementação ingênua para esta classe seria algo como abaixo:

No código acima, nos comprometemos a usar uma implementação concreta da classe F16. E se a empresa apresentar versões mais recentes da aeronave e formos obrigados a representá-los em nosso programa? Isso significaria alterar o código do cliente onde criamos uma instância F16. Uma saída é encapsular a criação do objeto em outro objeto exclusivamente responsável pela criação das variantes solicitadas do F-16. Para começar, digamos que queremos representar as variantes A e B de F16; nosso código pode ficar assim:

A Simple Factory é um idioma de programação simples que não cria um objeto de fábrica. O método make pode se tornar estático para evitar a criação de um objeto desnecessário. No entanto, como os métodos estáticos não podem ser substituídos em subclasses, não poderemos usar essa fábrica simples como base para uma hierarquia de classe abstrata.
No entanto, queremos manter a criação de partes do objeto F16 dentro da mesma classe e ainda poder introduzir novas variantes F16 à medida que elas surgem. Nesse caso, poderíamos criar uma subclasse F16 e delegar a criação do objeto variante F16 correto para a subclasse que lida com essa variante. É exatamente assim que o padrão de método de fábrica funciona! O método de fábrica aqui é makeF16() que criará uma nova variante F16 quando for chamado. Prosseguindo, introduzimos duas subclasses assim

Subclassificamos e especializamos o objeto do mecanismo usando herança. Um método de fábrica pode ou não fornecer uma implementação padrão ou genérica; no entanto, ainda podemos substituí-lo em subclasses para especializar ou modificar o produto. Nosso exemplo tem dois modelos variantes, cada um com um motor diferente, mas com o mesmo cockpit. O código do cliente agora pode usar os modelos mais recentes da seguinte forma:

Observe que o padrão de design do método de fábrica retorna um tipo abstrato, uma interface Java ou uma classe abstrata Java. A superclasse, no nosso caso F16, não sabe que tipo específico de F16 foi retornado pelo método makeF16(). Em geral, um método create é abstrato ou vem com uma implementação padrão invocada pelos outros métodos da superclasse. Portanto, cabe às subclasses criar tipos específicos de objetos.
Diferenças com fábrica simples/estática
O padrão de método de fábrica é semelhante à fábrica simples ou estática, mas as diferenças incluem que fábricas simples não podem produzir produtos variados por meio de herança como um padrão de método de fábrica.
Outros exemplos
O padrão de método de fábrica é difundido em kits de ferramentas e estruturas. O padrão pode ser usado sempre que uma classe não souber antecipadamente quais objetos de subclasse ela precisaria instanciar. Isso geralmente acontece no design do framework, onde espera-se que os consumidores do framework estendam as classes abstratas fornecidas pelo framework e conectem funcionalidades ou criações de objetos.
A API Java expõe vários métodos de fábrica:
java.util.Calendar.getInstance()
java.util.ResourceBundle.getBundle()
java.text.NumberFormat.getInstance()
Ressalvas
- O padrão pode resultar em muitas subclasses com apenas pequenas diferenças entre elas.
- Se uma subclasse adicionar funcionalidade a uma superclasse, ela não poderá usar os novos métodos, a menos que reduza o objeto ao seu tipo concreto. Infelizmente, o Downcasting pode falhar em tempo de execução.