Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00127 009772 11028302 na godz. na dobę w sumie
Head First Design Patterns. Edycja polska (Rusz głową!) - książka
Head First Design Patterns. Edycja polska (Rusz głową!) - książka
Autor: , , , Liczba stron: 656
Wydawca: Helion Język publikacji: polski
ISBN: 83-7361-792-2 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> techniki programowania
Porównaj ceny (książka, ebook, audiobook).

Poznaj w niekonwencjonalny sposób zasady stosowania wzorców projektowych

Otwórz swój umysł. Poznaj wszystko, co jest związane z wzorcami projektowymi, w sposób gwarantujący szybkie i skuteczne opanowanie zasad ich stosowania. Zapomnij o listingach liczących tysiące linii, długich i nużących opisach teoretycznych oraz rozbudowanych schematach zależności. Czytając książkę 'Head First Design Patterns. Edycja polska', poznasz wzorce projektowe w inny sposób. Wzorce projektowe to gotowe opisy rozwiązań najczęściej spotykanych zagadnień związanych z tworzeniem oprogramowania. Aby je prawidłowo stosować, należy poznać założenia, na podstawie których zostały stworzone, oraz nauczyć się implementować je we właściwy sposób.

Dzięki książce 'Head First Design Pattern. Edycja polska' wszystkie pojęcia związane ze wzorcami projektowymi przestaną być dla Ciebie wiedzą tajemną. Autorzy książki, wykorzystując najnowsze elementy teorii uczenia, przedstawią Ci wszystkie zagadnienia niezbędne do rozpoczęcia projektowania i tworzenia aplikacji w oparciu o wzorce projektowe. Poznasz najczęściej stosowane wzorce projektowe, metody ich implementacji i zadania, do jakich są przeznaczone. Jednak, co najważniejsze, nauczysz się stosować tę wiedzę w praktyce.

Przekonaj się, że nowoczesne metody nauczania mogą zmienić również sposób poznawania nowoczesnych technik programistycznych.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

IDZ DO IDZ DO PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ SPIS TREĎCI SPIS TREĎCI KATALOG KSI¥¯EK KATALOG KSI¥¯EK KATALOG ONLINE KATALOG ONLINE ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG TWÓJ KOSZYK TWÓJ KOSZYK DODAJ DO KOSZYKA DODAJ DO KOSZYKA CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE ZAMÓW INFORMACJE O NOWOĎCIACH O NOWOĎCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: helion@helion.pl Head First Design Patterns. Edycja polska Autorzy: Eric Freeman, Elisabeth Freeman T³umaczenie: Pawe³ Koronkiewicz (wprowadzenie, rozdz. 1–8), Grzegorz Kowalczyk (rozdz. 9–14) ISBN: 83-7361-792-2 Tytu³ orygina³u: Head First Design Patterns Format: 200×230, stron: 656 Poznaj w niekonwencjonalny sposób zasady stosowania wzorców projektowych • Dowiedz siê, czym s¹ wzorce projektowe • Poznaj typy wzorców projektowych • Zastosuj wzorce projektowe w praktyce • Naucz siê projektowaæ aplikacje w oparciu o wzorce projektowe Otwórz swój umys³. Poznaj wszystko, co jest zwi¹zane z wzorcami projektowymi, w sposób gwarantuj¹cy szybkie i skuteczne opanowanie zasad ich stosowania. Zapomnij o listingach licz¹cych tysi¹ce linii, d³ugich i nu¿¹cych opisach teoretycznych oraz rozbudowanych schematach zale¿noġci. Czytaj¹c ksi¹¿kê „Head First Design Patterns. Edycja polska”, poznasz wzorce projektowe w inny sposób. Wzorce projektowe to gotowe opisy rozwi¹zañ najczêġciej spotykanych zagadnieñ zwi¹zanych z tworzeniem oprogramowania. Aby je prawid³owo stosowaæ, nale¿y poznaæ za³o¿enia, na podstawie których zosta³y stworzone, oraz nauczyæ siê implementowaæ je we w³aġciwy sposób. Dziêki ksi¹¿ce „Head First Design Pattern. Edycja polska” wszystkie pojêcia zwi¹zane ze wzorcami projektowymi przestan¹ byæ dla Ciebie wiedz¹ tajemn¹. Autorzy ksi¹¿ki, wykorzystuj¹c najnowsze elementy teorii uczenia, przedstawi¹ Ci wszystkie zagadnienia niezbêdne do rozpoczêcia projektowania i tworzenia aplikacji w oparciu o wzorce projektowe. Poznasz najczêġciej stosowane wzorce projektowe, metody ich implementacji i zadania, do jakich s¹ przeznaczone. Jednak, co najwa¿niejsze, nauczysz siê stosowaæ tê wiedzê w praktyce. • Cele stosowania wzorców projektowych • Za³o¿enia, na których opieraj¹ siê wzorce projektowe • Najwa¿niejsze i najczêġciej wykorzystywane wzorce projektowe • Przechowywanie i prezentacja danych • Mechanizm RMI • Wzorzec MVC • Implementacja wzorców projektowych w aplikacjach Przekonaj siê, ¿e nowoczesne metody nauczania mog¹ zmieniæ równie¿ sposób poznawania nowoczesnych technik programistycznych. Spis treści (skrócony) Wprowadzenie 1. Witamy w krainie wzorców projektowych: wprowadzenie 2. Jak sprawić by Twoje obiekty były zawsze dobrze poinformowane: Wzorzec Obserwator 3. Dekorowanie zachowania obiektów: Wzorzec Dekorator 4. Pizzeria zorientowana obiektowo: Wzorzec Fabryka 5. Obiekty jedyne w swoim rodzaju: Wzorzec Singleton 6. Hermetyzacja wywołań: Wzorzec Polecenie 7. Zdolność do adaptacji: Wzorce Adapter oraz Fasada 8. Hermetyzacja algorytmów: Wzorzec Metoda Szablownowa 9. Zarządzanie kolekcjami: Wzorce Iterator i Kompozyt 10. Stan obiektu: Wzorzec Stan 11. Kontrola dostępu do obiektu: Wzorzec Proxy 12. Łączenie wzorców: Wzorce złożone 13. Wzorce projektowe w praktyce: Nowe życie z wzorcami 14. Dodatek: inne wzorce Skorowidz 21 33 67 109 139 197 217 259 297 335 403 447 517 595 629 649 Spis treści (na serio) Wprowadzenie Twój mózg jest skoncentrowany na wzorcach projektowych. W tym rozdziale Ty starasz się czegoś dowiedzieć, a Twój mózg robi Ci przysługę i nie przykłada się do zapamiętywania zdobywanej wiedzy. Twój mózg myśli sobie: „Lepiej zostawię miejsce w pamięci na bardziej istotne informacje, na przykład: jakich dzikich zwierząt należy unikać bądź czy jeżdżenie nago na snowboardzie jest dobrym pomysłem”. A zatem, w jaki sposób możesz przekonać swój mózg, że Twoje życie zależy od poznania wzorców projektowych? Dla kogo przeznaczona jest ta książka? Wiemy także, co sobie myśli Twój mózg Metapoznanie Zmuś swój mózg do posłuszeństwa Zespół recenzentów technicznych Podziękowania 22 23 25 27 30 31 6 Wprowadzenie do wzorców projektowych 1 Witamy w krainie wzorców projektowych Ktoś rozwiązał już Twoje problemy. W tym rozdziale dowiesz się, dlaczego (i w jaki sposób) możesz wykorzystać wiedzę i doświadczenia zdobyte przez innych projektantów i programistów, którzy podczas pracy nad różnymi projektami zmuszeni byli wstąpić na pełną zdradliwych pułapek ścieżkę i — co najważniejsze — udało im się przeżyć taką wyprawę. Zanim dobrniemy do końca rozdziału, rzucimy okiem na sposoby wykorzystywania wzorców projektowych i przedstawimy ich zalety, poznamy kilka podstawowych zasad projektowania zorientowanego obiektowo, a także omówimy sposób działania przykładowego wzorca. Najlepszą metodą zastosowania wzorca jest załadowanie go bezpośrednio do Twojego mózgu, a następnie zlokalizowanie obszarów w obrębie projektowanych rozwiązań oraz istniejących aplikacji, w których możesz je zastosować. Pracując z wzorcami projektowymi, zamiast wielokrotnego wykorzystywania tych samych fragmentów kodu, wielokrotnie wykorzystujesz swoje doświadczenia. Pamiętaj, opanowanie takich zagadnień, jak abstrakcyjność, dziedziczenie i polimorfizm, nie zrobi jeszcze z Ciebie dobrego projektanta systemów zorientowanych obiektowo. Prawdziwy guru zawsze myśli o stworzeniu elastycznego projektu, który będzie łatwy do serwisowania i będzie sobie w stanie poradzić ze zmieniającymi się warunkami. Prosta aplikacji o nazwie SymulatorKaczki Jacek rozmyśla o dziedziczeniu… A może by tak interfejs? Jedyny pewny element w procesie tworzenia oprogramowania Oddzielanie tego, co się zmienia, od tego, co pozostaje niezmienione Projektowanie zachowania Kaczki Testowanie kodu klasy Kaczka Dynamiczne ustawianie zachowania Wielki diagram „ukrytych” zachowań Relacja MA może być lepsza niż JEST Rozmawiając o wzorcach projektowania Potęga wspólnego słownika wzorców W jaki sposób mogę wykorzystywać wzorce projektowe? Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 34 37 38 40 42 43 50 52 54 55 56 60 61 64 66 E n c a p s u l a t e d fl y b e h a v i o r i n t e r f a c e F l y B e h a v i o r fl y ( ) T w ó j M Ó Z G h c y w o t k e j o r p w ó c r o z w a p u r G i e n t C l D u c k F l y B e h a v i o r fl y B e h a v i o r ; Q u a c k B e h a v i o r q u a c k B e h a v - s w i m ( ) d i s p l a y ( ) p e r f o r m Q u a c k ( ) p e r f o r m F l y ( ) s e t F l y B e h a v i o r ( ) s e t Q u a c k B e h a v i o r ( ) O T H E R d u c k - l i k e m e t h - / / D e c o y D u c k d i s p l a y ( ) { l l o o k s / / i k e a d e c o y D u c k r u b b e r d u c k } R u b b e r ) d i s p l a y ( l o o k s / / { i k e a l } R e d h e a d D u c k ) d i s p l a y ( r e d h e a d l o o k s / / { i k e a l l a r d D u c k M a l { ) d i s p l a y ( i k e a m a l l o o k s / / Object that holds state l a r d l } t h W i n g s F l y W i fl y ( ) { i m p l e m e n t s d u c k / / fl y i n g F l y N o W a y d o n o t h i n g - c a n ’ fl y ( ) { / } / fl y ! t E n c a p s u l a t e d q u a c k b e h a v i o r i n t e r f a c e Q u a c k B e h a v i o r q u a c k ( ) M u t e Q u a c k q u a c k ( ) { d o n o t h i n g - c a n ’ / / q u a c k ! t S q u e a k q u a c k ( ) { r u b b e r d u c k i e / / s q u e a k Q u a c k q u a c k ) { i m p l e m e n t s d u c k / / q u a c k i n g OBSERWATOR 8 int Subject O bj e ct 8 8 8 8 Dog O bject Duck O bject Cat Obj e ct Automatic update/notification Mouse O bject C o n t Observers r o l l e r V i e w t n e d n e bje p e D O s t c M V C e l d M o j u ż c a ł k i e m t e r a z K o d, w z b o g a c o n y p o p r z e z i Tw ó j n o w y z a s t o s o w a n i e w z o r c ó w p r o j e k t o w y c h . 7 Request Wzorzec Obserwator 2 Jak sprawić, by Twoje obiekty były zawsze dobrze poinformowane Nie przegap okazji, kiedy dzieje się coś naprawdę ciekawego! Przedstawimy Ci wzorzec, który potrafi poinformować inne obiekty o tym, że wydarzyło się coś, czym powinny się zająć. Co ciekawe, obiekty mogą nawet samodzielnie decydować w czasie działania programu o tym, czy chcą być informowane o takich wydarzeniach. Wzorzec Obserwator jest jednym z najczęściej wykorzystywanych wzorców w pakiecie JDK (ang. Java Development Kit) a co najważniejsze, jest wręcz niewiarygodnie użyteczny. W niniejszym rozdziale rzucimy również okiem na relacje typu jeden-do-wielu oraz tzw. luźne związki (tak, to prawda, napisaliśmy „luźne związki”). Korzystając z wzorca Obserwator, z pewnością odmienisz swoje życie. P o d s t a w y p r o g r a m o w a n i a o b i e k t o w e g o A b s t r a k c y j n o ś ć H e r m e t y z a c j a i z m i m o r f Po l D z i e d z i c z e n i e i t o, c o R e g u ł y p r o g r a m o w a n i a o b i e k t o w e g o R e g u ł y p r o g r a m o w a n i a o b i e k t o w e g o s i ę z m i e n i a . h e r m e t y z a c j Po d d a w a j k o m p o z y c j ę n a d d z i e d z i c z e n i e . P r z e d k ł a d a j s ó w, i n t e r f e j s i ę n a t w o r z e n i u S k o n c e n t r u j i m p l e m e n t a c j a n i e s i ę t w o r z y ć p r o j e k t y, w k t ó r y c h i, o l u ź n o p o w i ą z a n e S t a r a j s ą z e o b i e k t y i w e, n i e o d d z i a ł u j ą n a m o ż l s o b ą . i i l e t o s i e b i e w z a j e m n i e . Aplikacja sprawdzająca warunki pogodowe Spotkanie z wzorcem Obserwator Wydawca + Prenumerator = wzorzec Obserwator Pięciominutowe przedstawienie — obserwowany kontra obserwujący Definicja wzorca Obserwator Siła luźnych zależności Projektowanie stacji meteorologicznej Implementacja stacji meteorologicznej Java — zastosowanie wbudowanego wzorca Obserwator Ciemna strona klasy java.util.Observable Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 69 74 75 78 81 83 86 87 94 101 104 107 Obiekt, którego stan jest obserwowany RELACJA JEDEN-DO-WIELU 8 int Obiekt obs e w r o wany 8 8 8 8 Obiekt Pies Obiekt K a czka Obiekt K o t Automatyczna aktualizacja (powiadamianie) Obiekt Mysz Obiekty obserwujące (Observers) e n ż e l a z y t k e i b O 8 Wzorzec Dekorator 3 Dekorowanie zachowania obiektów W zasadzie niniejszy rozdział możemy równie dobrze zatytułować „Otwieranie oczu programistom z nadmiernymi skłonnościami do nadużywania dziedziczenia”. W tym rozdziale spróbujemy krytycznie przyjrzeć się zwyczajowym skłonnościom do nadużywania mechanizmu dziedziczenia oraz nauczymy Cię sposobów dekorowania zachowania klas w czasie działania programu przy użyciu pewnej formy kompozycji obiektów. Dlaczego? Po zapoznaniu się z technikami dekoracji zachowania klas będziesz mógł wyposażać swoje (i nie tylko) obiekty w nowe możliwości bez konieczności dokonywania jakichkolwiek modyfikacji w kodzie klas podstawowych. Witamy w „Star Caf�” Reguła otwarte-zamknięte Spotkanie z wzorcem Decorator Konstruowanie zamówienia przy użyciu Dekoratorów Definicja wzorca Decorator Dekorujemy nasze Napoje Tworzymy kod aplikacji „Star Caf�” Dekoratory w świecie rzeczywistym: obsługa wejścia-wyjścia w języku Java Tworzenie własnych dekoratorów obsługi wejścia-wyjścia Twoja skrzynka narzędziowa Rozwiązania ćwiczeń Zawsze sądziłem, że prawdziwi mężczyźni tworzą podklasy dla wszystkiego, co się tylko do tego nadaje. Tak było — do czasu, gdy dowiedziałem się o korzyściach, jakie daje możliwość rozszerzania możliwości aplikacji na poziomie działania, a nie kompilacji. A teraz — spójrzcie tylko na mnie! 110 116 118 119 121 122 125 130 132 135 136 9 Wzorzec Fabryka 4 Pizzeria zorientowana obiektowo Przygotuj się do stworzenia kilku projektów, w których zastosujemy luźne powiązania pomiędzy poszczególnymi obiektami. Stworzenie nowego obiektu to dużo więcej niż tylko proste zastosowanie operatora new. Niebawem przekonasz się, że proces ten jest operacją, która nie zawsze powinna być publicznie dostępna, a co więcej, jest operacją, która często może prowadzić do poważnych problemów z powiązaniami międzyobiektowymi. A tego byś nie chciał, prawda? Przekonaj się, w jaki sposób wzorzec Factory może uratować Cię z takiej opresji. Klientami fabryki abstrakcyjnej są dwa obiekty naszej klasy Pizzeria, WłoskaPizzeria i Amerykańska Pizzeria. WłoskaPizzeria utwórzPizza() interfejs Ciasto GrubeChrupkieCiasto CienkieChrupkieCiasto interfejs Sos SosPomidorowy SosMarinara interfejs Ser SerMozzarella SerReggiano interfejs Małże MrożoneMałże ŚwieżeMałże Każda fabryka wytwarza różne implementacje tej samej rodziny produktów. Klasa abstrakcyjna FabrykaSkładnikówPizzy jest interfejsem, który określa, w jaki sposób powinna być tworzona rodzina spokrewnionych produktów — wszystkie składniki, które są niezbędne do zrobienia pizzy. interfejs FabrykaSkładnikówPizzy utwórzCiasto() utwórzSos() utwórzSer() utwórzWarzywa() utwórzPepperoni() utwórzMałże() WłoskaFabrykaSkładnikówPizzy AmerykańskaFabryka SkładnikówPizzy utwórzCiasto() utwórzSos() utwórzSer() utwórzWarzywa() utwórzPepperoni() utwórzMałże() utwórzCiasto() utwórzSos() utwórzSer() utwórzWarzywa() utwórzPepperoni() utwórzMałże() Zadaniem fabryk rzeczywistych jest wytwarzanie odpowiednich składników pizzy. Każda fabryka wie, w jaki sposób należy utworzyć składniki odpowiednie dla danego regionu. Kiedy widzisz „nowy” obiekt, myśl o nim jako o „konkretnym” Pizza w Obiektowie Hermetyzacja procesu tworzenia obiektów Budujemy prostą fabrykę pizzy Tworzymy definicję „wzorca” Simple Factory Nowa struktura Pizzerii Zezwalamy klasom podrzędnym na podejmowanie decyzji Tworzymy Pizzerię Deklarowanie metody typu Factory (fabryka) Spotkanie z wzorcem Metoda Fabrykująca Równoległa hierarchia klas Definicja wzorca Metoda Fabrykująca Pizzeria mocno uzależniona Sprawdzamy zależności pomiędzy obiektami Zastosowanie reguły DIP A w międzyczasie, na zapleczu Pizzerii… Rodziny składników… Budujemy fabryki składników pizzy Fabryka Abstrakcyjna Za kulisami Definicja wzorca Fabryka Abstrakcyjna Porównanie Metody Fabrykującej oraz Fabryki Abstrakcyjnej Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 140 142 144 145 147 150 151 153 155 161 162 164 167 168 170 174 175 176 183 184 186 190 192 193 10 Wzorzec Singleton 5 Obiekty jedyne w swoim rodzaju Kolejnym przystankiem w naszej podróży jest wzorzec Singleton, czyli nasza przepustka do kreowania jedynych w swoim rodzaju obiektów, posiadających tylko jedną instancję. Być może ucieszysz się na wieść o tym, że Singleton jest najprostszym z istniejących wzorców projektowych (przynajmniej pod względem kategorii stopnia złożoności jego diagramu klas); jak by na to nie patrzeć, jego diagram składa się tylko z jednej klasy! Ale nie wpadaj w euforię; niezależnie od prostoty diagramu klas tego wzorca na drodze prowadzącej do jego implementacji napotkamy całkiem sporo wybojów i dziur. Lepiej zapnij mocno pasy — to nie będzie takie proste jakby mogło się wydawać. Jeden i tylko jeden Mały Singleton Analiza klasycznej implementacji wzorca Singleton Wyznania obiektu Singleton Fabryka czekolady Definicja wzorca Singleton Uuups, mamy problem… Zostań wirtualną maszyną Java Jak sobie radzić z wielowątkowością? Wzorzec Singleton — pytania i odpowiedzi Twoja skrzynka narzędziowa Rozwiązania ćwiczeń Hershey, PA i W z o r c e p r o g r a m o w a n i a o b i e k t o w e g o j e d e n - r e l a c j ę i n i u j e r o d z i n y a l g o r y t m ó w, d o k o n u j e i n i u j e p o m i ę d z y o b i e k t a m i D e k o r a t o r — p o z w a l a n a d y n a m i c z n e p r z y d z i e l a n i e s p o s ó b, ż e k i e d y w y b r a n y o b i e k t z m i e n i a s i ę o n e w y m i e n n e . O b s e r w a t o r — d e f S t r a t e g y — d e f s t a j ą D e k o r a t o r y d a j ą d o s p o w o d u j e, ż e i n t e r f e j j e g o o b i e k t y z a l e ż n e z o s t a j ą o t y m i k a c j ę d a n e g o Fa b r y k a A b s t r a k c y j n a — d o s t a r c z a p o z w a l a j ą c y n o w y c h z a c h o w a ń . l u b z a l e ż n y c h i c h h e r m e t y z a c j d o - w i e l u w t a k i W z o r z e c S t r a t e g y p o z w a l a n a m o d y f j a k ą d a j e d z i e d z i c z e n i e, s i e n t a, k t ó r y t e g o a l g o r y t m u i n t e r f e j s p o k r e w n i o n y c h d a n e m u o b i e k t o w i i z o w a n e . i n i u j e s t a n, w s z y s t k i e n a t w o r z e n i e o b i e k t ó w, a l e p o z w a l a k l a s o m p o d r z ę d n y m S i n g l e t o n — z a p e w n i a, ż e d a n a k l a s a b ę d z i e m i a ł a t y l k o M e t o d a Fa b r y k u j ą c a — d e f i c h k l a s a u t o m a t y c z n i e z a k t u a l t w o r z e n i a c a ł y c h r o d z i n e l a s t y c z n o ś ć p o d o b n ą d o t e j, o k r e ś l a n i a s w ó j j e d n a k w z a m i a n z n a c z n i e r o z s z e r z o n ą a l g o r y t m u n i e z a l e ż n i e o d k l s i e b i e o b i e k t ó w b e z k o n i e c z n o ś c i z a p e w n i a g l o b a l n y i p o w i a d o m i o n e k l a s y o b i e k t z o s t a n i e u t w o r z o n y. W z o r z e c Fa c t o r y M e t h o d p r z e k a z u j e o d p o w i e d z i a l n o ś ć z a i i n s t a n c j ę o b i e k t u o f e r u j ą c o d u ż y w a . j a k i e j j e d n ą r z e c z y w i s t y c h . d e c y d o w a ć, w y ł ą c z n i e f u n k c j o n a l n o ś ć . i n s t a n c j i p u n k t d o s t ę p u d o t e j p o d r z ę d n y c h . t w o r z e n i e o b i e k t ó w d o k l a s . i i 198 199 201 202 203 205 206 207 208 212 214 216 11 Wzorzec Polecenie 6 Hermetyzacja wywołań W niniejszym rozdziale przeniesiemy hermetyzację na zupełnie nowy poziom: mamy zamiar dokonać hermetyzacji wywołań metod. Zgadza się, dzięki hermetyzacji wywołań metod możemy wykrystalizować pewne fragmenty obliczeń tak, że obiekt wywołujący obliczenia nie musi się martwić, w jaki sposób je wykonać; po prostu wykorzystuje naszą metodę. Z takimi hermetyzowanymi wywołaniami metod możemy również dokonywać wielu zadziwiająco sprytnych operacji, takich jak na przykład zapisywanie ich do dzienników czy też ponowne wykorzystywanie w celu zaimplementowania mechanizmu Cofnij (ang. Undo) w naszej aplikacji. Automatyka w domu i zagrodzie Mamy nową zabawkę! Sprawdzamy, jak działa SuperPilot… Co zawiera otrzymany dysk CD-R A w międzyczasie w naszym barze szybkiej obsługi… Przyjrzyjmy się nieco dokładniej wzajemnym interakcjom… Zadania i zakresy odpowiedzialności Od Baru do wzorca Polecenie Nasze pierwsze POLECENIE Definicja wzorca Polecenie Wzorzec Command i SuperPilot Implementujemy SuperPilota Sprawdzamy możliwości naszego SuperPilota Nadszedł wreszcie czas, aby utworzyć trochę dokumentacji… Implementacja mechanizmu wycofywania przy użyciu stanów Każdy pilot powinien posiadać tryb Impreza! Zastosowanie makropoleceń Kolejne zastosowania wzorca Polecenie — kolejkowanie żądań Kolejne zastosowania wzorca Polecenie — żądania rejestracji Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 218 219 220 223 224 225 227 229 232 234 236 238 241 246 250 251 254 255 256 258 P o p r o s z ę z a p i e k a n k ę z s e r e m i n a p ó j s ł o d o w y . a si ę z h w c y a m ó w i e n i a . k b n i e s a m ó w i e Z c ji w y y z o z z p k i e a n a b l a e n n a p is d a ł n a r c i e z utwórzZamówienie() r n i a o y z ł a a m ó w i e t s o e z a r u z ó t t k i e u, k n n b l a m e Z apiekanka z sere m N apój słodo w y c h i c s k pobierzZamówienie() o g e z c K li e ż, w i e j u t n n i e . a m ó w i e e, a d a z ł K e l n e r k a p r z y jm u j e Z am ów i e n i e o d k l z t ym u p o r a, w yw o ł u j e m e t o d ę r e a l r o z p o c z y n a p r o c e s r e a l i z a c j i M e t o d a t a i e n t a . j u ż s i ę i k i e d y i e n t a i z u j Z am ów i e n i e ( ) . Z am ów i e n i a z ł o ż o n e g o p r z e z k l realizujZamówienie() u r g B e r M a lt p r z y g o t u j Z a p i e k a n k ę ( ) , p r z y g o t u j N a p ó j ( ) N a Z a m ó w ieniu zn ajd ują się w szelkie instrukcje niezbę d ne d o teg o, a b y p rzy g oto w a ć w łaści w y p osiłek. Z a m ó w ienie kieruje p ra cą K uch arz a, p osłu g ują c się m eto d a m i takim i, jak p rzy g otujZ a pieka nkę(). Kucharz realizuje instrukcje podane w Zamówieniu i przygotowuje odpowiedni posiłek. produkt końcowy 12 Wzorce Adapter oraz Fasada 7 Zdolność do adaptacji Europejski standard ściennego gniazda elektrycznego Adapter Standardowa wtyczka zasilająca W niniejszym rozdziale mamy zamiar dokonać paru niesamowitych wyczynów z dziedziny rzeczy niemożliwych, takich jak na przykład włożenie kwadratowego kołka do okrągłego otworu. Brzmi nierealnie? Nie wtedy, kiedy mamy pod ręką odpowiednie wzorce projektowe. Pamiętasz wzorzec Dekorator? Podczas pracy z nim owijaliśmy obiekty innymi obiektami tak, aby nadać im nowe zachowania. Teraz mamy zamiar postępować tak samo, ale w nieco innym celu: chcemy sprawić, by ich interfejsy wyglądały jak coś, czym nie są. Dlaczego jednak mielibyśmy to robić? Na przykład po to, aby zaadaptować projekt oczekujący danego interfejsu do klasy, która implementuje zupełnie inny interfejs. To jeszcze nie wszystko; skoro już jesteśmy przy tym temacie, przyjrzymy się również innemu wzorcowi, który owija obiekty w celu uproszczenia ich interfejsów. Adaptery są wśród nas Adaptery zorientowane obiektowo Wzorzec Adapter bez tajemnic Definicja wzorca Adapter Adaptery obiektów i klas Temat dzisiejszej wieczornej pogawędki: Adapter obiektów i Adapter klas Adaptery w świecie rzeczywistym Adaptujemy interfejs Enumeration do wymagań interfejsu Iterator Temat dzisiejszej wieczornej pogawędki: wzorce Dekorator i Adapter Nie ma to jak kino domowe Światła, kamera, fasada! Konstruujemy fasadę naszego systemu kina domowego Definicja wzorca Fasada Reguła ograniczania interakcji Twoja skrzynka narzędziowa Rozwiązania ćwiczeń Klient żądanie() ) ( e n o z c u m a ł T n i e a d ą ż Obiekt adaptowany Klient jest zaprojektowany niezgodnie z wymogami interfejsu docelowego. Adapter e l o w y c o d s j e f r e t i n Adapter implementuje interfejs docelowy i przechowuje instancję obiektu adaptowanego. e t p k A d y d e l o w y K a c I n a o d interfejs obiektu adaptowanego i n t e r f e j s o b i e k t u I n d y k t o a d a p t ow a n e g o . e j s f r e t u j e i n t n r i m p l e m e k z c a . 260 261 265 267 268 271 272 273 276 279 282 285 288 289 294 296 13 Wzorzec Metoda Szablonowa 8 Hermetyzacja algorytmów Jesteśmy jak w transie: hermetyzowaliśmy już proces tworzenia obiektów, wywołania metod, złożone interfejsy, kaczki, indyki, pizze… ciekawe, co będzie następne? Otóż, teraz mamy zamiar zająć się hermetyzacją fragmentów algorytmów, tak aby klasy podrzędne mogły „podczepiać się” w różnych miejscach wykonywanych obliczeń. Co więcej, zajmiemy się również regułą projektowania, której korzenie wywodzą się w prostej linii z … Hollywood. Tworzymy klasy reprezentujące kawę i herbatę (w języku Java) Kawa i herbata, czyli klasy abstrakcyjne Ciągniemy nasz projekt o krok dalej… Wydobywanie metody recepturaParzenia() Czego już dokonaliśmy? Spotkanie z wzorcem Metoda Szablonowa Zróbmy sobie herbatę… Co nam daje zastosowanie metody szablonowej? Definicja wzorca Metoda Szablonowa Bliskie spotkania z kodem aplikacji Haczyk na wzorzec Metoda Szablonowa… Zastosowanie haczyka Testujemy naszą aplikację Reguła Hollywood Reguła Hollywood a wzorzec Metoda Szablonowa Wzorzec Metoda Szablonowa w głębokiej kniei… Sortowanie przy użyciu wzorca Metoda Szablonowa A teraz musimy posortować trochę kaczek… Porównywanie kaczek z innymi kaczkami Robimy maszynę do sortowania kaczek Zabawy z ramkami Aplety Java Temat dzisiejszej wieczornej pogawędki: wzorce Metoda Szablonowa oraz Strategia Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 299 302 303 304 307 308 309 310 311 312 314 315 316 318 319 321 322 323 324 326 328 329 330 332 333 Zauważyliśmy, że dwie receptury są bardzo do siebie podobne, chociaż niektóre ich etapy wymagają różnych implementacji. Dzięki temu spostrzeżeniu mogliśmy uogólnić recepturę i umieścić ją w klasie bazowej. Napoje 3 4 zawierające H e r b a t a Z ag r zej o d p ow ie d nią ilo ść w o d y . Wł óż t o r e bk ę h e r b a t y d o w r zą t k u. N alej h e r b a t y d o f ili ża nk i. D o daj c y t r y n ę d o sm a k u. 1 2 3 4 Kawa 1 2 Zagrzej odpowiednią ilość wody. Zalej wrzątkiem odmierzoną porcję kawy. Nalej kawy do filiżanki. Dodaj cukier i mleko do smaku. uogólnienie niektóre etapy delegowane są do klasy podrzędneja P o d k l a s a H e r b a t a kofeinę 1 2 3 4 Zagrzej odpowiednią ilość wody. uogólnienie Zaparz napój. Nalej uzyskany napój do filiżanki. Domieszaj do napoju odpowiednie dodatki. niektóre etapy delegowane są do klasy podrzędneja Podklasa Kawa 2 4 Włóż torebkę herbaty do wrzątku. Dodaj cytrynę. Klasa NapójZKofeiną doskonale zna poszczególne etapy receptury, choć sama wykonuje tylko etap pierwszy izację , zostawiając real i trzeci etapów drugiego i czwartego klasom Kawa i Herbata. Z a p a r z o d m ie r zoną p o r cję k a w y . D o daj cuk ie r i mle k o. 2 4 14 Wzorce Iterator i Kompozyt 9 Zarządzanie kolekcjami Jest wiele sposobów grupowania obiektów w kolekcje. Można utworzyć obiekty Array, Stack, List, Hashtable. Każdy z nich ma swoje zalety i wady. Jednak w pewnym momencie klient rozpocznie iteracyjne przetwarzanie elementów kolekcji. Czy wtedy ujawnisz mu swoją implementację? Mam nadzieję, że nie. To nie byłoby profesjonalne. Nie musisz się jednak obawiać, Twoja kariera zawodowa nie jest zagrożona. W tym rozdziale przedstawimy metodę, która umożliwia klientom przetwarzanie iteracyjne bez wiedzy o tym, jak obiekty są przechowywane. Przedstawimy też technikę tworzenia superkolekcji (ang. super collections) obiektów, które pozwalają na obsługę bardzo rozbudowanych struktur danych. Będziemy też pisać o odpowiedzialności obiektów. To jest kolekcja ArrayList, która przechowuje menu poszczególnych restauracji. Wszystkie menu P ancakeHo u 1 e s Menu DinerMe n 2 u u n UJackaM e 3 Menu restauracji PancakeHouse Menu restauracji U Jacka Pozycja M e n u Pozycja M e n u Pozycja M e n u Pozycja M e n u 2 3 1 4 ArrayList Menu deserów 1 2 3 Pozycja M e n u Pozycja M e n u Pozycja M e n u Menu restauracji Diner tablica 1 2 3 4 Pozycja M e n u Pozycja M e n u Pozycja M e n u Pozycja M e n u klucz klucz klucz klucz Pozycja M e n u Pozycja M e n u Pozycja M e n u Pozycja M e n u Hashtable Kolekcja DinerMenu ma przechowywać podmenu. Jednak nie możemy wprowadzić menu jako elementu tablicy ze względu na niezgodność typów. Fuzja restauracji Diner i Pancake House Implementacje menu Łukasza i Miłosza Czy można hermetyzować iteracje? Wzorzec Iterator Wiązanie iteratora z obiektem menu Co już mamy… Szersze spojrzenie na kod naszego projektu Uproszczenia po wprowadzeniu interfejsu java.util.Iterator Jaki jest efekt końcowy? Definicja wzorca Iterator Jeden zakres odpowiedzialności Iteratory i kolekcje Iteratory i kolekcje w języku Java 5 I gdy już miało być tak dobrze… Definicja wzorca Kompozyt Projektujemy menu oparte na wzorcu Kompozyt Implementacja klasy Menu Powracamy do iteratora IteratorPusty Wzorce Iterator i Kompozyt razem… Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 336 338 343 345 347 351 353 355 356 359 368 369 373 376 379 382 388 392 394 399 400 15 Wzorzec Stan 10 Stan obiektu Mało znany fakt: wzorce Strategy i State to bliźniaki, rozdzielone zaraz po narodzinach. Jak już wiemy, wzorzec Strategy umożliwił przeprowadzenie wielu niezwykle udanych przedsięwzięć opartych na zamiennie stosowanych algorytmach. Wzorzec State ma inną rolę. Jest nią wspomaganie obiektów w kontrolowaniu ich własnych zachowań poprzez wewnętrzną zmianę stanu. Łatwo usłyszeć, jak mówi swoim podopiecznym: „Powtarzaj za mną: jestem wystarczająco zdolny, jestem wystarczająco dobry, dam radę to zrobić…”. Krótka narada Maszyny stanowe 101 Piszemy kod Wiedziałeś, że to jest blisko… zmiana! Kłopotliwy STAN rzeczy… Definiowanie interfejsów i klas reprezentacji stanu Implementowanie klas Stan Nowa wersja automatu sprzedającego Definicja wzorca Stan Wzorzec Stan kontra wzorzec Strategia Wzorzec Stan, weryfikacja projektu Niemal zapomnieliśmy! Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 405 406 408 412 414 417 419 420 428 429 435 438 441 442 Automaty Sprzedające SA gdzie automatyczny sprzedawca nigdy nie jest w połowie pusty… B r g a u k m Poniżej przedstawiamy naszą koncepcję pracy kontrolera automatu sprzedającego gumę do żucia. Mamy nadzieję, że zaimplementowanie tego schematu w Javie nie sprawi Wam trudności. W przyszłości będziemy zapewne dodawać nowe zachowania, więc prosimy o projekt możliwie elastyczny i łatwy do modyfikowania. — Inżynierowie firmy Automaty Sprzedające y t e n o nie m a d a ł k w t t e s e n a J m o N i e m e n m o t a y przekręcanie gałki y t e n o nie m a c a r w z liczbaGum 0 liczbaGum = 0 n i e w y d a w a u m y g a e z d m r G u s p a n a 16 Wzorzec Proxy 11 Kontrola dostępu do obiektu Próbowałeś kiedyś stosować metodę „dobrego i złego”? Ty jesteś tym dobrym, który zrobi wszystko, o co się go poprosi, który jest zawsze miły i uprzejmy. Nie chcesz jednak, żeby każdy mógł prosić o Twoje usługi. To jest miejsce dla „złego”, który będzie kontrolował dostęp do Ciebie. Takie jest właśnie zadanie pośredników (ang. proxy) w modelu obiektowym — kontrolowanie i zarządzanie dostępem. Jak się przekonamy, istnieje bardzo wiele schematów takiego pośrednictwa. Obiekty Proxy mogą przekazywać wywoływanie metody obiektowi w innym węźle internetu; bywa też, że zastępują wyjątkowo leniwe obiekty. B r z y d k i Ł a d n y Kontrolowania stanu automatów sprzedających Rola „zdalnego pośrednika” RMI — wycieczka z przewodnikiem Zdalny pośrednik automatu sprzedającego Pośrednik zdalny, za kulisami Definicja wzorca Proxy Pośrednik wirtualny Projektowanie wirtualnego pośrednika do wyświetlania okładek Pośrednik wirtualny, za kulisami Wykorzystanie mechanizmów Java API Teatrzyk — ochrona przedmiotów Budowanie dynamicznego pośrednika ZOO pośredników Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 448 452 455 468 476 478 480 482 488 492 496 497 506 508 509 interface Przedmiot żądanie() interface InvocationHandler invoke() N a p o ś r e d n i k a s k ł a d a j ą s i ę t e r a z d w i e k l a s y. PrawdziwyPrzedmiot żądanie() Proxy żądanie() InvocationHandler invoke() 17 Wzorce złożone 12 Łączenie wzorców Przyszłoby Ci do głowy, że wzorce mogą pracować razem? Byliśmy już świadkami wielu niespokojnych „Pogawędek przy kominku” (a ominął Cię „Death Match” wzorców, który wydawca kazał wyrzucić*) — czy wsłuchując się w ich ton można jeszcze liczyć na to, że wzorce będą ze sobą współpracować? Możesz wierzyć lub nie, ale najbardziej wyszukane projekty obiektowe wykorzystują wiele wzorców jednocześnie. Przygotuj się na kolejny poziom wiedzy o wzorcach projektowych. Czas na wzorce złożone. Wzorzec złożony Powrót kaczek Potrzebujemy adaptera gęsi Wprowadzamy zliczanie kwaknięć Fabryka produkująca kaczki Tworzymy stado kaczek Przygotowanie interfejsu Observable Co zrobiliśmy? Widok z lotu kaczki — diagram klas Model-Widok-Kontroler — piosenka Kluczem do schematu MVC będą wzorce projektowe Spojrzenie na schemat Model-Widok-Kontroler przez pryzmat wzorców Wykorzystujemy MVC do sterowania beatem... Piszemy kod elementów Widok A teraz kontroler Eksplorujemy możliwości wzorca Strategia Adaptowanie modelu Nowy kontroler — SerceKontroler Wzorzec MVC i sieć WWW Model 2 a wzorce projektowe Twoja skrzynka narzędziowa Rozwiązania ćwiczeń 518 519 522 524 526 531 534 541 542 544 546 550 552 555 557 560 563 564 565 567 575 578 579 Beat jest ustawiony na 119 BPM i chcemy zwiększyć szybkość do 120 BPM. Klikamy przycisk zwiększający szybkość… Widok … co powoduje wywołanie kontrolera. Kontroler żąda od modelu zwiększenia wartości BPM o jeden. e B a tModel s t a r t ( ) stop() ustawBPM() p o b i e r z B P M ( ) Controler Pasek beatu pulsuje co pół sekundy. Widok Ponieważ szybkość beatu to 120 BPM, widok jest uaktualniany co pół sekundy. Widok zostaje uaktualniony, aby wyświetlał 120 BPM. Widok jest powiadamiany o zmianie BPM. Wywołuje metodę modelu pobierzBPM(). 18 Nowe życie z wzorcami 13 Wzorce projektowe w praktyce Ach, jesteś już gotowy na spotkanie z nowym wspaniałym światem pełnym wzorców projektowych… Ale zanim rozpoczniesz wędrówkę ku nowym horyzontom, poświęć chwilę na przeczytanie rozdziału poświęconego pewnym szczególnym kwestiom, które pojawiają się, gdy rozpoczynasz stosowanie wzorców w codziennej pracy. Nie wszędzie jest tak pięknie, jak w Obiektowie. Przygotowaliśmy więc mały przewodnik, który pomoże Ci odnaleźć się w twardej rzeczywistości… P r z e w o d n i k n a n o w e ż y c i e z w z o r c a m i P r z y j m i j , p r o s z ę , n a s z p o d r ę c z n y z b i ó r p o r a d , k t ó r e p o m o g ą C i ż y ć z w z o r c a m i p r o j e k t o w y m i w c o d z i e n n e j p r a c y i z m a g a n i a c h . n i e p o r o z u m i e n i a c h z w i ą z a n y c h z t e r m i n e m „ w z o r z e c p r o j e k t o w y ” ;  B ę d z i e m y w n i m m ó w i ć o : k a t a l o g a c h w z o r c ó w p r o j e k t o w y c h u n i k a n i u s t o s o w a n i a w z o r c ó w t a m , g d z i e n i e p r z y d a ć ;  w ł a ś c i w y m k l a s y f i k o w a n i u w z o r c ó w ; d e f i n i o w a n i u w z o r c ó w p r o j e k t o w y c h z a r e z e r w o w a n e d l a w y b r a n y c h . D o w i e s z s i ę , ć w i c z e n i a c h u m y s ł u , k t ó r e t r a k t u j e m y z r ó w n ą p o w a g ą , w z o r c ó w ;  U j a w n i m y t o ż s a m o ś ć G a n g u C z t e r e c h — t a j e m n i c z e g o G a n g o f Fo u r. m i s t r z o w i e Z e n . p o w i n i e n m i e ć k a ż d y u ż y t k o w n i k w z o r c ó w w p ł y w a ć n a p r o g r a m i s t ó w, s t o s u j ą c j a k b a r d z o m o g ą C i j e s t t o p o t r z e b n e ; j e s t t o z a j ę c i e j a k z o s t a ć a u t o r e m o t y m , ż e n i e o t y m , j a k i e k s i ą ż k i j a k z d o b y ć p r z y j a c i ó ł  Z d r a d z i m y, p r o j e k t o w y c h . p r e c y z y j n ą t e r m i n o l o g i ę w z o r c ó w p r o j e k t o w y c h .  O p o w i e m y, i   j a k    s i ę i i Przewodnik na nowe życie z wzorcami Definicja wzorca projektowego Drugie spojrzenie na definicję wzorca Niech moc będzie z Tobą Katalog wzorców Jak tworzyć wzorce Zostać autorem wzorców projektowych Porządkowanie wzorców projektowych Myślenie wzorcami Głowa pełna wzorców Nie zapominaj o potędze jednolitego słownictwa Pięć podstawowych sposobów promowania Twojego słownictwa Gang Czterech w Obiektowie Podróż dopiero się zaczyna… Inne źródła informacji o wzorcach ZOO pełne wzorców Walka ze złem przy użyciu antywzorców Twoja skrzynka narzędziowa Opuszczamy Obiektowo… d r a h e l m R i c H Ralph Johnson Gang czterech John Vlissides Erich Gamma 578 597 599 600 601 604 605 607 612 615 617 618 619 620 621 622 624 626 627 19 14 Dodatek — inne wzorce Nie wszyscy mogą być sławni. Przez ostatnie dziesięć lat wiele się w świecie wzorców zmieniło. Od czasu pierwszego wydania książki Design Patterns: Elements of Reusable Object-Oriented Software (Wzorce projektowe) programiści wykorzystali opisane w nich schematy tysiące razy. Wzorce, które zebraliśmy w tym dodatku, to dopracowane, kompletne, „oficjalne” wzorce grupy GoF. Różnią się od wcześniej opisanych tylko tym, że nie spotkamy ich tak często, jak tych, którym poświęciliśmy całe rozdziały. Nie umniejsza to ich zalet i nie powinno zniechęcać do ich stosowania tam, gdzie wymaga tego sytuacja. Celem niniejszego dodatku jest zapewnienie Ci szerszej orientacji w najłatwiej dostępnych zasobach zgromadzonej przez lata wiedzy. Bridge (most) Builder (budowniczy) Chain of Responsibility (łańcuch odpowiedzialności) Flyweight (waga piórkowa) Interpreter (interpreter) Mediator (mediator) Memento (memento) Prototype (prototyp) Visitor (gość) Jedyne, czego wymagamy od klas kompozytu, to metody pobierzStan() (i tego, żeby nie obawiały się ujawnienia). Klasa Gość musi mieć możliwość wywołania metody pobierzStan() każdej z klas. Jest miejscem, gdzie można wprowadzić nowe metody, z których będą korzystać klienty. p o b i e r z S t a n ( ) Menu pobierzStan() Gość p o pobierzStan() pobierzStan() b ie r z S t a n ( ) Pozycja Menu Pozycja Menu Klient żąda, aby Gość pobrał informacje ze struktury Compoztu… Dodawanie nowych metod klasy Gość nie wpływa na kompozyt. p o bierz W skaźnik W arto ś ci Z dro w otn ej() p o bierz K alorie() p o bierz W ę glo w o d a n y() p o bierz Białka() Klient i Obiekt przechodzenia Obiekt przechodzenia (Traverser) umie przeprowadzić gościa przez całą strukturę kompozytową. Składnik Składnik S Skorowidz 20 630 632 634 636 638 640 642 644 646 649 Rozdział 3. Wzorzec Dekorator   Dekorowanie zachowania obiektów  Zawsze sądziłem, że prawdziwi mężczyźni tworzą podklasy dla wszystkiego, co się tylko do tego nadaje. Tak było — do czasu, gdy dowiedziałem się o korzyściach, jakie daje możliwość rozszerzania możliwości aplikacji na poziomie działania, a nie kompilacji. A teraz — spójrzcie tylko n a mnie! W zasadzie niniejszy rozdział możemy równie dobrze zatytułować „Otwieranie oczu programistom z nadmiernymi skłonnościami do nadużywania dziedziczenia”. W tym rozdziale spróbujemy krytycznie przyjrzeć się zwyczajowym skłonnościom do nadużywania mechanizmu dziedziczenia oraz nauczymy Cię sposobów dekorowania zachowania klas w czasie działania programu przy użyciu pewnej formy kompozycji obiektów. Dlaczego? Po zapoznaniu się z technikami dekoracji zachowania klas będziesz mógł wyposażać swoje (i nie tylko) obiekty w nowe możliwości bez konieczności dokonywania jakichkolwiek modyfikacji w kodzie klas podstawowych. to jest nowy rozdział 109 Historia pewnej kafejki Witamy w „Star Café” „Star Café” jest jedną z najszybciej rozwijających się sieci kawiarni*. Jeżeli przez okno widzisz jedną z nich, możesz być całkowicie pewny, że gdy wyjrzysz za róg najbliższego skrzyżowania, zobaczysz kolejną. Ponieważ rozwijają się tak szybko, ostatnio niemal rozpaczliwie walczą z tym, aby kolejne aktualizacje ich systemu zamówień nadążały za ciągle rozszerzającą się paletą oferowanych napojów. Kiedy pierwsza kawiarenka „Star Café” otwarła swe podwoje dla klientów, diagram klas ich systemu zamówień wyglądał mniej więcej tak: Napoje to klasa abstrakcyjna, której podklasami są poszczególne rodzaje napojów oferowanych w naszej kafejce. Metoda koszt() jest abstrakcyjna; poszczególne podklasy powinny posiadać własne jej implementacje. Napój opis pobierzOpis() koszt() // Inne użyteczne metody... Zmienna obiektowa opis jest ustawiana w każdej podklasie; przechowuje opisy poszczególnych napojów, jak np. „Znakomity, mocno palony gatunek kawy!”. Metoda pobierzOpis() jako rezultat zwraca wartość zmiennej opis. StarCafeSpecial MocnoPalona Bezkofeinowa Espresso koszt() koszt() koszt() koszt() Każda podklasa posiada zaimplementowaną metodę koszt(), która zwraca cenę danego napoju. * Oczywiście, jest to sieć fikcyjna, wszelkie podobieństwo do jakiejkolwiek rzeczywistej instytucji jest całkowicie przypadkowe i niezamierzone — przyp. tłum. 110 Rozdział 3 Wzorzec Dekorator Do każdej kawy możesz również zamówić szereg dodatków, takich jak mleko, mleczko sojowe, mocha* (znana również pod nazwą „czekolada”). Możesz pokryć to wszystko bitą śmietaną. „Star Café” za każdy z tych dodatków dolicza niewielką opłatę, więc, chcąc nie chcąc, właściciele sieci musieli informacje o dodatkach (i ich możliwych kombinacjach) wbudować w swój system zamówień. Ich pierwsza próba wyglądała mniej więcej tak… Napój opis pobierzOpis() koszt() // Inne użyteczne metody... MocnoPalona NapojeMocnoPalonaZMlekiem koszt() koszt() MocnoPalonaZMlekiemCzekoladą Bezkofeinowa ZCzekoladą StarCafeSpecial ZMlekiem koszt() koszt() koszt() MocnoPalonaZCzekoladą koszt() MocnoPalonaZBitąŚmietaną CzekoladąMleczkiemSojowym StarCafeSpecial ZCzekoladą NapojeMocnoPalonaZBitąŚmietaną koszt() BezkofeinowaZMlekiemCzekoladą koszt() MleczkiemSojowym StarCafeSpecialZMlekiem Czekoladą koszt() StarCafeSpecialZMlekiemCzekoladą MleczkiemSojowym koszt() StarCafeSpecialZCzekoladą MleczkiemSojowym Bezkofeinowa ZMlekiemCzekoladą koszt() EspressoZBitąŚmietanąEspressoWith MocnoPalonaZMlekiemCzekoladąMl koszt() eczkiemSojowym Bezkofeinowakoszt() koszt() MocnoPalonaZCzekoladą koszt() koszt() koszt() MocnoPalonaZBitąŚmietaną koszt() BezkofeinowaZMlec koszt() MleczkiemSojowym koszt() cost() BezkofeinowaZMlekiem cost() cost() BezkofeinowaZMlekiem DarkRoastWithSoy NapojeBezkofeinowaZBitąŚmietaną BezkofeinowaZCzekoladą MleczkiemSojowym koszt() StarCafeSpecial koszt() koszt() EspressoZMlekiemCzekoladą koszt() EspressoZMlekiem cost() DarkRoastWithSoy StarCafeSpecialZMlekiemCzekoladąEspr Espresso essoWithSteamedMilk koszt() koszt() MocnoPalonaZBitąŚmietaną CzekoladąMleczkiemSojowym cost() StarCafeSpecialZBitąŚmietaną CzekoladąMleczkiemSojowym DecafWithSoy BezkofeinowaZCzekoladąNapoje koszt() cost() MocnoPalonaZCzekoladą MleczkiemSojowym koszt() koszt() BezkofeinowaZBitąŚmietaną koszt() BezkofeinowaZBitąŚmietanąNapoje koszt() koszt() koszt() BezkofeinowaZMlekiem MleczkiemSojowym cost() StarCafeSpecialZCzekoladą MleczkiemSojowym BezkofeinowaZCzekoladąMleczkiem Sojowym cost() EspressoZCzekoladąMleczkiem StarCafeSpecialZMlekiemCzekoladą cost() MleczkiemSojowym Sojowym koszt() EspressoZMlekiemCzekoladą MleczkiemSojowym koszt() koszt() Uuuaaa! To się dopiero nazywa „eksplozja klas”! Poszczególne metody koszt() obliczają cenę danego napoju przy uwzględnieniu odpowiedniej kawy oraz wszystkich zamówionych dodatków. * Pod nazwą Mocha (lub Arabica Mocha) kryje się również znakomity gatunek kawy arabskiej, odznaczający się wybitnie czekoladowym aromatem i średnią mocą napoju; polecam! — przyp. tłum. jesteś tutaj 111 Pogwałcenie reguł projektowania Wysil szare komórki Chyba dla wszystkich jest oczywiste, że projektanci ze „Star Café” sami sobie narobili kłopotów, tworząc strukturę aplikacji, która z punktu widzenia serwisowania, modyfikacji i rozbudowy jest po prostu koszmarnym snem szalonego programisty. Wyobraź sobie tylko, co oni powinni zrobić, jeśli cena mleka pójdzie w górę? Albo co mają zrobić, jeśli firma wprowadzi nową polewę karmelową? Spróbuj pomyśleć nieco szerzej, nie tylko o problemie serwisowania aplikacji — które spośród omawianych do tej pory reguł projektowania zostały pogwałcone podczas tworzenia tego projektu? Wskazówka: dwie z tych reguł zostały tutaj kompletnie podeptane! Przecież to głupie — po co nam te wszystkie klasy? Czy nie możemy po prostu użyć zmiennych obiektowych oraz mechanizmu dziedziczenia z klasy nadrzędnej do obsługi wszystkich dodatków? No dobrze, zatem spróbujmy tak zrobić. Projektowanie rozpoczniemy z naszej superklasy bazowej Napój, do której dodamy zmienne obiektowe odpowiadające temu, czy dany napój będzie z mlekiem, czy też nie; czy będzie z czekoladą, czy nie itd. Napój opis mleko mleczko sojowe czekolada bita śmietana pobierzOpis() koszt() zMlekiem() dodajMleko() zMleczkiemSojowym() dodajMleczkoSojowe() zCzekoladą() dodajCzekoladę() zBitąŚmietaną() dodajBitąŚmietanę() // Inne użyteczne metody... typu boolean dla każdego z dodatków. Teraz zaimplementujemy metodę koszt() bezpośrednio w klasie Napój (do tej pory była to metoda abstrakcyjna), tak że będzie mogła policzyć cenę powiązaną z dodatkami dla danego obiektu klasy Napój. Klasy podrzędne będą nadal miały własne wersje metody koszt() (czyli będą przesłaniały metodę koszt()), aczkolwiek będą również wywoływały tę metodę bezpośrednio z klasy nadrzędnej (czyli superwersję tej metody) tak, aby mogły policzyć cenę napoju podstawowego plus koszty wszystkich zamówionych do niego dodatków. Te metody pobierają oraz ustawiają wartości zmiennych logicznych dla poszczególnych dodatków. 112 Rozdział 3 Wzorzec Dekorator A teraz dodajmy do naszego diagramu poszczególne podklasy, po jednej dla każdego napoju wyszczególnionego w menu: Metoda koszt() zaimplementowana w klasie nadrzędnej będzie wyliczała całkowity koszt wszystkich zamówionych do danego napoju dodatków, podczas gdy przesłaniające metody koszt() w klasach podrzędnych rozszerzą jej funkcjonalność, pozwalając dołączyć cenę danego napoju podstawowego. Każda metoda koszt() musi policzyć cenę napoju podstawowego, a następnie dodać cenę dodatków, wywołując w tym celu metodę koszt() z klasy nadrzędnej. Napój opis mleko mleczko sojowe czekolada bita śmietana pobierzOpis() koszt() zMlekiem() dodajMleko() zMleczkiemSojowym() dodajMleczkoSojowe() zCzekoladą() dodajCzekoladę() zBitąŚmietaną() dodajBitąŚmietanę() // Inne użyteczne metody... StarCafeSpecial MocnoPalona Bezkofeinowa Espresso koszt() koszt() koszt() koszt() Zaostrz ołówek Spróbuj napisać kod implementujący metodę koszt() dla następujących klas (możesz użyć w zapisie pseudokodu Java): public class Napój { public double koszt() { } } public class MocnoPalona extends Napój { public MocnoPalona() { opis = Znakomity, mocno palony gatunek kawy! } public double koszt() { } } jesteś tutaj 113 Wpływ zmian Zobaczmy, w sumie wyszło z tego pięć klas. Czyli definitywnie jest to kierunek, w którym powinniśmy się dalej poruszać. Nie jestem tego taki pewny; jeżeli sobie pomyślę, jakie zmiany może przechodzić ten projekt w przyszłości, przewiduję kilka potencjalnych problemów. Zaostrz ołówek Jakie wymagania (bądź inne czynniki) mogą się zmieniać tak, że będą miały wpływ na nasz projekt? Zmiana cen poszczególnych dodatków będzie nas zmuszała do modyfikacji istniejącego kodu. Wprowadzanie do oferty nowych dodatków będzie nas zmuszało do dodawania nowych metod oraz modyfikacji kodu metody koszt() w klasie nadrzędnej. Może się okazać, że w ofercie pojawią się nowe napoje. Dla niektórych napojów (na przykład dla mrożonej herbaty) pewne dodatki mogą być nieodpowiednie, aczkolwiek mimo wszystko podklasa Herbata powinna dziedziczyć takie metody, jak np. zBitąŚmietaną(). A co w sytuacji, kiedy klient zażyczy sobie podwójną porcję czekolady? o l e j: T w o j a k 114 Rozdział 3 J a n p ż u ś m y d z o p a n e j e o m y j k a li w o t n r i p r s s t z r s - o 1., ę r b y k z e ę a l e a w d o d i i ! ł Wzorzec Dekorator Mistrz i uczeń… Mistrz: Od naszego ostatniego spotkania upłynęło już całkiem sporo czasu, młody człowieku… Czy spędzałeś dużo czasu pogrążony głęboko w rozważaniach nad istotą dziedziczenia? Uczeń: Tak, Mistrzu. Dziedziczenie jest zaiste potężną bronią, nauczyłem się jednak, że nie zawsze jej użycie prowadzi do wystarczająco elastycznych i łatwych w modyfikacji projektów. Mistrz: O, co za niespodzianka! Poczyniłeś, widzę, pewne postępy! A zatem powiedz mi, mój młody adepcie, w jaki sposób możemy uzyskać kod, którego da się używać wielokrotnie, inaczej niż poprzez dziedziczenie? Uczeń: Mistrzu, nauczyłem się, że istnieją sposoby, które podczas działania programu dają takie same efekty, jakie normalnie daje dziedziczenie; należy zatem skorzystać z odpowiedniej kompozycji i delegacji. Mistrz: Proszę, kontynuuj… Uczeń: Kiedy dziedziczę dane zachowania poprzez tworzenie klasy podrzędnej, takie zachowanie jest tworzone statycznie podczas kompilacji programu. Co więcej, wszystkie klasy podrzędne muszą dziedziczyć te same zachowania. Jeżeli jednak mogę rozszerzyć zakres zachowań obiektu poprzez kompozycję, takiej operacji mogę dokonać dynamicznie podczas działania programu. Mistrz: Bardzo dobrze, mój młody adepcie, jesteś już bliski ujrzenia potęgi i mocy kompozycji. Uczeń: Tak, Mistrzu. Obecnie mogę już przy użyciu tej techniki dodawać nowe zadania do poszczególnych obiektów, włączając w to zadania, o których nawet się nie śniło projektantom klasy nadrzędnej. Co więcej, nie muszę w żaden sposób modyfikować ich kodu! Mistrz: A czego nauczyłeś się o wpływie, jaki zastosowanie kompozycji wywiera na możliwość zarządzania i modyfikacji kodu programu? Uczeń: To jest właśnie to, do czego zmierzałem, Mistrzu. Wykorzystując dynamiczną kompozycję obiektów, mogę im nadawać nowe cechy poprzez proste tworzenie nowego kodu, a nie modyfikację kodu istniejącego. Zatem, ponieważ nie będę modyfikował istniejącego kodu, szanse na wprowadzenie nowego błędu czy też zaistnienie nieoczekiwanych efektów ubocznych zdecydowanie maleją. Mistrz: Bardzo dobrze. Wystarczy na dzisiaj, młody człowieku. Teraz chciałbym, abyś się oddalił i oddał dalszym medytacjom i rozważaniom na ten temat… Pamiętaj, kod powinien być tak zamknięty (na zmiany), jak kwiat lotosu o zmierzchu, ale jednocześnie tak otwarty (na rozbudowę), jak kwiat lotosu o świcie. jesteś tutaj 115 Reguła otwarte-zamknięte Reguła otwarte-zamknięte Nasz młody adept sztuki projektowania jest teraz na najlepszej drodze do poznania jednej z najważniejszych reguł projektowania: Reguła projektowania Klasy powinny być otwarte na rozbudowę, ale zamknięte na modyfikacje. O T WA R T E Wejdź proszę, jest otwarte. Możesz bez skrępowania rozbudowywać nasze klasy dowolnymi nowymi zachowaniami. Jeżeli Twoje potrzeby lub wymagania ulegną zmianie (a my wiemy, że wcześniej czy później tak właśnie się stanie), po prostu idź do przodu i dokonuj rozbudowy wedle własnego uznania. ZAMKNIĘTE GODZINY PRACY PON. OD _____DO _____ WT. OD _____ DO _____ ŚR. OD _____ DO _____ CZW. OD _____ DO _____ PIĄ. OD _____ DO _____ Przepraszamy, zamknięte. To prawda, spędzamy masę czasu, pracując nad tym, aby kod aplikacji był stabilny i wolny od błędów, więc nie możemy pozwolić Ci go — ot, tak sobie — modyfikować. Kod musi, niestety, pozostać zamknięty na wszelkie modyfikacje. Jeżeli Ci się to nie podoba, możesz porozmawiać z przełożonym. Naszym celem jest umożliwienie łatwej rozbudowy poszczególnych klas poprzez dodawanie im nowych zachowań, ale bez konieczności modyfikacji ich istniejącego kodu. Co otrzymamy w zamian za nasze wysiłki po osiągnięciu tego celu? Struktury, które będą się łatwo adaptowały do zmian i będą wystarczająco elastyczne, aby przyjąć nowe zachowania spełniające nowe wymagania. 116 Rozdział 3 Nie ma niemądrych pytań P: Otwarte na rozbudowę i zamknięte na modyfikacje? To wygląda na swego rodzaju sprzeczność. W jaki sposób można osiągnąć taką strukturę? P: W jaki sposób mogę stworzyć strukturę (aplikacji), w której każdy z elementów będzie zgodny z regułą otwarte-zamknięte? Wzorzec Dekorator kodu naszej aplikacji. Salomonowym rozwiązaniem jest więc koncentrowanie się raczej na tych obszarach systemu, dla których prawdopodobieństwo wystąpienia znaczących zmian jest największe, i stosowanie reguł projektowania właśnie tam. obszary zmian są najważniejsze? P: Będę wiedział, które O: Częściowo jest to kwestia O: To jest bardzo dobre pytanie. Faktycznie, na pierwszy rzut oka wygląda to na sprzeczność. W końcu, jak by na to nie patrzeć, im mniejsze są możliwości modyfikacji danego czegoś, tym trudniej jest to coś rozbudować, prawda? Jak się jednak okazuje, w programowaniu zorientowanym obiektowo istnieje kilka pomysłowych technik pozwalających na rozbudowę istniejących systemów nawet w sytuacji, kiedy nie możemy modyfikować zasadniczego kodu aplikacji. Przypomnij sobie wzorzec Obserwator (o którym mówiliśmy w rozdziale 2.)… Dodając nowe obiekty obserwujące, możemy rozbudować obiekt obserwowany bez konieczności dodawania nowego kodu do tego ostatniego. Niebawem poznasz kilka nowych sposobów rozbudowy czy też dodawania kolejnych zachowań przy użyciu innych technik programowania zorientowanego obiektowo. P: No dobrze, rozumiem zasady funkcjonowania wzorca Observer, ale w jaki sposób, ogólnie mówiąc, można zaprojektować coś, co będzie podatne na rozbudowę, ale jednocześnie zamknięte na modyfikacje? O: Wiele wzorców projektowych daje nam już wielokrotnie sprawdzone w praktyce rozwiązania, które pozwalają na ochronę kodu aplikacji przed mody- fikacją przy jednoczesnej rozbudowie jej funkcjonalności. W niniejszym rozdziale znajdziesz dobry przykład zastosowania wzorca Dekorator przy jednoczesnym postępowaniu zgodnie z regułą otwarte-zamknięte. O: Zazwyczaj nie da się tego zrobić. doświadczenia w projektowaniu systemów zorientowanych obiektowo, jak również — oczywiście — dogłębna znajomość dziedziny, dla której dany system powstaje. Szczegółowa analiza innych przykładów i rozwiązań z pewnością pomoże Ci w procesie nauki identyfikacji obszarów zmiennych, które będą występowały w Twoich aplikacjach. Tworzenie elastycznych i otwartych na rozbudowę aplikacji zorientowanych obiektowo bez modyfikacji istniejącego kodu wymaga poświęcenia dodatkowego czasu i zasobów. Ogólnie rzecz biorąc, zazwyczaj nie możemy sobie pozwolić na takie zaprojektowanie każdego elementu naszej aplikacji (co więcej, prawdopodobnie byłaby to zwykła strata czasu, a więc i pieniędzy…). Projektowanie zgodnie z regułą otwarte-zamknięte zazwyczaj wymaga wprowadzenia nowych poziomów abstrakcji, co nieuchronnie prowadzi do powiększenia stopnia skomplikowania Pomimo, iż może to pozornie wyglądać na sprzeczność, istnieją techniki programowania zorientowanego obiektowo pozwalające na rozbudowę funkcjonalności kodu bez konieczności jego bezpośredniej modyfikacji. Wybierając obszary kodu aplikacji, które powinny zostać rozbudowane, powinieneś zachować umiar i zdrowy rozsądek; postępowanie zgodnie z regułą otwarte-zamknięte WSZĘDZIE jest niepotrzebną stratą czasu, zasobów, zazwyczaj też pieniędzy, a poza tym może prowadzić do powstania bardzo skomplikowanego i trudnego do zrozumienia kodu programu. jesteś tutaj 117 Spotkanie z wzorcem Dekorator Spotkanie z wzorcem Dekorator OK, mam dość tego klubu „Miłośników projektowania zorientowanego obiektowo”. Mamy tutaj poważny, rzeczywisty problem! Pamiętacie o nas? „Star Cafè”? Czy Wy naprawdę sądzicie, że któraś z tych Waszych reguł projektowania może nam w czymś pomóc? Jak się niedawno przekonaliśmy, próba odwzorowania systemu zamówień napojów wraz z różnymi dodatkami przy użyciu mechanizmów dziedziczenia nie dała zbyt dobrych rezultatów — występowała „eksplozja klas”, otrzymywaliśmy sztywny projekt, efektem były też próby rozbudowy klasy bazowej mechanizmami nieodpowiednimi dla niektórych klas podrzędnych. Zamiast tego w chwili obecnej zrobimy coś zupełnie innego: rozpoczniemy od przygotowania napoju podstawowego. Dodatkami „udekorujemy” go dopiero podczas działania programu. Przykładowo, jeżeli klient zażyczy sobie czarną, mocno paloną kawę z czekoladą i bitą śmietaną, będziemy postępować następująco: 1 Weź obiekt MocnoPalona. 2 „Udekoruj” go obiektem Czekolada. 3 „Udekoruj” go obiektem „BitaŚmietana”. 4 Wywołaj metodę koszt() i przy użyciu mechanizmu delegacji dodaj koszty dodatków. No dobrze, ale w jaki sposób mogę „dekorować” poszczególne obiekty i w jaki sposób zastosować tutaj delegację? Zobaczmy zatem, jak to działa. 118 Rozdział 3 Konstruowanie zamówienia przy użyciu Dekoratorów Wzorzec Dekorator 1 Rozpoczynamy od naszego obiektu MocnoPalona. koszt() MocnoP alona t M o c n o P a l o n a P a m i ę t a j, ż e o b i e k d z i e d z i c z y z a c h o w a n i a z k l a s y N a p ó j i a d a z a i m p l e m e n t o w a n ą m e t o d ę k o s z t p o s i t ó r a w y li c z a k o s z t k n a p o j u . ), ( 2 Klient zażyczył sobie czekolady, więc tworzymy obiekt Czekolada i „zawijamy” go dookoła obiektu MocnoPalona. koszt() koszt() MocnoP alona Czekolad a i j e s t d e k o r a t o r em . J e g o t y p O b i e k t C z e k o l a d a o d zw i e r c i e d l a t y p o b i e k t u d e k o r ow a n e g o, c z y l ( p r z e z w n a s z ym p r z y p a d k u o b i e k t u k l a s y N a p ó j , ż e p o p r o s t u s ł ow o „ o d zw i e r c i e d l a ” r o z um i em y t u t a j j e s t t e g o s am e g o t y p u… ) . C z e k o l a d a r ó w n i e ż p o s i a d a s w o j ą m e t o d ę i m o r f i z m u m o ż e m y d o k t ó r e g o d o d a m y C z e k o l a d ę, d z i ę k i j e s t p o d t y p e m w ł a s n o ś c i o m p o l ( p o n i e w a ż C z e k o l a d a , J a k w i d a ć, i k o s z t ( ) t r a k t o w a ć k a ż d y n a p ó j j a k o k o l e j n y n a p ó j k l a s y N a p o j e ) . 3 Klient życzy sobie również bitej śmietany, więc tworzymy oczywiście dekorator BitaŚmietana i „zawijamy” go dookoła obiektu Czekolada. koszt() MocnoP alona koszt() koszt() BitaŚmietan a Mocha BitaŚmietana jest dekoratorem, więc również odzwierciedla typ obiektu MocnoPalona i posiada zaimplementowaną metodę kosz(). Czyli obiekt MocnoPalona „zawinięty” w obiekty Czekolada i BitaŚmietana jest nadal napojem (obiektem klasy Napoje), więc możemy z nim zrobić dokładnie to samo, co z „czystym” obiektem MocnoPalona, włączając w to wywoływanie jego metody koszt(). jesteś tutaj 119 Charakterystyki dekoratora 4 A teraz nadszedł wreszcie czas na obliczenie kwoty, jaką powinien zapłacić klient za swoje zamówienie. Dokonamy tego poprzez wywołanie metody koszt() najbardziej zewnętrznego dekoratora, BitaŚmietana, który z kolei będzie delegował obliczanie kosztów do obiektów, które dekoruje. Po uzyskaniu wyników ich obliczeń dekorator ten dodaje swój koszt (bitej śmietany) i dzięki temu otrzymujemy całkowity koszt napoju. 2 Dekorator BitaŚmietana wywołuje metodę koszt() dekoratora Czekolada. 1 Po pierwsze, wywołujemy metodę koszt() najbardziej zewnętrznego dekoratora, jakim jest BitaŚmietana. j a k o n t o r o b i l k a s t r o n d a l e j ) . ( O t y m, d o w i e s z s i ę k i , 3 Czekolada wywołuje metodę koszt() obiektu MocnoPalona. 1.29zł 0,10 zł koszt() 0,20 zł koszt() koszt() P alona 0,99 zł Mocno Czekolad a BitaŚmieta n a 4 Obiekt MocnoPalona zwraca swój koszt, czyli 99 groszy. 6 Dekorator BitaŚmietana dodaje swój koszt, czyli 10 groszy, do wyniku uzyskanego od dekoratora Czekolada i zwraca całkowity koszt napoju — 1,29 zł. 5 Dekorator Czekolada dodaje swój koszt, czyli 20 groszy, do wyniku, jaki uzyskał od obiektu MocnoPalona, a następnie zwraca całą sumę, czyli 1,19 zł. Podsumujmy zatem, czego dowiedzieliśmy się do tej pory…  Obiekty dekorujące są tego samego typu, co obiekty dekorowane.  Jeden obiekt podstawowy może zostać „zawinięty” zarówno w jeden, jak i w większą ilość dekoratorów.  Przy założeniu, że dekorator jest tego samego typu, co obiekt dekorowany, możemy przekazywać obiekt „owinięty” dekoratorem zamiast obiektu oryginalnego.  Dekorator dodaje swoje własne zachowania przed delegowaniem do obiektu dekorowanego właściwego zadania i (lub) po nim.  Obiekty mogą być dekorowane w dowolnym momencie, czyli możemy je również dekorować dynamicznie w czasie działania programu, używając do tego takiej liczby dekoratorów, jaka nam będzie potrzebna. A teraz zobaczymy, jak to naprawdę działa — przyjrzymy się definicji wzorca Dekorator, a także napiszemy nieco kodu. 120 Rozdział 3 g a z o w e z c K l u a d n i e n i e ! Wzorzec Dekorator Definicja wzorca Dekorator Przede wszystkim przyjrzyjmy się definicji wzorca Dekorator: Wzorzec Dekorator pozwala na dynamiczne przydzielanie danemu obiektowi nowych zachowań. Dekoratory dają elastyczność podobną do tej, jaką daje dziedziczenie, oferując jednak w zamian znacznie rozszerzoną funkcjonalność. Powyższa definicja opisuje nam jedynie przeznaczenie wzorca Dekorator, ale nie daje nam niemal żadnych wskazówek, w jaki sposób moglibyśmy zaimplementować ten wzorzec w naszej aplikacji. Rzućmy okiem na diagram klas, który nieco rozjaśni nam całą sytuację (na następnej stronie zobaczymy tę samą strukturę, wykorzystaną do rozwi
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Head First Design Patterns. Edycja polska (Rusz głową!)
Autor:
, , ,

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: