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:
publicznyabstrakcyjnyklasaInformacja zwrotna{
prywatny Strunowy imię i nazwisko recenzenta;
prywatny Strunowy recenzjaWiadomość;
prywatnyint recenzjaOceny;
publicznyInformacja zwrotna(Nazwa recenzenta ciągu, Wiadomość recenzji ciągu, int recenzjaOceny){
Ten.reviewerName = recenzentNazwa;
Ten.reviewMessage = reviewMessage;
Ten.reviewRatings = reviewRatings;
}
publiczny Strunowy pobierz imię recenzenta(){
powrót imię i nazwisko recenzenta;
}
publicznypróżniaustaw imię i nazwisko recenzenta(Nazwa recenzenta ciągu znaków){
Ten.reviewerName = recenzentNazwa;
}
publiczny Strunowy pobierz wiadomość recenzji(){
powrót recenzjaWiadomość;
}
publicznypróżniaustawWiadomość recenzji(Przegląd ciąguWiadomość){
Ten.reviewMessage = reviewMessage;
}
publicznyintpobierzOceny recenzji(){
powrót recenzjaOceny;
}
publicznypróżniaustaw RecenzjeOceny(int recenzjaOceny){
Ten.reviewRatings = reviewRatings;
}
}
Każda opinia będzie miała trzy obowiązkowe właściwości, imię i 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
publicznyklasaInformacje zwrotne e-mailemrozciąga sięInformacja zwrotna{
prywatny Strunowy recenzentE-mail;
publiczna informacja zwrotna e-mail (Strunowy imię i nazwisko recenzenta, Strunowy recenzjaWiadomość, int recenzjaOceny, Strunowy e-mail recenzenta) {
Super(reviewerNazwa, reviewMessage, reviewOceny);
Ten.reviewerEmail = recenzentE-mail;
}
publiczny Strunowy pobierz e-mail recenzenta(){
powrót recenzentE-mail;
}
publicznypróżniaustaw adres e-mail recenzenta(E-mail recenzenta ciągu znaków){
Ten.reviewerEmail = recenzentE-mail;
}
}
Klasa opinii pocztowej
publicznyklasaMailInformacje zwrotnerozciąga sięInformacja zwrotna{
prywatny Strunowy adres zwrotny;
publiczna informacja zwrotna (Strunowy imię i nazwisko recenzenta, Strunowy recenzjaWiadomość, int recenzjaOceny, Strunowy adres zwrotny) {
Super(reviewerNazwa, reviewMessage, reviewOceny);
Ten.adrespowrotu = adrespowrotu;
}publiczny Strunowy pobierz adres zwrotny(){
powrót adres zwrotny;
}
publicznypróżniaustaw adres zwrotny(String Adres zwrotny){
Ten.adrespowrotu = adrespowrotu;
}
}
Klasa informacji zwrotnych w mediach społecznościowych
publicznyklasaInformacje zwrotne z mediów społecznościowychrozciąga sięInformacja zwrotna{
prywatny Strunowy recenzentUchwyt;
publiczne informacje zwrotne z mediów społecznościowych (Strunowy imię i nazwisko recenzenta, Strunowy recenzjaWiadomość, int recenzjaOceny, Strunowy uchwyt recenzenta) {
Super(reviewerNazwa, reviewMessage, reviewOceny);
Ten.reviewerHandle = recenzentHandle;
}
publiczny Strunowy getReviewerHandle(){
powrót recenzentUchwyt;
}
publicznypróżniazestawReviewerHandle(Uchwyt recenzenta ciągu){
Ten.reviewerHandle = recenzentHandle;
}
}
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.
publicznyklasaFeedbackReportFactory{
publiczny Informacja zwrotna wyślij opinię(Typ sprzężenia zwrotnego ciągu){
Informacje zwrotne = zero;
Jeśli(feedbackType.equals("e-mail")) {
informacja zwrotna = nowy EmailFeedback();
}w przeciwnym razieJeśli (feedbackType.equals("Poczta")) {
informacja zwrotna = nowy MailFeedback();
}w przeciwnym razieJeśli (feedbackType.equals("społeczny")) {
informacja zwrotna = nowy Informacje zwrotne o mediach społecznościowych();
}
powrót informacja zwrotna;
}
}
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. Stosując metodę fabryczną, zreformowany FeedbackReportFactoryklasa Javy będzie teraz zawierał następujący kod:
publicznyabstrakcyjnyklasaFeedbackReportFactory{
publicznyabstrakcyjnypróżniaZgłoś opinię(Informacje zwrotne);
}
Strukturę fabrycznego wzorca projektowego można zdefiniować za pomocą następującego diagramu klas:
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, które są unikalne 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
publicznyklasaWyślij e-mailem raport zwrotnyrozciąga sięFeedbackReportFactory{
E-mail Informacje zwrotne;
@Nadpisanie
publicznypróżniaZgłoś opinię(Informacje zwrotne){
Ten.feedback = (EmailFeedback) informacja zwrotna;
System.na zewnątrz.println("\nZgłośDlaInformacja zwrotnaPrzezE-mail" +
"\nNazwisko recenzenta: " +Ten.feedback.getReviewerName() +
"\nOpinia: " + Ten.feedback.getReviewMessage() +
"\nOceny: " + Ten.feedback.getReviewRatings() +
"\nAdres e-mail: " + Ten.feedback.getReviewerEmail());
}
}
Fabryka opinii pocztowych
publicznyklasaRaport zwrotny pocztyrozciąga sięFeedbackReportFactory{
Informacje zwrotne dotyczące poczty;
@Nadpisanie
publicznypróżniaZgłoś opinię(Informacje zwrotne){
Ten.feedback = (MailFeedback) informacja zwrotna;
System.na zewnątrz.println("\nZgłośDlaInformacja zwrotnaPrzezPoczta" +
"\nNazwisko recenzenta: " +Ten.feedback.getReviewerName() +
"\nOpinia: " + Ten.feedback.getReviewMessage() +
"\nOceny: " + Ten.feedback.getReviewRatings() +
"\nAdres pocztowy: " + Ten.feedback.getReturnAddress());
}
}
Fabryka opinii w mediach społecznościowych
publicznyklasaRaport opinii o mediach społecznościowychrozciąga sięFeedbackReportFactory{
Informacje zwrotne dotyczące mediów społecznościowych;
@Nadpisanie
publicznypróżniaZgłoś opinię(Informacje zwrotne){
Ten.feedback = (SocialMediaFeedback) informacja zwrotna;
System.na zewnątrz.println("\nZgłośDlaInformacja zwrotnaPrzezSpołecznyGłoska bezdźwięczna" +
"\nNazwisko recenzenta: " + Ten.feedback.getReviewerName() +
"\nOpinia: " + Ten.feedback.getReviewMessage() +
"\nOceny: " + Ten.feedback.getReviewRatings() +
"\nUchwyt do mediów społecznościowych recenzenta: " + Ten.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ą JUnitlub możesz utworzyć klasę sterownika:
publicznyklasaGłówny{
publicznystatycznypróżniagłówny(String[] argumenty){
Informacje zwrotne = nowy Informacja zwrotna e-mailem ("Nacięcie", "Świetny produkt!", 5, "[email protected]");
Informacje zwrotne2 = nowy MailFeedback("Jan", „Produkt jest dobry, ale nie jest to coś, co kupowałbym regularnie”, 4, "pierwsza ulica");
Informacje zwrotne3 = nowy Informacje zwrotne z mediów społecznościowych („Jane”, "To nie dla mnie", 2, "@janey");
Fabryka FeedbackReportFactory = nowy EmailFeedbackReport();
FeedbackReportFabryka fabryczna2 = nowy MailFeedbackReport();
FeedbackReportFabryka fabryczna3 = nowy SocialMediaFeedbackReport();
fabryka.makeFeedbackReport(informacja zwrotna);
fabryka2.makeFeedbackReport(informacja zwrotna2);
fabryka3.makeFeedbackReport(informacja zwrotna3);
}
Powyższa klasa Main używa odpowiednich fabryk do utworzenia trzech raportów, generując następujące dane wyjściowe w konsoli:
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.
Używając fabrycznego wzorca projektowego, wykorzystujesz dwie ważne zasady projektowania: otwarte-zamknięte i odwrócenie sterowania (IoC).