Leitores como você ajudam a apoiar o MUO. Quando você faz uma compra usando links em nosso site, podemos ganhar uma comissão de afiliado. Consulte Mais informação.

O padrão de projeto fábrica (ou método fábrica) é especializado em delegação e encapsulamento. Esse padrão permite que uma superclasse adie a instanciação para subclasses. Isso ocorre porque a classe que contém o padrão de método de fábrica principal é abstrata.

A versão original do método fábrica assume a forma de um método não implementado porque não conhece o produto que irá criar. O método fábrica pode saber que está criando algum produto, mas não conhece as características específicas do produto que irá criar. Este conhecimento está disponível apenas para as respectivas subclasses. Portanto, a responsabilidade de implementar o método fábrica e criar os objetos apropriados é exclusivamente de uma subclasse.

Implementando o Factory Design Pattern em Java

Este artigo utiliza um exemplo de aplicativo de geração de relatórios de feedback. Esta aplicação utiliza os diferentes tipos de feedback que uma empresa recebe (de um novo lanche) para criar relatórios específicos (utilizando o método de fábrica). Portanto, o padrão de fábrica criará um feedback específico (ou relatório de feedback), usando como base a seguinte classe primária de produto:

públicoabstratoaulaOpinião{

privado Corda revisorNome;
privado Corda revisãoMensagem;
privadoint avaliações de avaliação;

públicoOpinião(String reviewerName, String reviewMessage, int revisãoAvaliações){
esse.reviewerName = revisorName;
esse.reviewMessage = reviewMessage;
esse.reviewRatings = reviewRatings;
}

público Corda getReviewerName(){
retornar revisorNome;
}
públicovaziosetReviewerName(String revisorName){
esse.reviewerName = revisorName;
}
público Corda getReviewMessage(){
retornar revisãoMensagem;
}
públicovaziodefinirReviewMessage(String reviewMessage){
esse.reviewMessage = reviewMessage;
}
públicointgetReviewRatings(){
retornar avaliações de avaliação;
}
públicovaziosetReviewRatings(int revisãoAvaliações){
esse.reviewRatings = reviewRatings;
}
}

Cada feedback terá três propriedades obrigatórias, um nome do revisor, uma mensagem de revisão e uma classificação numérica (de um a cinco) para o novo lanche. Os diferentes tipos de feedback que a empresa receberá virão de um dos três canais:

Aula de feedback por e-mail

públicoaulaEmailFeedbackestendeOpinião{

privado Corda revisorEmail;

Public EmailFeedback(Corda revisorNome, Corda reviewMessage, int reviewRatings, Corda e-mail do revisor) {
super(reviewerName, reviewMessage, reviewRatings);
esse.reviewerEmail = revisorEmail;
}
público Corda getReviewerEmail(){
retornar revisorEmail;
}
públicovaziosetReviewerEmail(String reviewerEmail){
esse.reviewerEmail = revisorEmail;
}
}

Classe de feedback de e-mail

públicoaulaMailFeedbackestendeOpinião{

privado Corda endereço de devolução;

public MailFeedback(Corda revisorNome, Corda reviewMessage, int reviewRatings, Corda endereço de devolução) {
super(reviewerName, reviewMessage, reviewRatings);
esse.returnAddress = returnAddress;
}

público Corda getReturnAddress(){
retornar endereço de devolução;
}

públicovaziosetReturnAddress(String returnAddress){
esse.returnAddress = returnAddress;
}
}

Aula de feedback de mídia social

públicoaulaFeedback de mídia socialestendeOpinião{

privado Corda revisorHandle;

public SocialMediaFeedback(Corda revisorNome, Corda reviewMessage, int reviewRatings, Corda revisorHandle) {
super(reviewerName, reviewMessage, reviewRatings);
esse.reviewerHandle = reviewerHandle;
}

público Corda getReviewerHandle(){
retornar revisorHandle;
}

públicovaziosetReviewerHandle(String reviewerHandle){
esse.reviewerHandle = reviewerHandle;
}
}

Você notará que cada subclasse de feedback tem uma propriedade única. Isso significa que você precisará criar o relatório para cada tipo de feedback usando pelo menos uma propriedade exclusiva desse tipo.

A Fábrica Simples

Uma fábrica simples é uma abordagem popular para usar o padrão de projeto de fábrica. Essa abordagem envolve agrupar todos os diferentes feedbacks (ou produtos) em um método (a fábrica simples) e selecionar o feedback apropriado com base em um parâmetro.

públicoaulaFeedbackRelatórioFábrica{

público Opinião fazerFeedback(String feedbackType){
Feedback feedback = nulo;

se(feedbackType.igual("e-mail")) {
feedback = novo EmailFeedback();
}outrose (feedbackType.igual("correspondência")) {
feedback = novo MailFeedback();
}outrose (feedbackType.igual("social")) {
feedback = novo SocialMediaFeedback();
}
retornar opinião;
}
}

