O método de fábrica é um padrão de design criativo, ou seja, relacionado à criação de objeto. No padrão de fábrica, criamos o objeto sem expor a lógica de criação ao cliente e o cliente usa a mesma interface comum para criar um novo tipo de objeto.
A ideia é usar uma função-membro estática (método de fábrica estático) que cria & retorna instâncias, ocultando os detalhes dos módulos de classe do usuário.
Um padrão de fábrica é um dos princípios básicos de design para criar um objeto, permitindo que os clientes criem objetos de uma biblioteca (explicada abaixo) de forma que não tenha um acoplamento forte com a hierarquia de classes da biblioteca.
O que queremos dizer quando falamos sobre biblioteca e clientes?
Uma biblioteca é algo fornecido por terceiros que expõe algumas APIs públicas e os clientes fazem chamadas a essas APIs públicas para concluir sua tarefa. Um exemplo muito simples podem ser diferentes tipos de visualizações fornecidas pelo sistema operacional Android.
Por que o padrão de fábrica?
Vamos entender isso com um exemplo:
Saída:
I am two wheeler
Quais são os problemas com o design acima?
Como você deve ter observado no exemplo acima, o cliente cria objetos de TwoWheeler ou FourWheeler com base em alguma entrada durante a construção de seu objeto.
Digamos, a biblioteca apresenta uma nova classe ThreeWheeler para incorporar veículos de três rodas também. O que aconteceria? O cliente acabará encadeando um novo else se estiver na escada condicional para criar objetos de ThreeWheeler. O que, por sua vez, precisará do Cliente ser recompilado. Portanto, cada vez que uma nova alteração é feita no lado da biblioteca, o Cliente precisa fazer algumas alterações correspondentes em seu final e recompilar o código. Soa mal? Esta é uma prática muito ruim de design.
Como evitar o problema?
A resposta é: crie um método estático (ou de fábrica). Vamos ver o código abaixo.
Resultado:
I am three wheeler
No exemplo acima, nós desacoplamos totalmente a seleção do tipo para criação de objeto do Cliente. A biblioteca agora é responsável por decidir qual tipo de objeto criar com base em uma entrada. O cliente só precisa fazer uma chamada para o método Create de fábrica da biblioteca e passar o tipo que deseja, sem se preocupar com a implementação real da criação de objetos.
Obrigado a Rumplestiltskin por fornecer a explicação acima.
Outros exemplos de Método de Fábrica:
- Digamos, em um sistema de ‘Desenho’, dependendo da entrada do usuário, imagens diferentes como quadrado, retângulo, círculo podem ser desenhadas. Aqui, podemos usar o método de fábrica para criar instâncias, dependendo da entrada do usuário. Para adicionar um novo tipo de forma, não há necessidade de alterar o código do cliente.
- Outro exemplo: No site de viagens, podemos reservar passagens de trem, ônibus e passagens aéreas. Neste caso, o usuário pode fornecer seu tipo de viagem como ‘ônibus’, ‘trem’ ou ‘vôo’.
Aqui temos uma classe abstrata ‘AnyTravel’ com uma função de membro estático ‘GetObject’ que, dependendo do tipo de viagem do usuário, criar & objeto de retorno de ‘BusTravel’ ou ‘TrainTravel’. ‘BusTravel’ ou ‘TrainTravel’ têm funções comuns, como nome do passageiro, origem, parâmetros de destino.
Graças a Abhijit Saha fornecendo os primeiros 2 exemplos.