Czym są wzorce projektowe?

Wzorzec projektowy to nazwane rozwiązanie problemu, który powtarza się w różnych projektach. To nie gotowy kod do skopiowania, tylko schemat, który dopasowujesz do konkretnej sytuacji.

Wzorce dają zespołowi wspólną nazwę dla decyzji projektowej i przenoszą doświadczenie ludzi, którzy rozwiązali ten problem wcześniej. Czytelniejszy kod to bonus, ale tylko dla czytelnika, który wzorzec zna. Kosztem jest pośredniość. Wzorzec, który nie zarabia na siebie, utrudnia zrozumienie systemu.

Kategorie wzorców

Wzorce grupuje się według tego, co zmieniają: tworzenie obiektów, ich składanie albo współpracę.

Wzorce kreacyjne

Dotyczą sposobu tworzenia obiektów.

  • Singleton: pilnuje, żeby klasa miała jedną instancję, i daje do niej globalny dostęp
  • Factory: tworzy obiekty bez wskazywania konkretnych klas
  • Abstract Factory: daje interfejs do tworzenia rodzin powiązanych obiektów
  • Builder: oddziela sposób budowania złożonego obiektu od jego reprezentacji
  • Prototype: tworzy nowe obiekty przez kopiowanie prototypu

Wzorce strukturalne

Dotyczą składania obiektów i relacji między nimi.

  • Adapter: zamienia interfejs klasy na taki, którego oczekuje klient
  • Decorator: dodaje obowiązki obiektowi w czasie wykonania
  • Facade: daje jeden uproszczony interfejs do całego zestawu interfejsów
  • Proxy: podstawia inny obiekt w miejsce docelowego
  • Bridge: oddziela abstrakcję od implementacji
  • Composite: składa obiekty w drzewo, żeby przedstawić hierarchię część-całość
  • Flyweight: współdzieli dane, żeby obsłużyć dużo drobnych obiektów bez marnowania pamięci

Wzorce behawioralne

Dotyczą współpracy obiektów i podziału odpowiedzialności.

  • Observer: definiuje zależność jeden do wielu, w której zmiana stanu obiektu powiadamia zależne obiekty
  • Strategy: definiuje rodzinę algorytmów, zamyka każdy w osobnej klasie i pozwala je wymieniać
  • Command: zamienia żądanie w obiekt, dzięki czemu klient może je parametryzować
  • State: pozwala obiektowi zmienić zachowanie wraz ze zmianą stanu wewnętrznego
  • Template Method: definiuje szkielet algorytmu w klasie bazowej i pozwala podklasom nadpisać kroki
  • Iterator: daje sekwencyjny dostęp do kolekcji bez ujawniania jej reprezentacji
  • Mediator: zamyka w obiekcie sposób, w jaki zestaw obiektów komunikuje się ze sobą
  • Chain of Responsibility: przekazuje żądania wzdłuż łańcucha obsługujących
  • Visitor: dodaje operacje do elementów struktury obiektu bez zmiany samych elementów

Kiedy używać wzorców

Używaj wzorca, gdy umiesz nazwać problem, który rozwiązuje, i zmianę, którą czyni tańszą. Wzorzec dodany po to, żeby kod wyglądał poważnie, to tylko dodatkowy kod do czytania.

Typowe błędy

  • Nadmiar wzorców. Nie używaj wzorca tylko dlatego, że go znasz.
  • Zły wzorzec. Niedopasowany wzorzec ukrywa prawdziwy projekt.
  • Zbyt wiele warstw. Pośredniość kosztuje, a koszty się sumują.
  • Sztywne trzymanie się schematu. Wzorzec to punkt wyjścia, nie reguła. Dopasuj go do problemu.

Nauka wzorców

Zacznij od jednego wzorca, który możesz zastosować w tym miesiącu. Czytaj przykłady w znanym Ci kodzie. Nie chodzi o kolekcjonowanie wzorców, tylko o rozpoznawanie sytuacji, w której któryś się przyda, i o zostawianie go w spokoju, gdy nie pasuje.