No entanto, a abordagem de fábrica simples não é o padrão de projeto de fábrica, nem é um padrão de projeto. É mais como um conceito de design.

O método de fábrica

O método de fábrica é a verdadeira representação do padrão de projeto. Usando o método de fábrica, o reformado FeedbackRelatórioFábricaclasse Java agora conterá o seguinte código:

públicoabstratoaulaFeedbackRelatórioFábrica{
públicoabstratovaziomakeFeedbackReport(Feedback);
}

Você pode definir a estrutura do padrão de design de fábrica com o seguinte diagrama de classe:

No diagrama acima, você verá que uma classe abstrata (ou interface) conterá uma versão abstrata do método de fábrica. Assim, as classes de fábrica concretas que estendem a classe abstrata implementarão o método de fábrica, usando propriedades exclusivas do produto que deseja criar. Você também deve observar que qualquer classe de fábrica concreta deve criar um ou mais produtos.

O aplicativo de amostra tem três produtos relacionados, mas exclusivos. Cada tipo de feedback tem pelo menos uma propriedade exclusiva. Assim, a aplicação precisará ter três fábricas de concreto para construir cada produto.

Fábrica de feedback por e-mail

públicoaulaE-mailFeedbackRelatórioestendeFeedbackRelatórioFábrica{

Feedback de feedback por e-mail;

@Sobrepor
públicovaziomakeFeedbackReport(Feedback){

esse.feedback = (EmailFeedback) feedback;

Sistema.fora.println("\nRelatórioParaOpiniãoAtravés daE-mail" +
"\nNome do Revisor: " +esse.feedback.getReviewerName() +
"\nFeedback: " + esse.feedback.getReviewMessage() +
"\nAvaliações: " + esse.feedback.getReviewRatings() +
"\nEndereço de e-mail: " + esse.feedback.getReviewerEmail());
}
}

Fábrica de feedback de e-mail

públicoaulaMailFeedbackReportestendeFeedbackRelatórioFábrica{
Feedback do MailFeedback;

@Sobrepor
públicovaziomakeFeedbackReport(Feedback){
esse.feedback = (MailFeedback) feedback;

Sistema.fora.println("\nRelatórioParaOpiniãoAtravés daCorrespondência" +
"\nNome do Revisor: " +esse.feedback.getReviewerName() +
"\nFeedback: " + esse.feedback.getReviewMessage() +
"\nAvaliações: " + esse.feedback.getReviewRatings() +
"\nEndereço para correspondência: " + esse.feedback.getReturnAddress());
}
}

Fábrica de feedback de mídia social

públicoaulaRelatório de feedback de mídia socialestendeFeedbackRelatórioFábrica{
Feedback de Social MediaFeedback;

@Sobrepor
públicovaziomakeFeedbackReport(Feedback){
esse.feedback = (SocialMediaFeedback) feedback;

Sistema.fora.println("\nRelatórioParaOpiniãoAtravés daSocialmeios de comunicação" +
"\nNome do Revisor: " + esse.feedback.getReviewerName() +
"\nFeedback: " + esse.feedback.getReviewMessage() +
"\nAvaliações: " + esse.feedback.getReviewRatings() +
"\nAvaliador de mídia social do revisor: " + esse.feedback.getReviewerHandle());
}
}

Testando o aplicativo de exemplo

Agora você pode usar os respectivos métodos de fábrica para fazer relatórios em miniatura sobre o feedback recebido dos diferentes canais. Você pode testar o aplicativo usando JUnit, ou você pode criar uma classe de driver:

públicoaulaPrincipal{

públicoestáticovazioprincipal(String[] argumentos){
Feedback feedback = novo EmailFeedback("Usuario", "Ótimo produto!", 5, "[email protected]");
Feedback feedback2 = novo MailFeedback("John", "O produto é bom, mas não é algo que eu compraria regularmente", 4, "primeira rua");
Feedback feedback3 = novo Feedback de mídia social("Jane", "Não é para mim", 2, "@janey");

FeedbackReportFactory fábrica = novo EmailFeedbackReport();
FeedbackReportFactory factory2 = novo MailFeedbackReport();
FeedbackReportFactory factory3 = novo SocialMediaFeedbackReport();

fábrica.makeFeedbackReport(opinião);
fábrica2.makeFeedbackReport(feedback2);
fábrica3.makeFeedbackReport(feedback3);
}

A classe Main acima usa as respectivas fábricas para criar três relatórios, produzindo a seguinte saída no console:

Vantagens de usar o padrão de design de fábrica

O padrão de design de fábrica promove flexibilidade de design, onde você usa interfaces (ou classes abstratas) para criar classes concretas. Também promove escalabilidade por meio de polimorfismo, permitindo que novas classes implementem a interface existente à medida que o aplicativo se expande.

Ao usar o padrão de projeto de fábrica, você está utilizando dois importantes princípios de projeto: aberto-fechado e inversão de controle (IoC).