poniedziałek, 24 lutego 2014

Ach te wzorce...

kolejny rok czas zacząć...

Zima już nas zostawiła, wszelkie śniegi, które na chwilę do nas zawitały również już się potopiły tak więc najwyższa pora rozruszać stawy i sprawdzić czy palce potrafią jeszcze pisać w takt pojawiających się w głowie słów. A że powrót do formy po tak długiej przerwie do przyjemnych nie należy, a im dużej się go odwleka, tym jest trudniejszy, to aby sobie to wszystko uprzyjemnić i ułatwić postanowiłem zacząć nowy rok od nowej serii wpisów. Tym razem pod młotek idzie temat długo przeze mnie pomijany - Wzorce Projektowe.

Na wstępie jednak zaznaczę, że w przeciwieństwie do serii o tym jak pisać obiektowo oraz o SOLID (tutaj pragnę nadmienić, że ostatnie dwa wpisy pojawią się w niedługim czasie) będzie to dość luźna seria i choć plany na kilka najbliższych wpisów już mam, to jestem otwarty na propozycje i jeżeli w zakamarkach Waszych głów czai się wzorzec, który nie daje Wam spokoju, to piszcie w komentarzach, a ja postaram się co nieco rozjaśnić (o ile oczywiście będę w stanie :).
A jeżeli brakuje Wam pomysłów to zawsze możecie ponownie sięgnąć po klasykę i zastanowić się czy nie ma tam niczego, co wymagałoby wyjaśnienia :)

Chcąc nie chcąc, na wstępie, czyli dzisiaj, musi być trochę, tak przez wszystkich kochanej, suchej teorii, czyli słów kilka o tym, czym wzorzec jest, po co i dlaczego je stosować, co daje ich znajomość oraz jak je dzielimy.

a czymże jest ten wzorzec?

Abyśmy w ogóle mogli mówić o wzorcu ważne jest, aby wiedzieć czym on jest:
Wzorzec - wzór doskonałości, model, forma, schemat postępowania, wzór do naśladowania, kanon.

Czyli wzorzec jest pewnym szablonem, który można zastosować w określonej sytuacji.

Warto jeszcze zaznaczyć, że w programowaniu wzorce się opisuje, a nie wymyśla, tak więc, nie może być nazwane wzorcem projektowym rozwiązanie, które jeszcze nigdy nie było wykorzystane do poradzenia sobie z konkretnym problemem.
Najpierw jest coś co nam nie daje spokoju, następnie rozwiązanie, a po pewnym czasie, gdy zauważamy, że pewne kroki za każdym razem powtarzamy i robimy to już prawie, że automatycznie, możemy pokusić się o nazwanie i opisanie takiego szablonu.

Podstawowymi elementami wzorca projektowego są:
  • Nazwa - jakby na to nie patrzeć istotnym jest, abyśmy byli w stanie jednoznacznie określić o czym chcemy mówić.
  • Problem - dobrze wiedzieć jakie problemy dany wzorzec pomaga rozwiązać.
  • Rozwiązanie - czyli co i jak trzeba zrobić, aby zastosowane rozwiązanie można było nazwać "wykorzystaniem wzorca X".
  • Konsekwencje - wady i zalety stosowania wzorca.

po co mi to?

Czasami zderzałem się z opinią opornych, którzy twierdzili, że nie ma żadnych istotnych powodów za tym, aby znać te wszystkie (lub przynajmniej jakąś ich część) wzorców. Po co? Przecież to są po prostu dobre rozwiązania pewnych problemów, a gdy dobry programista dobierze się do kodu, to przecież jego rozwiązanie będzie zapewne dobre - wręcz niejednokrotnie wykorzysta wzorzec nieświadomie.

Oczywiście prawdą jest to nieświadome wykorzystywanie wzorców (pewnie sami niejednokrotnie się z tym zetknęliście), mimo wszystko warto jednak się z nimi (wzorcami) zapoznać (i nie mam tu na myśli wykucia wszystkich na pamięć) z jednego podstawowego powodu - wzrasta nasze tempo pracy. Zajmujemy się rozwiązywaniem tych nietrywialnych problemów zamiast wynajdywać koło na nowo.
Im więcej wiemy, im większą pulę gotowych rozwiązań mamy w rękawie, tym szybciej przechodzimy do tych rzeczy, które są największą zagwozdką i prawdziwym wyzwaniem.
Po drugie, nie tracimy tyle czasu na wymianę informacji (a przecież wszyscy wiemy, jak bardzo programiści nie lubią odrywać się od kodu :), ponieważ zamiast opisywać problem i jego rozwiązanie możemy rzucić nazwą wykorzystanego wzorce (lub kilku) i nasz rozmówca jest w stanie pojąć resztę bez dalszego zgłębiania tematu.

ponad podziałami

Wzorce projektowe można podzielić na trzy rodziny:
  • Kreacyjne - to wszystki te, które pomagają nam w zarządzaniu tworzeniem, inicjalizacją oraz konfiguracją obiektów.
  • Strukturalne - wzorce wykorzystywane do tworzenia struktur powiązanych ze sobą obiektów.
  • Behawioralne - te, które mają na celu pomoc nam przy problemach dotyczących zachowania i odpowiedzialności obiektów.

*) W miarę publikowania kolejnych wpisów będę aktualizował powyższą listę o linki do artykułów na temat konkretnych wzorców.

im więcej, tym niekoniecznie lepiej

Już na wstępie, zanim na dobre zabiorę się za pisanie artykułów chciałbym przestrzec wszystkich tych, którzy dopiero rozpoczynają swoją przygodę ze wzorcami - nie popadajcie w przesadę! Jakość kodu wcale nie jest wprost proporcjonalna do ilości wykorzystanych wzorców!

Z doświadczenia wiem, że zaznajomienie się z jakimś wzorcem przez programistę często kończy się tym, że po pewnym czasie (zazwyczaj dość krótkim) jesteśmy w stanie, czytając jego kod powiedzieć ze stu procentową pewnością o co powiększył w ostatnim czasie swoją wiedzę. Pamiętajcie, że nie ma uniwesalnego rozwiązania na całe zło tego świata, a jeżeli nagle jakiś wzorzec wydaje się Wam idealny do poradzenia sobie z połową problemów, które macie z kodem, to najlepiej zrobicie jak dacie sobie na wstrzymanie i po pierwsze jeszcze raz przeczytacie do czego powinien on być stosowany, a po drugie - poznacie wzorce podobne, które mogą w danej sytuacji lepiej się nadawać.

Drugim problemem jest wspomniana przeze mnie wcześniej przesada. Jest to istny koszmar, gdy traficie do kodu, po którym widać, że ktoś w danym momencie swojego życia zaznajamiał się właśnie z książką napisaną przez Bandę Czworga. Wzorce to nie są puzzle, z których składacie aplikację, a jeżeli fragment Waszego softu zaczyna tak właśnie wyglądać to wiedzcie, że coś się dzieje, i najprawdopodbniej nie jest to nic dobrego.

i na koniec

Obiecuję, że następnym razem już nie będzie tyle teorii i tekstu i zajmiemy się tym, co programiści lubią najbardziej - przykładami i kodem :)