Wzorce projektowe

Jakie rozwiązania stosować dla typowych problemów?

Wzorce projektowe to znane i sprawdzone rozwiązania dla problemów powtarzajacych się podczas projektowania oprogramowania. W złożonym systemie zawsze można dopatrzeć się pewnych powielanych szablonów.

Gdy system jest oparty o obiekty relacje między nimi wpisują się w określony schemat.

Usystematyzowanie tych relacji i zachowań stanowi zbior wzorów które są na tyle uniwersalne, że mogą być z powodzeniem stosowane przez każdego architekta/dewelopera. Poniżej przedstawiam zbiór tych najpopularniejszych.

singleton (kreacyjny) - stosowany w celu ograniczenia liczby instancji do jednej globalnej. Tworzony za pomocą statycznej metody, która sprawdza czy istnieje już egzemplarz tej klasy. Jeżeli obiekt jeszcze nie istnieje - tworzy go i zwraca przez referencje. Stworzony obiekt jest przechowywany w statycznym polu klasy. Oczywiście konstruktor musi być prywatny, by zapobiec niekontrolowanemu tworzeniu kolejnych egzemplarzy obiektu. Użytkownik nie musi wiedzieć czy egzemplarz tej klasy istnieje, o to dba metoda kreacyjna. Przykład wykorzystania - dziennik zdarzeń.

fabryka abstrakcyjna (kreacyjny) - dostarcza interfejs dla różnych obiektów jednego typu, wymuszając spójność w projekcie. Umożliwia jednemu obiektowi tworzenie innych obiektów powiązanych ze sobą i jednocześnie ukrywaich implementacje przed klientem. Wykorzystywana np. jako sposób tworzenia interfejsu graficznego, gdzie okna i przyciski tworzone są przez fabryke.

obserwator (czynnościowy) - polega na powiadamianie wszystkich zainteresowanych obiektów (obserwatorów) o zmianie stanu obserwowanego obiektu. Obserwowany zawiera dane, jest ich jedynym właścicielem i on decyduje kiedy wysłać informacje do obserwatorów. Możliwe więc jest dodawanie nowych obiektów bez potrzeby zmiany obiektu od którego zależa, z relacje między nimi mogą być dynamicznie zmieniane. Przykładowo obiekt zajmujący się kopiowaniem plików (obserwowany) i obiekt wyświetlający postęp prac (obserwator).

łańcuch zobowiązań (czynnościowy) - przekazuje do następnego obiektu żądanie jego obsługi, jeżeli nie może ono zostać spełnione w danym miejscu. Odsuwa od siebie klienta i odbiorce żądania. Często implementowane w postaci listy jednokierunkowej klas dziedziczącej po abstrakcyjnej klasie obsługi. Pozwala na dużą elastyczność, bo elementy łańcucha można dynamicznie dodawać i odejmować. Często wykorzysywane do tworzenia filtrów wiadomości pocztowych albo obsługi otwierania plików.

leniwa inicjalizacja (kreacyjny) - opóźnienie tworzenia obiektu i przeprowadzenia kosztownych operacji do momentu pierwszego zapotrzebowania. Zwykle implementowany za pomocą testowania statycznej flagi (pojedynczego pola klasy lub mapy obiektów) pod kątem sprawdzenia czy dana operacja miała już miejsce. Jako api wystawiona jest metoda tworząca obiekty, a sam konstruktor jest prywatny. Wykorzystywana do oszczędzanie zasobów systemu.

fasada (strukturalny) - polega na wystawieniu uproszczonego api, które ułatwia użycie złożonego systemu. Definiuje interface wysokiego poziomu który ułatwia korzystanie z system, jest dla niego punktem wejściowym. Wykorzystanie fasady zmniejsza zależności między klientem a systemem oraz ułatwia niezależny rozwój warstw. Przykład wykorzystania: aplikacja bankowa

TAGS: wzorce, design patterns