Spis treści
Wstęp [nie trzeba czytać] ...................................................................................................... 2
Wstęp właściwy..................................................................................................................... 2
Wzorce konstrukcyjne ........................................................................................................... 3
Metoda Fabrykująca .......................................................................................................... 3
Fabryka abstrakcyjna ......................................................................................................... 3
Budowniczy ....................................................................................................................... 4
Prototyp ............................................................................................................................. 6
Singleton ............................................................................................................................ 7
Podsumowanie................................................................................................................... 7
Wzorce Strukturalne .............................................................................................................. 8
Adapter .............................................................................................................................. 8
Most ................................................................................................................................... 8
Kompozyt .......................................................................................................................... 9
Dekorator ......................................................................................................................... 10
Fasada .............................................................................................................................. 12
Wzorce Czynnościowe ........................................................................................................ 12
Łańcuch odpowiedzialności ............................................................................................ 12
Polecenie.......................................................................................................................... 14
Interpretator ..................................................................................................................... 14
Iterator ............................................................................................................................. 14
Mediator........................................................................................................................... 15
Obserwator....................................................................................................................... 16
Stan .................................................................................................................................. 16
Słowo końcowe.................................................................................................................... 17
Bibliografia .......................................................................................................................... 17
Wzorce Projektowania
Wstęp[nietrzebaczytać]
Przeglądając Internet w poszukiwaniu nowych wyzwań natknąłem się na hasło: Wzorce
Projektowania. Korzystając z
www.google.pl
szybko wyszukałem kilka interesujących
artykułów na ten temat ale nigdzie nie spotkałem pojedynczego źródła zawierającego
chociaŜby podstawowe informacje na temat kaŜdego – wszędzie tylko po trochu informacji. Z
tego teŜ względu postanowiłem stworzyć dokument, którego celem jest opisanie wzorców
projektowania w jednym miejscu najlepiej jak się da… Jak wyjdzie – to się okaŜe… :)
Nie będę opisywać tutaj wszystkich wzorców ale jedynie te, które wydają mi się
najpotrzebniejsze, najczęściej uŜywane i najfajniejsze :P
Wstępwłaściwy
Wzorce projektowania, jak wskazuje sama ich nazwa, są pewnymi sprawdzonymi wzorami
na rozwiązywanie typowych problemów związanych z projektowaniem większych aplikacji
[tudzieŜ gier] zorientowanych obiektowo. Wprowadzone zostały po to aby nie trzeba było
przeprowadzać [jak ktoś gdzieś juŜ zauwaŜył] „re-inŜynierii” koła ;) Dodatkową zaletą
wzorców jest fakt, Ŝe stosowanie ich zwiększa moŜliwości późniejszego rozwoju tworzonego
programu.
Wzorcekonstrukcyjne
Wzorce konstrukcyjne automatyzują tworzenie obiektów.
MetodaFabrykująca
Generalnie słuŜy temu samemu co wszystkie Wzorce Konstrukcyjne – zajmuje się
tworzeniem obiektów. Charakteryzuje się tym, Ŝe na podstawie podanych informacji
konstruuje obiekt i zwraca instancję do niego.
Przykładem uŜycia tego wzorca moŜe być wczytywanie obrazów i tworzenie
odpowiedniego obiektu w zaleŜności od typu pliku. Dzięki tej metodzie w przyszłości bardzo
łatwo będzie dodać obsługę nowych typów plików.
enum
IMG_TYPE { FE_JPG, FE_GIF };
class
Image {
/*...*/
};
class
ImageJPG :
public
Image {
/*...*/
};
class
ImageGIF :
public
Image {
/*...*/
};
class
ImageFactory
{
public
:
static
Image *getImage( std::string filename )
{
IMG_TYPE type = getFileExtension( filename );
switch
( type )
{
case
FE_JPG:
return
new ImageJPG( filename );
case
FE_GIF:
return
new ImageGIF( filename );
}
}
};
Zdefiniowanie metody
getImage()
jako statycznej mocno ułatwi uŜywanie takiej fabryki ze
względu na to Ŝe nie będzie trzeba wszędzie, gdzie chcemy skonstruować jakiś obiekt obrazka
tworzyć obiektu
ImageFactory
. Wystarczy wtedy wywołać metodę w ten sposób:
Image *img = ImageFactory::getImage(
„jakisplik.jpg”
);
Fabrykaabstrakcyjna
Wikipedia definiuje ją jako: „[....] wzorzec projektowy stosowany w inŜynierii
oprogramowania pozwalający na enkapsulację grupy metod fabrykujących dotyczących tego
samego zagadnienia […]”. Tłumacząc to z polskiego na nasz: wzorzec ten słuŜy do tworzenia
nowych obiektów w zaleŜności od wywołanej metody oraz parametrów jej przekazanych.
Metoda taka zwraca wskaźnik do nowo utworzonej instancji obiektu. Oczywiście jedna
fabryka powinna tworzyć obiekty związane tylko z jednym zagadnieniem [np. fabryka
obiektów GUI].
Niektórzy powinni teraz zapytać „No dobra, ale gdzie tu abstrakcja?!” i słusznie. Cała
zabawa polega na tym, Ŝe naleŜy zdefiniować sobie klasę abstrakcyjną która będzie klasą
podstawową dla fabryk tworzących obiekty w danych warunkach. Dla większego zrozumienia
dam tutaj mały przykład:
Chcemy mieć moŜliwość tworzenia i obsługi okienek w systemie Windows oraz
XWindow [wszelkie –ux’y ;) ] no więc tworzymy sobie fabrykę abstrakcyjną, która będzie
miała metody
tworzOkno()
oraz
tworzSuwak()
. Następnie naleŜy stworzyć klasy oparte na
naszej klasie abstrakcyjnej nazwijmy je
fabrykaWinXP
i
fabrykaXWin
. Jak łatwo się domyślić
pierwsza z nich zajmuje się tworzeniem i obsługą okien w Windows’ie a druga w środowisku
XWindow. Sposób uŜycia takich klas jest juŜ chyba jasny ;)
Teraz zobrazowanie powyŜszego przykładu w moim ojczystym języku. Dla skrócenia
wcisnąłem tu tylko metody odpowiedzialne za tworzenie okien z pominięciem tworzenia
suwaków dla kaŜdego z systemów poniewaŜ sposób jest podobny.
class
Okno {
/*...*/
};
class
OknoWinXP : public Okno {
/*...*/
};
class
OknoXWin : public Okno {
/*...*/
};
class
fabryka
// fabryka abstrakcyjna
{
public
:
Okno *tworzOkno() = 0;
};
class
fabrykaWinXP :
public
fabryka
{
public
:
Okno *tworzOkno()
{
return
new OknoWinXP();
}
};
class
fabrykaXWin :
public
fabryka
{
public
:
Okno *tworzOkno()
{
return
new OknoXWin();
}
};
Budowniczy
Ten wzorzec słuŜy głównie do tworzenia obiektów większych składających się z
mniejszych części. Podczas poszukiwań informacji na temat tego wzorca widziałem wiele
róŜnych kodów i wiele róŜnych sposobów implementacji. Problem polegał na tym, Ŝe
pomimo, Ŝe wiedziałem jak to ma wyglądać, nigdzie nie było przykładu uŜycia czegoś
takiego. W końcu gdzieś tam w otchłani Internetu znalazłem coś co pomogło mi pojąć zasadę
działania tego stwora i udało mi się napisać bardzo ogólny przykład:
class
Produkt
{
public
:
void
dodajCzesc(std::string czesc) {
/*...*/
}
};
class
Budowniczy
{
public
:
void
zbudujCzescA() = 0;
void
zbudujCzescB() = 0;
Produkt pobierzWynik() = 0;
};
// buduje obiekt z czesci
class
BudowniczyJakis :
public
Budowniczy
{
Produkt *produkt;
public
:
void
zbudujCzescA()
{
czesc.dodajCzesc(
"CzescA"
);
}
void
zbudujCzescB()
{
czesc.dodajCzesc(
"CzescB"
);
}
Produkt *pobierzWynik()
{
return
produkt;
}
};
class
Dyrektor
{
public
:
void
Konstruuj(Budowniczy *budowniczy)
{
budowniczy.zbudujCzescA();
budowniczy.zbudujCzescB();
}
};
// sposób wykorzystania
int
main()
{
Dyrektor *director =
new
Dyrektor();
Budowniczy *builder =
new
BudowniczyJakis();
Produkt *product;
director.Konstruuj(builder);
product = builder.pobierzWynik();
/* ... */
}