Wzorce projektowe - okładka

Wzorce projektowe – czym są i dlaczego warto je znać?

Opublikowano Kategorie Czysty kodCzas czytania 7min

Tematyce wzorców projektowych poświęciłem na blogu sporo czasu. Do tej pory brakowało jednak wpisu, który skupiałby się na tym, czym są wzorce projektowe, jakie są najpopularniejsze wzorce projektowe oraz jakie korzyści wynikają z ich znajomości i stosowania.

Czym są wzorce projektowe?

Programiści w swoich codziennych zadaniach spotykają się z najróżniejszymi problemami. Rzadko kiedy problemy są na tyle unikalne, że nikt ich jeszcze nie opisał lub nie rozwiązał. Wiele z tych problemów zostało sklasyfikowanych, opisanych i rozwiązanych. Udokumentowane i opisane rozwiązania tych problemów nazwane są właśnie wzorcami projektowymi.

Jednym z lepszych źródeł dokumentacji wzorców są książki, takie jak Design Patterns — Elements of Reusable Object-Oriented Software autorstwa tzw. Bandy Czworga (Gang of Four). Samych pozycji książkowych jest oczywiście znacznie więcej. Oprócz książek, opisy wzorców można znaleźć w wielu miejscach w Internecie, także na tym blogu. Opisy niektórych wzorców, w zależności od źródła, mogą się różnić niuansami np. nazewnictwem czy szczegółami w implementacji.

Christopher Alexander o wzorcach mówi w następujący sposób:

Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice

Banda Czworga definiuje składowe wzorców projektowych następująco:

  • nazwa wzorca — powinna być krótka i łatwa do zapamiętania. Nazwa wzorca powinna jednoznacznie informować programistę, jakiego problemu dany wzorzec dotyczy;
  • problem — wzorzec powinien rozwiązywać konkretny problem. Problem może być związany np. z wykorzystaniem jakiegoś konkretnego algorytmu czy opisywać zależności między obiektami. Wzorzec może także wskazywać warunki konieczne do spełnienia, aby go zastosować;
  • rozwiązanie — opisuje elementy składowe rozwiązania, ich powiązania i odpowiedzialności. Co istotne, opis rozwiązania nie zawiera ścisłej implementacji. W zależności od języka czy specyficznego przypadku zastosowania, implementacje mogą się nieco różnić. Wzorzec stanowi jedynie stanowi abstrakcyjny opis problemu i wytycznych, w jaki sposób dany problem może zostać rozwiązany;
  • konsekwencje — wykorzystanie każdego wzorca ma określone konsekwencje, zarówno pozytywne, jak i negatywne. Przykładowo, dany wzorzec może zwiększać rozszerzalność kodu kosztem prostoty lub elastyczności. Znajomość konsekwencji stosowania danego wzorca jest równie ważna, jak znajomość samego wzorca.

Zalety wynikające z wykorzystania wzorców projektowych

Główna z zalet wynika z samej charakterystyki wzorców projektowych. Programista otrzymuje rozwiązanie na napotkany problem wraz ze znajomością konsekwencji jego zastosowania.

Drugą, równie istotną zaletą wynikającą ze stosowania wzorców projektowych jest stosowanie wspólnego języka z innymi programistami. Operując nazwami wzorców projektowych, można w znacznie prostszy i jednoznaczny sposób omawiać problemy i ich rozwiązania. Przykładowo, podczas code review znacznie prościej jest zasugerować np. wykorzystanie Fabryki czy Strategii, zamiast szczegółowo opisywać proponowane zmiany. Nawet jeśli programista nie zna tego wzorca, to znając jego nazwę, może zrobić szybki research i go poznać.

Wykorzystanie wzorców projektowych pozwala również oszczędzić czas. Korzystanie ze znanych i sprawdzonych rozwiązań oznacza potencjalnie mniej problemów podczas implementacji, ponieważ można działać według gotowych wytycznych. Korzystanie z „gotowców” oznacza też mniej czasu spędzonego na „ponownym wynajdowaniu koła”.

Wiele wzorców pomaga również pisać kod zgodny z dobrymi praktykami programistycznymi np. zasadami SOLID. Moją osobistą obserwacją jest również, że kod wykorzystujące wzorce projektowe często jest prosty w testowaniu i sprzyja pisaniu lepszych testów.

Kiedy nie korzystać ze wzorców projektowych

