O que é o padrão de design de fábrica?

O que é o padrão de design de fábrica?

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:

public abstract class Feedback {

   private String reviewerName;
   private String reviewMessage;
   private int reviewRatings;

   public Feedback(String reviewerName, String reviewMessage, int reviewRatings) {
        this.reviewerName = reviewerName;
        this.reviewMessage = reviewMessage;
        this.reviewRatings = reviewRatings;
  }

  public String getReviewerName() {
      return reviewerName;
  }
  public void setReviewerName(String reviewerName) {
      this.reviewerName = reviewerName;
  }
  public String getReviewMessage() {
      return reviewMessage;
  }
  public void setReviewMessage(String reviewMessage) {
      this.reviewMessage = reviewMessage;
  }
  public int getReviewRatings() {
      return reviewRatings;
  }
  public void setReviewRatings(int reviewRatings) {
      this.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

public class EmailFeedback extends Feedback {

  private String reviewerEmail;


  public EmailFeedback(String reviewerName, String reviewMessage, int reviewRatings, String reviewerEmail) {
     super(reviewerName, reviewMessage, reviewRatings);
     this.reviewerEmail = reviewerEmail;
  }
  public String getReviewerEmail() {
     return reviewerEmail;
  }
  public void setReviewerEmail(String reviewerEmail) {
     this.reviewerEmail = reviewerEmail;
  }
}

Classe de feedback de e-mail

public class MailFeedback extends Feedback {

   private String returnAddress;

   public MailFeedback(String reviewerName, String reviewMessage, int reviewRatings, String returnAddress) {
        super(reviewerName, reviewMessage, reviewRatings);
        this.returnAddress = returnAddress;
     }

   public String getReturnAddress() {
       return returnAddress;
     }

   public void setReturnAddress(String returnAddress) {
       this.returnAddress = returnAddress;
     }
}

Aula de feedback de mídia social

public class SocialMediaFeedback extends Feedback {

   private String reviewerHandle;

   public SocialMediaFeedback(String reviewerName, String reviewMessage, int reviewRatings, String reviewerHandle) {
        super(reviewerName, reviewMessage, reviewRatings);
        this.reviewerHandle = reviewerHandle;
     }

   public String getReviewerHandle() {
       return reviewerHandle;
     }

   public void setReviewerHandle(String reviewerHandle) {
       this.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.

public class FeedbackReportFactory {

    public Feedback makeFeedback(String feedbackType) {
         Feedback feedback = null;


         if(feedbackType.equals("email")) {
               feedback = new EmailFeedback();
         }else if (feedbackType.equals("mail")) {
               feedback = new MailFeedback();
         }else if (feedbackType.equals("social")) {
               feedback = new SocialMediaFeedback();
         }
     return feedback;
     }
}

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, a classe Java FeedbackReportFactory reformada agora conterá o seguinte código:

public abstract class FeedbackReportFactory {
    public abstract void makeFeedbackReport(Feedback feedback);
}

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

Diagrama de classe de método de fábrica

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

public class EmailFeedbackReport extends FeedbackReportFactory{

    EmailFeedback feedback;

    @Override
    public void makeFeedbackReport(Feedback feedback) {

        this.feedback = (EmailFeedback) feedback;

        System.out.println("\nReport For Feedback Via Email"+
                  "\nReviewer Name: " +this.feedback.getReviewerName() +
                  "\nFeedback: " + this.feedback.getReviewMessage() +
                  "\nRatings: " + this.feedback.getReviewRatings() +
                  "\nEmal Address: " + this.feedback.getReviewerEmail());
     }
}

Fábrica de feedback de e-mail

public class MailFeedbackReport extends FeedbackReportFactory {
    MailFeedback feedback;

    @Override
    public void makeFeedbackReport(Feedback feedback) {
         this.feedback = (MailFeedback) feedback;


         System.out.println("\nReport For Feedback Via Mail"+
                     "\nReviewer Name: " +this.feedback.getReviewerName() +
                     "\nFeedback: " + this.feedback.getReviewMessage() +
                     "\nRatings: " + this.feedback.getReviewRatings() +
                     "\nMailing Address: " + this.feedback.getReturnAddress());
     }
}

Fábrica de feedback de mídia social

public class SocialMediaFeedbackReport extends FeedbackReportFactory {
    SocialMediaFeedback feedback;

    @Override
    public void makeFeedbackReport(Feedback feedback) {
        this.feedback = (SocialMediaFeedback) feedback;


        System.out.println("\nReport For Feedback Via Social Media"+
                      "\nReviewer Name: " + this.feedback.getReviewerName() +
                      "\nFeedback: " + this.feedback.getReviewMessage() +
                      "\nRatings: " + this.feedback.getReviewRatings() +
                      "\nReviewer Social Media Handle: " + this.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 pode criar uma classe de driver:

public class Main {

   public static void main(String[] args) {
       Feedback feedback = new EmailFeedback("Nick", "Great product!", 5, "nick@email.com");
       Feedback feedback2 = new MailFeedback("john", "The product is good but not something I would buy regularly", 4, "first Street");
       Feedback feedback3 = new SocialMediaFeedback("Jane", "It's not for me", 2, "@janey");

       FeedbackReportFactory factory = new EmailFeedbackReport();
       FeedbackReportFactory factory2 = new MailFeedbackReport();
       FeedbackReportFactory factory3 = new SocialMediaFeedbackReport();

       factory.makeFeedbackReport(feedback);
       factory2.makeFeedbackReport(feedback2);
       factory3.makeFeedbackReport(feedback3);
   }

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

Saída do console do método de fábrica

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 design de fábrica, você está utilizando dois importantes princípios de design: aberto-fechado e inversão de controle (IoC).

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *