Co to jest fabryczny wzorzec projektowy?

Co to jest fabryczny wzorzec projektowy?

Wzorzec projektowy fabryki (lub metody fabryki) specjalizuje się w delegowaniu i hermetyzacji. Ten wzorzec pozwala nadklasie na odroczenie tworzenia instancji do podklas. Dzieje się tak, ponieważ klasa zawierająca podstawowy wzorzec metody fabrycznej jest abstrakcyjna.

Oryginalna wersja metody fabrycznej przybiera postać metody niezaimplementowanej, ponieważ nie zna produktu, który stworzy. Metoda fabryczna może wiedzieć, że tworzy jakiś produkt, ale nie zna specyficznych cech produktu, który stworzy. Ta wiedza jest dostępna tylko dla odpowiednich podklas. Dlatego odpowiedzialność za wdrożenie metody fabrycznej i utworzenie odpowiednich obiektów spoczywa wyłącznie na podklasie.

Implementacja Factory Design Pattern w Javie

W tym artykule wykorzystano przykładową aplikację do generowania raportów zwrotnych. Ta aplikacja wykorzystuje różne rodzaje informacji zwrotnych, które firma otrzymuje (w przypadku nowej przekąski) do tworzenia określonych raportów (metodą fabryczną). W związku z tym wzorzec fabryczny utworzy określoną informację zwrotną (lub raport zwrotny), wykorzystując jako podstawę następującą podstawową klasę produktu:

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;
  }
}

Każda opinia będzie miała trzy obowiązkowe właściwości, nazwisko recenzenta, treść recenzji i ocenę liczbową (od jednego do pięciu) dla nowej przekąski. Różne rodzaje informacji zwrotnych, które firma otrzyma, będą pochodzić z jednego z trzech kanałów:

Klasa opinii 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;
  }
}

Klasa opinii pocztowej

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;
     }
}

Klasa informacji zwrotnych w mediach społecznościowych

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;
     }
}

Zauważysz, że każda podklasa opinii ma unikalną właściwość. Oznacza to, że konieczne będzie utworzenie raportu dla każdego typu opinii przy użyciu co najmniej jednej właściwości unikalnej dla tego typu.

Prosta fabryka

Prosta fabryka to popularne podejście do używania wzorca projektowego fabryki. Podejście to polega na zgrupowaniu wszystkich różnych sprzężeń zwrotnych (lub produktów) w ramach metody (prostej fabryki) i wybraniu odpowiedniego sprzężenia zwrotnego na podstawie parametru.

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;
     }
}

Jednak proste podejście fabryczne nie jest fabrycznym wzorcem projektowym ani wzorcem projektowym. To raczej koncepcja projektowa.

Metoda fabryczna

Metoda fabryczna jest prawdziwą reprezentacją wzorca projektowego. Korzystając z metody fabrycznej, zreformowana klasa Java FeedbackReportFactory będzie teraz zawierać następujący kod:

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

Strukturę fabrycznego wzorca projektowego można zdefiniować za pomocą następującego diagramu klas:

Diagram klas metod fabrycznych

Z powyższego diagramu zobaczysz, że klasa abstrakcyjna (lub interfejs) będzie zawierała abstrakcyjną wersję metody fabrycznej. Tak więc konkretne klasy fabryczne, które rozszerzają klasę abstrakcyjną, zaimplementują metodę fabryczną, używając właściwości unikalnych dla produktu, który chce stworzyć. Należy również zauważyć, że każda konkretna klasa fabryki powinna tworzyć jeden lub więcej produktów.

Przykładowa aplikacja ma trzy powiązane, ale unikatowe produkty. Każdy typ opinii ma co najmniej jedną unikalną właściwość. Tak więc aplikacja będzie musiała mieć trzy konkretne fabryki, aby zbudować każdy produkt.

Fabryka opinii 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());
     }
}

Fabryka opinii pocztowych

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());
     }
}

Fabryka opinii w mediach społecznościowych

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());
           }
}

Testowanie przykładowej aplikacji

Teraz możesz użyć odpowiednich metod fabrycznych do tworzenia miniaturowych raportów na temat informacji zwrotnych otrzymanych z różnych kanałów. Możesz przetestować aplikację za pomocą JUnit lub utworzyć klasę sterownika:

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);
   }

Powyższa klasa Main używa odpowiednich fabryk do utworzenia trzech raportów, generując następujące dane wyjściowe w konsoli:

Wyjście konsoli metody fabrycznej

Zalety korzystania z fabrycznego wzorca projektowego

Wzorzec projektowania fabryki promuje elastyczność projektowania, w którym używasz interfejsów (lub klas abstrakcyjnych) do tworzenia konkretnych klas. Promuje również skalowalność poprzez polimorfizm, umożliwiając nowym klasom implementację istniejącego interfejsu w miarę rozwoju aplikacji.

Kiedy używasz fabrycznego wzorca projektowego, wykorzystujesz dwie ważne zasady projektowe: otwarte-zamknięte i odwrócenie sterowania (IoC).

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *