Krótki wpis z opisem najważniejszych wzorców projektowych. Po więcej szczegółów odsyłam do innych miejsc w sieci. :) Myślę jednak, że taka minimalistyczna lista wzorców może być przydatna. Opracowałem po przeczytaniu książek Refactoring to Patterns Joshuy Kerievskiego i Effective Java Joshuy Blocha.
- Adapter
- Unifikuje interfejsy różnych klas o tym samym lub bardzo zbliżonym zakresie odpowiedzialności w celu zakrycia różnic między nimi.
- Builder
- Upraszcza budowanie drzewa obiektów-kompozytów. Budowanie kompozytów nie jest najprzyjemniejsze – najczęściej to seria tworzenia nowych obiektów i umieszczania ich w innych. Builder ukrywa budowanie kompozytu za przyjemnym interfejsem. Drugim zastosowaniem wzorca budowniczego jest budowanie niezmiennych (immutable) obiektów, eliminując niebezpieczne dla wątków settery. Typowa implementacja budowniczego to statyczna wewnętrzna klasa. Przykład: Cipher cipher = new Cipher.Builder(Engine.RIJNDAEL).key(256).block(128).mode(Mode.CBC).build();
- Chain Constructors
- Połączenie wywołań konstruktorów w łańcuch, gdy w konstruktorach powtarzają się takie same fragmenty kodu. Polega to najczęściej na stworzeniu konstruktora zbierającego, który jest wywoływany przez inne konstruktory.
- Collecting Parameter
- Wzorzec ten warto zastosować, gdy metoda zbierająca dane jest długa. Wprowadza się wtedy obiekt zbierający dane (np. StringBuilder albo kolekcję) i przekazuje się go po kolei do wielu mniejszych metod – patrz wzorzec Composed Method.
- Command
- Ukrycie logiki obsługi poleceń w obiektach poleceń. Interfejs takich obiektów jest bardzo prosty, występuje najczęściej tylko jedna metoda, typowo void execute() lub void run(). Wykorzystywane w celu eliminacji długich instrukcji warunkowych w tzw. dispatcherach. Przykładem wzorca Command jest interfejs Runnable. Idealny do implementacji operacji cofnij-ponów.
- Composed Method
- Przekształcenie dużej, niezrozumiałej metody na kilka małych, prywatnych metod o takim samym poziomie szczegółowości. Duża metoda wywołuje po kolei te mniejsze.
- Composite
- Drzewo obiektów, na którym można operować jak gdyby operowało się na pojedynczym obiekcie. Przykładem kompozytu jest struktura elementów pliku XML lub klauzula WHERE dla bazy danych zapisana w systemie obiektowym.
- Creation Method
- Zamiana konstruktorów z różnymi parametrami na statyczne metody o przyjemnych nazwach, które zwracają nowy obiekt. Daje to przy okazji możliwość zmiany implementacji w przyszłości, np. zwracanie obiektów z puli obiektów.
- Decorator
- Dodanie dodatkowej funkcjonalności do klasy bez jej modyfikacji. Klasa rozszerzana o nową funkcjonalność nie jest świadoma tego, podobnie i użytkownicy tej klasy. Wzorzec jest zgodny z zasadą jednej odpowiedzialności (single responsibility principle), zidentyfikowanej przez Boba Martina. Przykład: składanie strumieni.
- Facade
- Ukrycie brzydkiego lub nadmiernie rozbudowanego podsystemu za interfejsem uporządkowanym i/lub uproszczonym. Uwaga – często mylony z adapterem.
- Factory
- Sposób na wyeliminowanie logiki tworzenia obiektów rozrzuconej pomiędzy dwie klasy.
- Interpreter
- Zapisanie prostego języka w postaci obiektów-kompozytów. Idealny dla prostych zapytań do bazy danych, gdy nie ma z góry zdefiniowanych, stałych zapytań. Przykład: new AndSpec(new ColorSpec(Color.RED), new OrSpec(new SizeSpec(Size.BIG), new ColorSpec(Color.BLACK))).
- Null Object
- Usunięcie często powtarzającej się logiki związanej z obsługą wartości null poprzez wprowadzenie klasy, która „nic” nie robi.
- Observer
- Powiadamianie obserwatorów o zajściu zdarzenia. Ma na celu wyeliminowanie niechcianych zależności pomiędzy klasą powiadamiającą i powiadamianą.
- Singleton
- Zapewnienie istnienia tylko jednego obiektu danej klasy, gdy tworzenie wielu egzemplarzy byłoby nieefektywne czasowo i pamięciowo. Uwaga – nigdy nie optymalizuj swoich programów na początku, bo ostatecznie dostaniesz kod nie tylko nieoptymalny, ale również trudny w utrzymaniu. Zajrzyj do Effective Java, aby uzyskać więcej informacji na ten temat.
- State
- Wykorzystanie prostych obiektów stanu zamiast wyrażeń warunkowych w celu uproszczenia logiki zmian stanu oraz poprawie czytelności.
- Strategy
- Hermetyzacja pojedynczego algorytmu przetwarzania w obiekcie strategii zamiast definiowania wszystkich możliwych sposobów przetwarzania w jednym miejscu i wybieraniu odpowiedniego za pomocą długich instrukcji warunkowych. Zawsze przed zastosowaniem dziedziczenia warto pomyśleć, czy wzorzec strategii nie będzie lepszym rozwiązaniem.
- Template Method
- Umieszczenie części wspólnych kilku klas w abstrakcyjnej klasie bazowej i pozostawienie części rozłącznych w klasach ją rozszerzających. Uwaga – jednym z niebezpieczeństw tego wzorca jest problem ułomnej klasy bazowej. Zajrzyj do książki Holub on patterns lub innych publikacji Allena Holuba.


Jest dopiero jeden komentarz ↓
Krzysztof Kędziorski // lip 13, 2010 at 21:29
Jak dla mnie super wprowadzenie i co ważniejsze na prawde bez wdawania się w szczegóły tylko co do czego i po co :) pozdrawiam
Zostaw swój komentarz