Wzorce projektowe to typowe rozwiązania problemów często napotykanych podczas projektowania oprogramowania. Definiują one wspólny język, który pozwala efektywniej współdziałać zespołowo. Wzorce te można klasyfikować według różnych kryteriów, w tym poziomu skomplikowania, szczegółowości oraz skali zastosowania. Jednym z najbardziej użytecznych sposobów klasyfikacji jest podział na trzy główne kategorie: wzorce kreacyjne, strukturalne i behawioralne. Każda z tych kategorii skupia się na różnych aspektach projektowania obiektowego.
Wzorce Kreacyjne
Wzorce kreacyjne koncentrują się na procesie tworzenia obiektów, oferując mechanizmy, które zwiększają elastyczność i pozwalają na ponowne wykorzystanie istniejącego kodu. Dzięki zastosowaniu tych wzorców, kod staje się bardziej przejrzysty i łatwiejszy do modyfikacji.
Przykłady wzorców kreacyjnych:
- Metoda wytwórcza (Factory Method)
- Udostępnia interfejs do tworzenia obiektów w ramach klasy bazowej, ale pozwala podklasom zmieniać typ tworzonych obiektów.
- Przykład: Klasa PrzygotowaniePosiłków może tworzyć różne typy posiłków, jak ‘Pizza’ lub ‘Sałatka’, w zależności od wymagań klienta.
- Fabryka Abstrakcyjna (Abstract Factory)
- Pozwala tworzyć rodziny spokrewnionych ze sobą obiektów bez określania ich konkretnych klas.
- Przykład: System interfejsów użytkownika może posiadać fabryki dla różnych systemów operacyjnych, które mogą tworzyć spokrewnione elementy interfejsu: Okna i Przyciski dla systemu Windows oraz Okna i Przyciski dla systemu macOS.
- Budowniczy (Builder)
- Umożliwia tworzenie złożonych obiektów etapami, krok po kroku.
- Przykład: Proces budowy komputera, który może być skonfigurowany na etapie wyboru procesora, RAM-u, karty graficznej, itp.
- Prototyp (Prototype)
- Umożliwia kopiowanie już istniejących obiektów bez tworzenia zależności pomiędzy kodem a klasami obiektów.
- Przykład: Klonowanie obiektu Robot, który posiada identyczne cechy jak inne, istniejące już obiekty Robot.
- Singleton (Singleton)
- Zapewnia istnienie wyłącznie jednej instancji danej klasy oraz globalny punkt dostępowy do tej instancji.
- Przykład: Logger aplikacji, gdzie jedna instancja zarządza wszystkimi zapisami do plików dziennika.
Wzorce Strukturalne
Wzorce strukturalne wyjaśniają, jak komponować obiekty i klasy w większe struktury, zachowując przy tym elastyczność i efektywność struktur. Pomagają one włączać nowe funkcjonalności do aplikacji bez wpływu na istniejący kod.
Przykłady wzorców strukturalnych:
- Adapter (Adapter)
- Pozwala na współdziałanie ze sobą obiektów o niekompatybilnych interfejsach.
- Przykład: Adapter HDMI, który pozwala na podłączenie monitora do laptopa zamiast użycia VGA.
- Most (Bridge)
- Oddziela abstrakcję od implementacji, umożliwiając ich niezależne rozwijanie.
- Przykład: System płatności online może mieć różne metody płatności (karta kredytowa, PayPal) oraz różne środowiska uruchomieniowe (web, mobilne), które są rozwijane niezależnie.
- Kompozyt (Composite)
- Pozwala komponować obiekty w struktury drzewiaste, a następnie traktować te struktury jakby były osobnymi obiektami.
- Przykład: Struktura plików, gdzie zarówno foldery jak i pliki są traktowane jednolicie i mogą być iterowane podobnie.
- Dekorator (Decorator)
- Pozwala dodawać nowe obowiązki obiektom dynamicznie, przez umieszczanie ich w specjalnych obiektach opakowujących.
- Przykład: Dodawanie różnych opcji do samochodu — takich jak klimatyzacja, skórzane siedzenia — bez zmieniania podstawowej klasy Samochód.
- Fasada (Facade)
- Oferuje uproszczony interfejs do skomplikowanego systemu klas.
- Przykład: Fasada systemu rezerwacji podróży, która oferuje uproszczony interfejs do lotów, hoteli i wynajmu samochodów.
- Pyłek (Flyweight)
- Pozwala zmieścić więcej obiektów w pamięci RAM poprzez współdzielenie ich opisu stanu.
- Przykład: Rysowanie ogromnej liczby małych obiektów na ekranie gry, gdzie każdy obiekt jest pyłkiem współdzielącym ten sam stan.
- Pełnomocnik (Proxy)
- Tworzy obiekt zastępczy w miejsce innego obiektu, nadzorując dostęp do niego.
- Przykład: Serwer proxy, który służy jako pośrednik umożliwiający dostęp do zasobów internetowych.
Wzorce Behawioralne
Wzorce behawioralne koncentrują się na efektywnej komunikacji i podziale obowiązków pomiędzy obiektami. Pomagają one w zarządzaniu algorytmami, relacjami oraz odpowiedzialnością między obiektami.
Przykłady wzorców behawioralnych:
- Łańcuch Zobowiązań (Chain of Responsibility)
- Pozwala przekazywać żądania wzdłuż łańcucha obiektów obsługujących.
- Przykład: Obsługa żądań pomocy technicznej, gdzie każde żądanie jest przekazywane do kolejnej osoby w zależności od jej kompetencji.
- Polecenie (Command)
- Zamienia żądania w samodzielne obiekty umożliwiające parametryzację metod, opóźnianie lub kolejkowanie wykonania oraz cofanie operacji.
- Przykład: Operacje w edytorze tekstu, takie jak kopiowanie, wstawianie i usuwanie, każda reprezentowana jako oddzielne polecenie.
- Iterator (Iterator)
- Umożliwia sekwencyjny dostęp do elementów kolekcji bez ujawniania ich wewnętrznej struktury.
- Przykład: Iterowanie po elementach listy zakupów bez ujawniania struktury danych listy.
- Mediator (Mediator)
- Redukuje bezpośrednie zależności pomiędzy obiektami, wymuszając współpracę przez obiekt pośredniczący.
- Przykład: System komunikacji w zespole projektowym, gdzie każdy członek komunikuje się przez menedżera projektu zamiast bezpośrednio z każdym innym członkiem.
- Pamiątka (Memento)
- Pozwala zapisywać i przywracać wcześniejszy stan obiektu bez ujawniania szczegółów jego implementacji.
- Przykład: System gier, który pozwala na zapisanie i przywrócenie stanu gry, umożliwiając graczowi powrót do poprzedniej rozgrywki.
- Obserwator (Observer)
- Pozwala definiować mechanizm subskrypcji, by powiadamiać wiele obiektów o zdarzeniach dziejących się w obserwowanym obiekcie.
- Przykład: Aplikacja pogodowa, która powiadamia subskrybentów o zmianach prognozy pogody.
- Stan (State)
- Umożliwia obiektowi zmianę swojego zachowania wraz ze zmianą jego stanu wewnętrznego.
- Przykład: Automat do sprzedaży napojów, który zachowuje się inaczej w stanie "przyjmowania monety", inaczej w stanie "wydawania napoju".
- Strategia (Strategy)
- Pozwala zdefiniować rodzinę algorytmów, umieścić je w osobnych klasach i uczynić obiekty tych klas wymienialnymi.
- Przykład: Algorytmy sortowania, takie jak quicksort i mergesort, które mogą być zamienne w zależności od wymagań.
- Metoda szablonowa (Template Method)
- Definiuje szkielet algorytmu w klasie bazowej, ale pozwala podklasom nadpisać pewne etapy algorytmu bez zmiany jego struktury.
- Przykład: Proces weryfikacji użytkownika w systemie logowania, gdzie różne metody uwierzytelniania mogą być implementowane w podklasach.
- Odwiedzający (Visitor)
- Pozwala oddzielić algorytmy od obiektów na których pracują.
- Przykład: System kontroli jakości, gdzie różne typy kontroli są przeprowadzane na różnych częściach produktu, takich jak metale, plastiki, elektroniczne komponenty.