Wprowadzenie
W inżynierii oprogramowania wzorzec projektowy opisuje ustalone rozwiązanie najczęściej napotykanych problemów w oprogramowaniu projekt. Przedstawia najlepsze praktyki wypracowane przez długi czas metodą prób i błędów przez doświadczonych programistów.
Wzorce projektowe zyskały popularność po opublikowaniu w 1994 roku przez Erich Gamma książki Wzorce projektowe: elementy oprogramowania obiektowego wielokrotnego użytku. , John Vlissides, Ralph Johnson i Richard Helm (znani również jako Gang of Four lub GoF).
W tym artykule zbadamy kreacyjne wzorce projektowe i ich typy. Przyjrzymy się także niektórym przykłady kodu i omówić sytuacje, w których te wzorce pasują do naszego projektu.
Kreacyjne wzorce projektowe
Kreacyjne wzorce projektowe dotyczą sposobu, w jaki tworzone są obiekty . Zmniejszają złożoność i niestabilność, tworząc obiekty w kontrolowany sposób.
Nowy operator jest często uważany za szkodliwy, ponieważ rozprasza obiekty po całej aplikacji. Z biegiem czasu zmiana implementacji może być trudna, ponieważ klasy stają się ściśle powiązane.
Kreacyjne wzorce projektowe rozwiązują ten problem, całkowicie oddzielając klienta od rzeczywistego procesu inicjalizacji.
W tym artykule , omówimy cztery typy wzorca projektowania kreacji:
- Singleton – zapewnia, że w całej aplikacji istnieje co najwyżej jedno wystąpienie obiektu.
- Metoda fabryczna – tworzy obiekty o kilka powiązanych klas bez określania dokładnego obiektu, który ma zostać utworzony
- Abstract Factory – tworzy rodziny powiązanych obiektów zależnych
- Builder – konstruuje złożone obiekty stosując podejście krok po kroku
Omówmy teraz szczegółowo każdy z tych wzorców.
Pojedynczy wzorzec projektowy
Pojedynczy wzorzec projektowy ma na celu zachowanie sprawdzenie inicjalizacji obiektów określonej klasy poprzez zapewnienie, że tylko jedna instancja obiektu istnieje w całej wirtualnej maszynie Javy.
Klasa Singleton zapewnia także jeden unikalny globalny punkt dostępu do obiektu, tak że każde kolejne wywołanie punktu dostępu zwraca tylko ten konkretny obiekt.
3.1. Przykład wzorca singletonowego
Chociaż wzorzec Singleton został wprowadzony przez GoF, wiadomo, że oryginalna implementacja jest problematyczna w scenariuszach wielowątkowych.
Więc tutaj „ Ponownie zastosujemy bardziej optymalne podejście, które wykorzystuje statyczną klasę wewnętrzną:
Tutaj utworzyliśmy statyczną klasę wewnętrzną, która zawiera instancję klasy Singleton. Tworzy instancję tylko wtedy, gdy ktoś wywoła metodę getInstance (), a nie gdy ładowana jest klasa zewnętrzna.
Jest to szeroko stosowane podejście dla klasy Singleton, ponieważ nie wymaga synchronizacji, jest bezpieczne dla wątków , wymusza leniwą inicjalizację i ma stosunkowo mniej schematu.
Zauważ też, że konstruktor ma modyfikator dostępu prywatnego. Jest to wymagane przy tworzeniu Singletona, ponieważ publiczny konstruktor oznaczałby, że każdy mógłby uzyskać do niego dostęp i rozpocząć tworzenie nowych instancji.
Pamiętaj, że to nie jest oryginalna implementacja GoF. Oryginalną wersję można znaleźć na tej powiązany artykuł Baeldung na temat singletonów w Javie.
3.2. Kiedy używać wzorca projektowego singleton
- W przypadku zasobów, które są drogie w tworzeniu (np. obiekty połączeń)
- Dobrą praktyką jest utrzymywanie wszystkich rejestratorów jako pojedynczych, co zwiększa wydajność.
- Klasy, które zapewniają dostęp do ustawień konfiguracyjnych aplikacji.
- Klasy, które zawierają zasoby, do których dostęp jest uzyskiwany w trybie współdzielonym
Wzorzec projektowy metody fabrycznej
Wzorzec projektowy fabryki lub wzorzec projektowy metody fabrycznej jest jednym z najczęściej używane wzorce projektowe w Javie.
Według GoF, ten wzorzec „definiuje interfejs do tworzenia obiektu, ale niech podklasy decydują, którą klasę instanować tiate. Metoda Factory pozwala klasie odroczyć instancję do podklas ”.
Ten wzorzec deleguje odpowiedzialność za inicjowanie klasy od klienta do określonej klasy fabrycznej poprzez utworzenie typu konstruktora wirtualnego.
Aby to osiągnąć, opieramy się na fabryce, która dostarcza nam obiekty, ukrywając rzeczywiste szczegóły realizacji. Dostęp do utworzonych obiektów uzyskuje się za pomocą wspólnego interfejsu.
4.1. Przykład wzorca projektowego metody fabrycznej
W tym przykładzie utworzymy interfejs Polygon, który zostanie zaimplementowany przez kilka klas konkretnych. Do pobrania obiektów z tej rodziny zostanie użyta Fabryka PolygonFactory :
Utwórzmy najpierw interfejs Polygon:
Następnie stworzymy kilka implementacji, takich jak Square, Triangle, itp., które implementują ten interfejs i zwracają obiekt typu Polygon.
Teraz możemy utworzyć fabrykę, która przyjmuje liczbę stron jako argument i zwraca odpowiednią implementację tego interfejsu:
Zwróć uwagę, jak klient może polegać na tej fabryce, aby dać nam odpowiedni Polygon, bez konieczności bezpośredniej inicjalizacji obiektu.
4.2. Kiedy używać wzorca projektowego metody fabrycznej
- Kiedy implementacja interfejsu lub klasy abstrakcyjnej ma się często zmieniać
- Kiedy bieżąca implementacja nie może wygodnie przyjąć nowej zmiany
- Gdy proces inicjalizacji jest stosunkowo prosty, a konstruktor wymaga tylko kilku parametrów
Abstrakcyjny wzorzec projektowy fabryki
W poprzedniej sekcji widzieliśmy, jak wzorzec projektowy Factory Method może być użyty do tworzenia obiektów związanych z pojedynczą rodziną.
Z kolei wzorzec projektu abstrakcyjnej fabryki jest używany do tworzenia rodzin powiązanych lub zależnych obiektów. Czasami nazywany jest również fabryką fabryk.
Aby uzyskać szczegółowe wyjaśnienie, zapoznaj się z naszym samouczkiem dotyczącym fabryki abstrakcyjnej.
Wzorzec projektowy konstruktora
Wzorzec projektowy Builder to kolejny wzorzec kreacyjny zaprojektowany do radzenia sobie z konstrukcją stosunkowo złożonych obiektów.
Gdy złożoność tworzenia obiektu wzrasta, wzorzec Builder może oddzielić proces tworzenia instancji za pomocą innego obiekt (budowniczy) do skonstruowania obiektu.
Ten konstruktor może następnie zostać użyty do stworzenia wielu innych podobnych reprezentacji przy użyciu prostego podejścia krok po kroku.
6.1. Wzorzec konstruktora Przykład
Oryginalny wzorzec projektowy Builder wprowadzony przez GoF koncentruje się na abstrakcji i jest bardzo dobry w przypadku złożonych obiektów, jednak projekt jest nieco skomplikowany.
Joshua Bloch, w swojej książce Effective Java, przedstawił ulepszoną wersję wzorca budującego, który jest czysty, bardzo czytelny (ponieważ wykorzystuje płynny projekt) i łatwy w obsłudze z punktu widzenia klienta. W tym przykładzie omówimy tę wersję.
Ten przykład ma tylko jedną klasę, BankAccount, która zawiera konstruktora jako statyczną klasę wewnętrzną:
Zauważ, że wszystkie modyfikatory dostępu do pól są deklarowane jako prywatne, ponieważ nie chcemy, aby zewnętrzne obiekty miały do nich bezpośredni dostęp.
Konstruktor jest również prywatny, więc tylko Konstruktor przypisany do tego klasa może uzyskać do niego dostęp. Wszystkie właściwości ustawione w konstruktorze są wyodrębniane z obiektu budującego, który podajemy jako argument.
Zdefiniowaliśmy BankAccountBuilder w statycznej klasie wewnętrznej:
Zauważ, że zadeklarowaliśmy ten sam zestaw pól, który zawiera klasa zewnętrzna. Wszelkie pola obowiązkowe są wymagane jako argumenty dla konstruktora klasy wewnętrznej, podczas gdy pozostałe pola opcjonalne można określić za pomocą metod ustawiających.
Ta implementacja obsługuje również podejście do projektowania płynnego, ponieważ metody ustawiające zwracają konstruktora
Na koniec metoda build wywołuje prywatny konstruktor klasy zewnętrznej i przekazuje samą siebie jako argument. Zwrócone konto BankAccount zostanie utworzone z parametrami ustawionymi przez BankAccountBuilder.
Zobaczmy krótki przykład wzorca konstruktora w akcji:
6.2. Kiedy używać wzorca konstruktora
- Gdy proces tworzenia obiektu jest niezwykle złożony, z wieloma obowiązkowymi i opcjonalnymi parametrami
- Gdy wzrost liczby parametrów konstruktora prowadzi do dużej listy konstruktorów
- Gdy klient oczekuje różnych reprezentacji skonstruowanego obiektu
Wniosek
W tym artykule dowiedzieliśmy się o kreacyjnych wzorcach projektowych w Javie. Omówiliśmy również ich cztery różne typy, tj. Singleton, Factory Method, Abstract Factory i Builder Pattern, ich zalety, przykłady i kiedy należy używamy ich.
Jak zawsze, pełne fragmenty kodu są dostępne na GitHubie.
Zacznij od Spring 5 i Spring Boot 2, korzystając z kursu Learn Spring:
> > ZAPOZNAJ SIĘ Z KURSEM