Można odpowiedzieć krótko — kiedy nie jest to konieczne. Stosowanie wzorca dla samego stosowania powoduje głównie niepotrzebne komplikowanie kodu. Szczególnie wśród młodszych stażem programistów, pokusa wykorzystania wzorców zawsze i wszędzie bywa duża. W stosowaniu wzorców warto zachować umiar i zdrowy rozsądek. Przypominam, że wraz z korzyściami, wykorzystanie wzorców ma również negatywne konsekwencje.

Świetnym przykładem tego, co mam na myśli przez niepotrzebne komplikowanie kodu, jest repozytorium Java Hello World Enterprise Edition. Wiem, że prosty „Hello, World!” w Javie do najkrótszych nie należy, ale przedstawiony przykład jest wybitnie przekombinowany i jest idealnym przykładem stosowania wzorców tam, gdzie nie jest to potrzebne.

Kategorie wzorców projektowych

Najczęściej spotykanym podziałem wzorców projektowych jest podział opisany przez Bandę Czworga kategoryzującym wzorce na wzorce kreacyjne (creational), strukturalne (structural) i behawioralne (behavioral). Analizując materiały na potrzeby przygotowania tego artykułu, natknąłem się również na kategorię wzorców związanych ze współbieżnością (concurrency).

Banda Czworga w swojej książce opisuje 23 wzorce projektowe. Nie oznacza to jednak, że są tylko 23 wzorce projektowe. Istnieje wiele wzorców, równie użytecznych, jak te opisane przez Bandę Czworga, a często mniej znanych. Do takich wzorców można zaliczyć np. Repozytorium, Object Pool, czy całą kategorię wzorców związanych ze współbieżnością.

Wzorce projektowe można również kategoryzować względem siebie. Niektóre wzorce będą względem siebie komplementarne, czyli będzie możliwe ich wspólne wykorzystanie. Wzorce mogą również być substytutami, tzn. dany problem można rozwiązać czasami więcej niż jednym wzorcem i należy dokonać wyboru.

Dla wzorców, których opisy znajdują się na moim blogu, dodałem linki do dedykowanych im artykułów.

Wzorce kreacyjne

Wykorzystywane są, gdy inicjalizacja obiektu jest złożona i wymaga np. obliczeń czy dodatkowych kroków. Wykorzystanie wzorców kreacyjnych pozwala zachować zasadę enkapsulacji i trzymać kod związany z inicjalizacją obiektu w jednym miejscu, w dedykowanej abstrakcji. Dedykowane komponenty kreacyjne umożliwiają rozdzielenie procesu tworzenia obiektów od innych warstw np. warstwy zawierającej logikę biznesową.

Do wzorców kreacyjnych można zaliczyć:

Wzorce strukturalne

Wzorce strukturalna koncentrują się na kompozycji obiektów, organizowaniu ich w większe struktury. Skupiają się one także na wzajemnych relacjach między obiektami.

Na kategorię wzorców strukturalnych składają się:

Wzorce behawioralne

Wzorce behawioralne opisują interakcje między obiektami. Wykorzystanie wzorców behawioralnych pozwala m.in. zredukować wykorzystanie dziedziczenia w kodzie i pozwalają zmniejszyć coupling między obiektami.

Kategoria wzorców behawioralnych obejmuje:

Podsumowanie

Wiedząc już, czym są wzorce projektowe i dlaczego warto je znać i z nich korzystać, kolejnym krokiem powinno być poznanie w szczegółach pierwszego wzorca projektowego. W moim przypadku jako pierwszy wzorzec do nauki wybrałem Fabryki, ale nie potrafię jednoznacznie stwierdzić, czy jest to dobry wybór, czy nie. Tak naprawdę wybór pierwszego wzorca nie ma większego znaczenia, bo prędzej czy później przyda Ci się każdy z nich. Wybór masz naprawdę spory i poznanie wszystkich z pewnością zajmie Ci sporo czasu. Zachęcam też do przeczytania Design Patterns — Elements of Reusable Object-Oriented Software, mimo że jej przepracowanie wymaga sporo samozaparcia.

Źródła i materiały dodatkowe

Dominik Szczepaniak

Zawodowo Senior Software Engineer w CKSource. Prywatnie bloger, fan włoskiej kuchni, miłośnik jazdy na rowerze i treningu siłowego.

Inne wpisy, które mogą Cię zainteresować

Zapisz się na mailing i odbierz e-booka

Zapisując się na mój mailing, otrzymasz darmowy egzemplarz e-booka 106 Pytań Rekrutacyjnych Junior JavaScript Developer! Będziesz też otrzymywać wartościowe treści i powiadomienia o nowych wpisach na skrzynkę e-mail.

Subscribe
Powiadom o
guest

0 komentarzy
Inline Feedbacks
View all comments