Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00443 007909 11010139 na godz. na dobę w sumie
UML. Inżynieria oprogramowania. Wydanie II - książka
UML. Inżynieria oprogramowania. Wydanie II - książka
Autor: Liczba stron: 304
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-0805-8 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> uml - programowanie
Porównaj ceny (książka, ebook, audiobook).

Praktyczny podręcznik do nauki języka UML

W świecie informatyki dobry projekt to często więcej niż połowa sukcesu, a wraz ze wzrostem popularności obiektowych języków programowania UML -- ujednolicony język modelowania przeznaczony do reprezentacji elementów w analizie obiektowej i programowaniu obiektowym -- stał się podstawowym narzędziem do tworzenia modeli. Dlatego też trudno wyobrazić sobie dobrego informatyka, który nie potrafi przygotować poprawnego projektu w tym języku lub odczytać modelu utworzonego przez kogoś innego.

'UML. Inżynieria oprogramowania. Wydanie II' to przystępny podręcznik dla studentów i informatyków pragnących nie tylko poznać ujednolicony język modelowania, ale przede wszystkim nauczyć się korzystać z niego w kontekście inżynierii oprogramowania. Czytając go, dowiesz się, jak powinien wyglądać dobry system, poznasz składnię i funkcje języka UML, a przedstawione studia przypadku pozwolą Ci zobaczyć, jak używać go do projektowania praktycznych rozwiązań.

Jeśli chcesz tworzyć oprogramowanie najwyższej jakości,
zacznij od dobrego projektu.

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

Darmowy fragment publikacji:

UML. In¿ynieria oprogramowania. Wydanie II Autor: Perdita Stevens T³umaczenie: Ireneusz Jakóbik ISBN: 978-83-246-0805-8 Tytu³ orygina³u: Using UML: Software Engineering with Objects and Components (2nd Edition) Format: B5, stron: 304 Praktyczny podrêcznik do nauki jêzyka UML • Jak zaprojektowaæ dobry system? • Jak poprawnie tworzyæ i odczytywaæ modele? • Jak w praktyce stosowaæ UML i poprawiæ jakoœæ projektowanych produktów? W œwiecie informatyki dobry projekt to czêsto wiêcej ni¿ po³owa sukcesu, a wraz ze wzrostem popularnoœci obiektowych jêzyków programowania UML — ujednolicony jêzyk modelowania przeznaczony do reprezentacji elementów w analizie obiektowej i programowaniu obiektowym — sta³ siê podstawowym narzêdziem do tworzenia modeli. Dlatego te¿ trudno wyobraziæ sobie dobrego informatyka, który nie potrafi przygotowaæ poprawnego projektu w tym jêzyku lub odczytaæ modelu utworzonego przez kogoœ innego. „UML. In¿ynieria oprogramowania. Wydanie II” to przystêpny podrêcznik dla studentów i informatyków pragn¹cych nie tylko poznaæ ujednolicony jêzyk modelowania, ale przede wszystkim nauczyæ siê korzystaæ z niego w kontekœcie in¿ynierii oprogramowania. Czytaj¹c go, dowiesz siê, jak powinien wygl¹daæ dobry system, poznasz sk³adniê i funkcje jêzyka UML, a przedstawione studia przypadku pozwol¹ Ci zobaczyæ, jak u¿ywaæ go do projektowania praktycznych rozwi¹zañ. • Projektowanie systemów bazuj¹cych na komponentach • Wprowadzenie do obiektowoœci • Efektywny proces projektowania • Opracowywanie modeli klas • Przygotowywanie modeli przypadków u¿ycia • Tworzenie diagramów interakcji, stanów i aktywnoœci • Przygotowywanie diagramów struktury i wdro¿eñ • Stosowanie komponentów i wzorców • Dbanie o jakoœæ procesu i produktu • Praktyczne przyk³ady projektowania systemów Jeœli chcesz tworzyæ oprogramowanie najwy¿szej jakoœci, zacznij od dobrego projektu Wydawnictwo Helion ul. Koœciuszki 1c 44-100 Gliwice tel. 032 230 98 63 e-mail: helion@helion.pl X Wstęp ...................................................................................................... 13 Część I Tło koncepcyjne .................................................................. 19 Rozdział I Inżynieria oprogramowania z użyciem komponentów ......................... 21 1.1. Co to jest dobry system? ......................................................................................... 21 1.2. Czy istnieją dobre systemy? ..................................................................................... 22 1.2.1. Problemy… ............................................................................................... 22 1.2.2. …a nawet katastrofalne niepowodzenia .................................................... 24 1.2.3. Obietnice, obietnice .................................................................................. 25 1.3. Jakie są dobre systemy? ............................................................................................ 26 1.3.1. Hermetyzacja: słabe powiązania ................................................................ 27 1.3.2. Abstrakcja: wysoki stopień spójności ......................................................... 30 1.3.3. Architektura i komponenty ........................................................................ 31 1.3.4. Projektowanie oparte na komponentach: modularność ............................ 33 1.4. Jak są zbudowane dobre systemy? ........................................................................... 33 Rozdział 2 Koncepcje obiektów ............................................................................... 35 2.1. Czym jest obiekt? ..................................................................................................... 35 2.1.1. Przykład ..................................................................................................... 37 2.1.2. Komunikaty ................................................................................................ 37 2.1.3. Interfejsy .................................................................................................... 38 2.1.4. Klasy .......................................................................................................... 39 2.2. Jaki to ma związek z celami poprzedniego rozdziału? .............................................. 42 2.2.1. Co wspólnego z komponentami mają obiekty? ......................................... 43 2.3. Dziedziczenie ........................................................................................................... 44 2.4. Polimorfizm i wiązanie dynamiczne ......................................................................... 46 Rozdział 3 Wstępne studium przypadku ................................................................. 49 3.1. Problem ................................................................................................................... 49 3.1.1. Sprecyzowanie wymagań ........................................................................... 49 3.1.2. Model przypadków użycia ......................................................................... 51 3.2. Zakres oraz iteracje ................................................................................................. 53 3.3. Identyfikowanie klas ................................................................................................. 55 3.4. Relacje między klasami ............................................................................................. 57 3.5. System w akcji ......................................................................................................... 60 3.5.1. Zmiany w systemie: diagramy stanów ....................................................... 64 3.5.2. Dalsze prace .............................................................................................. 64 4 UML. Inżynieria oprogramowania Rozdział 4 Proces projektowania ............................................................................. 67 4.1. Definicje terminów .................................................................................................. 67 4.1.1. Modele i języki modelowania .................................................................... 68 4.1.2. Proces i jakość ........................................................................................... 70 4.2. Proces projektowania .............................................................................................. 70 4.2.1. Zunifikowana metodologia? ....................................................................... 72 4.2.2. Procesy stosowane w UML ....................................................................... 73 4.3. System, projekt, model, diagram ............................................................................. 75 4.3.1. Wykorzystanie modeli ............................................................................... 76 Część II UML ..................................................................................... 79 Rozdział 5 Podstawy modeli klas ............................................................................. 81 5.1. Identyfikowanie obiektów i klas ............................................................................... 81 5.1.1. Co sprawia, że model klasy jest dobry? ..................................................... 81 5.1.2. Jak zbudować dobry model klasy ............................................................... 82 5.1.3. Jakim rodzajem rzeczy są klasy? ................................................................. 85 5.1.4. Obiekty ze świata rzeczywistego a ich reprezentacje w systemie ............ 85 5.2. Powiązania ............................................................................................................... 86 5.2.1. Wielokrotności .......................................................................................... 88 5.3. Atrybuty i operacje .................................................................................................. 89 5.3.1. Operacje .................................................................................................... 89 5.3.2. Atrybuty ..................................................................................................... 89 5.4. Generalizacja ............................................................................................................ 90 5.4.1. Korzystanie z języka polskiego w celu sprawdzenia, czy zachodzi generalizacja ...................................................................................................... 93 5.4.2. Implementacja generalizacji: dziedziczenie ................................................ 93 5.5. Model klasy podczas opracowywania ...................................................................... 94 5.6. Karty CRC ............................................................................................................... 95 5.6.1. Tworzenie kart CRC ................................................................................. 95 5.6.2. Używanie kart CRC podczas opracowywania projektu ............................ 96 5.6.3. Przykład karty CRC ................................................................................... 97 5.6.4. Refaktoring ................................................................................................ 98 Rozdział 6 Więcej na temat modeli klas ................................................................ 101 6.1. Więcej na temat powiązań ..................................................................................... 101 6.1.1. Agregacja i kompozycja ........................................................................... 101 6.1.2. Role ......................................................................................................... 103 6.1.3. Możliwości nawigacji ............................................................................... 104 6.1.4. Powiązania kwalifikowane ....................................................................... 105 6.1.5. Powiązania pochodne .............................................................................. 107 6.1.6. Ograniczenia ............................................................................................ 108 6.1.7. Klasy powiązań ........................................................................................ 110 6.2. Więcej na temat klas .............................................................................................. 112 6.2.1. Interfejsy .................................................................................................. 113 6.2.2. Klasy abstrakcyjne .................................................................................... 115 6.3. Klasy sparametryzowane ....................................................................................... 117 6.4. Zależność ............................................................................................................... 118 6.5. Komponenty i pakiety ............................................................................................ 119 6.6. Widoczność i ochrona ........................................................................................... 119 Spis treści 5 Rozdział 7 Najważniejsze informacje na temat modeli przypadków użycia ........ 121 7.1. Szczegóły dotyczące aktorów ................................................................................ 123 7.2. Przypadki użycia w szczegółach ............................................................................. 125 7.3. Granice systemu .................................................................................................... 126 7.4. Używanie przypadków użycia ............................................................................... 127 7.4.1. Przypadki użycia podczas gromadzenia wymagań ................................... 127 7.4.2. Przypadki użycia podczas projektowania ................................................ 128 7.5. Możliwe problemy z przypadkami użycia .............................................................. 130 Rozdział 8 Więcej informacji na temat modeli przypadków użycia ..................... 133 8.1. Relacje między przypadkami użycia ....................................................................... 133 8.1.1. Przypadki użycia do wielokrotnego użycia: include .................... 134 8.1.2. Komponenty i przypadki użycia ............................................................... 136 8.1.3. Rozdzielanie wariantów zachowania: extend ............................. 138 8.2. Generalizacje ......................................................................................................... 139 8.3. Aktorzy i klasy ........................................................................................................ 140 8.3.1. Notacja: aktorzy jako klasy ...................................................................... 141 Rozdział 9 Najważniejsze informacje na temat diagramów interakcji .................. 143 9.1. Współprace ............................................................................................................ 144 9.2. Diagramy komunikacji ........................................................................................... 145 9.3. Diagramy sekwencji ............................................................................................... 147 9.4. Więcej zaawansowanych funkcji ............................................................................ 150 9.4.1. Komunikaty z obiektu do samego siebie ................................................. 150 9.4.2. Zwracane wartości .................................................................................. 151 9.4.3. Tworzenie i usuwanie obiektów ............................................................. 152 9.5. Diagramy interakcji służące innym celom .............................................................. 154 9.5.1. Pokazywanie, jak klasa udostępnia operację ............................................ 154 9.5.2. Opisywanie, jak działa wzorzec projektowy ........................................... 154 9.5.3. Opisywanie, jak można użyć komponentu .............................................. 154 Rozdział 10 Więcej informacji na temat diagramów interakcji ............................... 155 10.1. Więcej niż tylko proste sekwencje komunikatów ................................................ 155 10.1.1. Zachowania warunkowe ....................................................................... 155 10.1.2. Iteracja ................................................................................................... 157 10.2. Współbieżność ..................................................................................................... 158 10.2.1. Modelowanie ścieżek kontroli ............................................................... 159 Rozdział 11 Najważniejsze informacje na temat diagramów stanów i aktywności ......165 11.1. Diagramy stanów ................................................................................................. 166 11.1.1. Niespodziewane komunikaty ................................................................ 167 11.1.2. Poziom abstrakcji ................................................................................... 168 11.1.3. Stany, zmiany stanu i zdarzenia .............................................................. 168 11.1.4. Akcje ...................................................................................................... 169 11.1.5. Dozór .................................................................................................... 171 11.2. Diagramy aktywności ........................................................................................... 174 Rozdział 12 Więcej informacji na temat diagramów stanów ................................... 179 12.1. Inne rodzaje zdarzeń ........................................................................................... 179 12.2. Inne rodzaje akcji ................................................................................................. 180 12.3. Zaglądanie do wnętrza stanów ............................................................................ 181 12.4. Współbieżność w obrębie stanów ....................................................................... 183 6 UML. Inżynieria oprogramowania Rozdział 13 Diagramy architektury i wdrożeń ....................................................... 185 13.1. Diagramy struktury komponentów ..................................................................... 185 13.2. Model wdrożeń ................................................................................................... 187 13.2.1. Warstwa fizyczna ................................................................................... 187 13.2.2. Wdrażanie oprogramowania na sprzęcie ............................................... 187 Rozdział 14 Pakiety i modele ................................................................................... 191 14.1. Pakiety ................................................................................................................. 191 14.1.1. Kontrolowanie przestrzeni nazw ........................................................... 192 14.2. Modele ................................................................................................................. 194 Część III Studia przypadków ........................................................... 197 Rozdział 15 Administrowanie I4 .............................................................................. 199 15.1. Studium przypadku .............................................................................................. 199 15.1.1. Model klas .............................................................................................. 203 15.1.2. Dynamika ............................................................................................... 204 15.1.3. Diagramy stanów ................................................................................... 204 15.1.4. Diagramy aktywności ............................................................................. 204 15.2. Dyskusja ............................................................................................................... 205 Rozdział 16 Gry planszowe ...................................................................................... 207 16.1. Zakres i wstępna analiza ...................................................................................... 208 16.1.1. „Kółko i krzyżyk” ................................................................................... 208 16.1.2. Szachy .................................................................................................... 209 16.2. Interakcja ............................................................................................................. 213 16.3. Z powrotem do szkieletu aplikacji ....................................................................... 215 16.4. Stany .................................................................................................................... 217 Rozdział 17 Symulacja metodą kolejnych zdarzeń ................................................. 219 17.1. Wymagania ........................................................................................................... 219 17.1.1. Bardziej szczegółowy opis ..................................................................... 220 17.2. Zarys modelu klasy .............................................................................................. 222 17.3. Przypadki użycia .................................................................................................. 224 17.3.1. Podsumowanie przypadku użycia tworzenie modelu ............................ 224 17.3.2. Podsumowanie przypadku użycia obserwowanie zachowania .............. 225 17.3.3. Podsumowanie przypadku użycia zbieranie danych statystycznych ...... 225 17.3.4. Podsumowanie przypadku użycia uruchomienie modelu ...................... 225 17.4. Standardowy mechanizm symulacji opartej na procesie ...................................... 226 17.5. Powiązania i możliwości nawigacji ....................................................................... 227 17.6. Klasy w szczegółach ............................................................................................. 230 17.6.1. Klasa Zarzadca ....................................................................................... 230 17.6.2. Klasa JednostkaAktywna ........................................................................ 231 17.6.3. Klasa JednostkaPasywna ........................................................................ 233 17.6.4. Klasa Zasob ............................................................................................ 233 17.7. Klasa Raport ......................................................................................................... 236 17.8. Klasa DaneStatystyczne ....................................................................................... 236 17.8.1. Klasa Srednia .......................................................................................... 236 17.9. Budowanie kompletnego modelu symulacji ......................................................... 237 17.10. Ucztujący filozofowie ......................................................................................... 238 Spis treści 7 Część IV W stronę praktyki ............................................................. 241 Rozdział 18 Wielokrotne używanie: komponenty i wzorce .................................... 243 18.1. Praktyczne informacje na temat wielokrotnego używania ................................... 243 18.1.1. Co może być użyte wielokrotnie i w jaki sposób? ................................. 244 18.1.2. Dlaczego używać powtórnie? ................................................................ 246 18.1.3. Dlaczego używanie wielokrotne jest trudne? ........................................ 247 18.1.4. Które komponenty w naturalny sposób nadają się do powtórnego użycia? ........................................................................ 248 18.1.5. A co z budowaniem własnych komponentów? ...................................... 249 18.1.6. Jaką różnicę sprawia zorientowanie obiektowe? ................................... 250 18.2. Wzorce projektowe ............................................................................................. 251 18.2.1. Przykład: Fasada .................................................................................... 254 18.2.2. Język UML i wzorce .............................................................................. 254 18.3. Szkielety ............................................................................................................... 256 Rozdział 19 Jakość produktu: weryfikowanie, walidacja i testowanie .................... 257 19.1. Omówienie jakości .............................................................................................. 257 19.2. W jaki sposób można osiągnąć wysoką jakość? .................................................... 258 19.2.1. Nastawienie na produkt ........................................................................ 258 19.2.2. Nastawienie na proces .......................................................................... 258 19.2.3. Dalsza lektura ........................................................................................ 259 19.3. Weryfikacja .......................................................................................................... 259 19.4. Walidacja .............................................................................................................. 260 19.4.1. Użyteczność .......................................................................................... 261 19.5. Testowanie .......................................................................................................... 262 19.5.1. Wybieranie i przeprowadzanie testów .................................................. 263 19.5.2. Dodatkowe problemy związane ze zorientowaniem obiektowym ....... 265 19.5.3. Dlaczego testowanie jest często przeprowadzane źle? ......................... 267 19.6. Przeglądy i inspekcje ............................................................................................ 268 19.6.1. Problemy związane z przeglądami FTR ................................................. 269 Rozdział 20 Jakość procesu: zarządzanie, zespoły i kontrola jakości ...................... 271 20.1. Zarządzanie ......................................................................................................... 271 20.1.1. Zarządzanie projektem .......................................................................... 272 20.1.2. Szacowanie projektu iteracyjnego ......................................................... 273 20.1.3. Zarządzanie projektowaniem opartym na komponentach .................... 274 20.1.4. Zarządzanie ludźmi ................................................................................ 275 20.2. Zespoły ................................................................................................................ 276 20.3. Przywództwo ...................................................................................................... 277 20.3.1. Zmiana procesu projektowania ............................................................. 278 20.4. Kontrola jakości ................................................................................................... 279 20.4.1. Kontrola jakości w procesach iteracyjnych ............................................ 281 20.4.2. Kompleksowe zarządzanie jakością ....................................................... 281 20.5. Dalsza lektura ...................................................................................................... 283 Skorowidz ............................................................................................ 289 W tym rozdziale będziemy kontynuować udzielanie odpowiedzi na pytanie „jakie są dobre systemy?”, opisując zorientowany obiektowo paradygmat, który zawdzięcza swoją popular- ność częściowo temu, że wspiera on projektowanie dobrych systemów. Korzystanie jednak ze zorientowania obiektowego nie jest ani niezbędne, ani wystarczające do budowania do- brych systemów. Udzielimy odpowiedzi na następujące pytania: Czym jest obiekt? · W jaki sposób porozumiewają się obiekty? · Jak jest zdefiniowany interfejs obiektu? · Co obiekty mają wspólnego z komponentami? · Pod koniec omówimy dziedziczenie, polimorfizm i wiązanie dynamiczne. Treści zawarte w tym rozdziale odnoszą się do standardowych, nowoczesnych, opartych na klasach, obiektowo zorientowanych języków, takich jak Java, C# i C++. Większość roz- działu można odnieść też do języków Smalltalk, Eiffel, CLOS, Perl5 i innych obiektowo zo- rientowanych języków, z którymi można się spotkać, jednak dokładne ich porównywanie wykracza poza zakres tej książki. W niniejszym rozdziale są zawarte pytania na temat sposobów, w jaki języki programo- wania używane przez Czytelnika udostępniają omawiane obiektowo zorientowane funkcje. Jeśli Czytelnik zna już jakiś język programowania, powinien być w stanie udzielić odpowie- dzi na te pytania. Jeśli nie, warto aby przeczytał ten rozdział do końca, poznał podstawy wy- branego języka, a następnie powrócił do pytań w celu sprawdzenia swojej wiedzy na temat sposobów realizowania przez język zorientowania obiektowego. W pytaniach język progra- mowania używany przez Czytelnika będziemy w skrócie nazywać „Twoim językiem”. 2.1. Czym jest obiekt? Pojęciowo obiekt jest elementem, z którym można wchodzić w interakcje: można wysyłać do niego różne komunikaty, a on będzie reagował. Zachowania obiektu zależą od jego bie- żącego stanu wewnętrznego, który może ulegać zmianie, na przykład na skutek reakcji na 36 Część I ¨ Tło koncepcyjne otrzymany komunikat. Ważne jest, z którym obiektem zachodzi interakcja, i dlatego odnie- sienie do obiektu następuje za pośrednictwem jego nazwy. Obiekt ma zatem swoją tożsa- mość, która odróżnia go od wszystkich innych obiektów. Obiekt jest więc elementem posia- dającym swoje zachowanie, stan i tożsamość; w taki sposób charakteryzuje go Grady Booch [7]. Rozważymy te aspekty bardziej szczegółowo. Przedmiot Pojęcie przedmiotu jest bardziej interesujące, niż może się to początkowo wydawać. Obiekt nie jest tylko elementem systemu; reprezentuje on w systemie koncepcję przedmiotu. Obiekt może być na przykład reprezentacją prawdziwego przedmiotu, takiego jak zegar, tablica rozdzielcza albo klient. W rzeczywistości obiekty pojawiły się jawnie po raz pierwszy w ję- zyku Simula, w którym reprezentowały obiekty z realnego świata — te, które były symulo- wane. Oczywiście, aby systemy programistyczne ogólnego przeznaczenia mogły być two- rzone w oparciu o obiekty, obiekty nie muszą reprezentować fizycznie istniejących rzeczy. Do kwestii sposobu rozpoznawania obiektów powrócimy w rozdziale 5. P: Które z elementów następującej listy mogą być obiektami: młotek, kula, proces chemiczny, miłość, mgła, rzeka, złość, kot, szarość, szary kot? Stan Stan obiektu to wszystkie dane aktualnie w nim zapisane. Zwykle obiekt ma wiele nazwa- nych atrybutów (zmiennych obiektu, danych składowych), z których każdy ma określoną wartość. Niektóre z atrybutów mogą podlegać zmianom, to znaczy ich wartości mogą się zmie- niać. Obiekt reprezentujący na przykład klienta może mieć atrybut o nazwie adres, którego wartość ulegnie modyfikacji po przeprowadzce klienta. Inne atrybuty mogą być niezmienne, czyli stałe. Obiekt reprezentujący klienta może mieć atrybut, którego wartością będzie numer identyfikacyjny klienta, pozostający bez zmian przez cały czas trwania życia obiektu. W większo- ści współczesnych obiektowo zorientowanych języków programowania zestaw atrybutów przypisanych obiektowi nie może ulec zmianie podczas trwania życia tego obiektu, chociaż wartości atrybutów mogą się zmieniać. Zachowanie Zachowanie oznacza sposób, w jaki obiekt działa i reaguje w sensie zmian swojego stanu i przekazywania komunikatów. Obiekt rozumie niektóre komunikaty, co znaczy, że może je odbierać i zgodnie z nimi postępować. Zestaw komunikatów rozumianych przez obiekt, po- dobnie jak i zestaw atrybutów, jest zwykle stały. Sposób, w jaki obiekt reaguje na komunikat, może zależeć od aktualnych wartości jego atrybutów. Dzięki temu, nawet jeśli świat zewnętrzny nie ma zagwarantowanego bezpośredniego dostępu do atrybutów (a zazwyczaj właśnie tak jest), może pośrednio wpływać na ich wartości. W taki sposób wartości atrybutów decydują o stanie obiektu. Rozdział 2. ¨ Koncepcje obiektów 37 Tożsamość To zagadnienie może być trochę trudne. Idea jest taka, że obiekty są definiowane nie tylko przez bieżące wartości swoich atrybutów. Istnienie obiektu jest ciągłe. Wartości atrybutów mogą na przykład ulec zmianie, zwykle w odpowiedzi na komunikat, ale to będzie ciągle ten sam obiekt. Odniesienie do obiektu następuje zazwyczaj przez jego nazwę (wartość zmien- nej w programie-kliencie, na przykład Klient), ale nazwa obiektu to nie to samo, co sam obiekt, ponieważ obiektowi można nadać kilka różnych nazw (co może być zaskakujące dla programistów funkcyjnych, a niektórzy z nich twierdzą, że zorientowanie obiektowe można zrealizować w czysto funkcyjny sposób; jednak tego zagadnienia nie będziemy poruszać w niniejszej książce). 2.1.1. Przykład Rozważmy obiekt o nazwie mojZegar, który rozumie komunikaty podajCzas i ustawCzasNa(07:43), i w ogólności ustawCzasNa(nowyCzas) dla sensownych wartości parametru nowyCzas. Można to zrealizować, tworząc interfejs, który ogłosi, że przyjmuje komunikaty w postaci podajCzas i ustawCzasNa(nowyCzas: Czas), gdzie Czas jest typem1, którego elementy są sensownymi wartościami wspomnianego parametru nowyCzas. W jaki sposób zaimplementować taką funkcję? Świat zewnętrzny nie musi tego wiedzieć (informacja powinna być ukryta), ale być może obiekt ma atrybut Czas, którego wartość zwraca w odpowiedzi na komunikat podajCzas i który jest ustawiany na wartość nowyCzas po otrzymaniu przez obiekt komunikatu ustawCzasNa(nowyCzas). Jest też możliwe, że komuni- kat jest przekazywany do innego obiektu, znanego obiektowi mójZegar, i że to właśnie ten inny obiekt pracuje z komunikatami. 2.1.2. Komunikaty Z poprzedniego przykładu można wysnuć kilka wniosków na temat komunikatów. W skład komunikatu wchodzi słowo kluczowe nazywane selektorem. W przykładzie selektorami są podajCzas i ustawCzasNa. Komunikat może, ale nie musi, zawierać jeden lub więcej argu- mentów, które są wartościami przekazywanymi obiektowi, podobnie jak są przekazywane wartości w przypadku wywoływania funkcji. W powyższym przykładzie 07:43 jest argu- mentem, stanowiącym część komunikatu ustawCzasNa(07:43). Zazwyczaj dla danego selektora istnieje pojedyncza „prawidłowa” liczba argumentów, które powinny znajdować się w ko- munikacie rozpoczynającym się tym od tego selektora. Nie można oczekiwać, że obiekt mojZegar zrozumie komunikat ustawCzasNa bez żadnego argumentu lub w postaci ustawCzasNa(4, 12:30) i tak dalej. Akceptowalne wartości argumentów również są ustalane w interfejsie obiektu2. 1 Albo klasą; klasy omówimy w podrozdziale 2.1.4. 2 Podając klasę (patrz podrozdział 2.1.4) lub niekiedy tylko interfejs, do których powinien należeć obiekt przekazywany jako argument, lub jego typ, jeśli należy do typu podstawowego, takiego jak int albo bool — szczegóły zależą od konkretnego języka. 38 Część I ¨ Tło koncepcyjne P: Jaka jest składnia przesyłania komunikatów w Twoim języku? Warto zauważyć, że wartości, na przykład wartości atrybutów obiektu albo wartości ar- gumentów przesyłane w komunikatach, nie muszą należeć do typu podstawowego (takiego jak znaki, liczby całkowite i tak dalej. Rodzaje typów podstawowych zależą od konkretnego języka). Mogą to być również obiekty. P: Jakie są podstawowe typy w Twoim języku? Jedną z czynności, którą może wykonać obiekt w odpowiedzi na komunikat, jest wysła- nie komunikatu do innego obiektu. Jeśli tak ma się stać, to powinien on w jakiś sposób po- znać nazwę tego obiektu. Prawdopodobnie wartością jednego z jego atrybutów mógłby być na przykład obiekt, którego nazwa byłaby wykorzystywana podczas wysyłania komunikatu. P: Niech o będzie obiektem. Do jakich innych obiektów może wysyłać komunikaty obiekt o, oprócz obiektów, dla których może być wartością ich atrybutów? Warto zwrócić uwagę na to, że podczas wysyłania komunikatu do obiektu nie wiadomo, jaki kod zostanie w wyniku wykonany, gdyż informacja o tym jest hermetyzowana. Będzie to istotne pod koniec niniejszego rozdziału, kiedy omówimy wiązanie dynamiczne. 2.1.3. Interfejsy Publiczny interfejs definiuje komunikaty, które będą przyjmowanie przez obiekt niezależnie od miejsca ich pochodzenia. Zazwyczaj interfejs zapisuje selektory tych komunikatów, łącznie z niektórymi informacjami na temat wymaganych argumentów oraz wartości, która ewentu- alnie mogłaby być zwrócona. Jak wspomnieliśmy w rozdziale 1., korzystne byłoby, gdyby interfejs zawierał jakiś rodzaj specyfikacji dotyczącej skutków wysłania komunikatu do obiektu. Informacje tego typu są jednak podawane jedynie w komentarzach i dokumentacji. W więk- szości języków programowania atrybuty mogą być zawarte również w publicznym interfejsie obiektu. Umieszczenie atrybutu x w interfejsie jest równoważne z zadeklarowaniem, że fragment danych tego obiektu, x, może być widziany i zmieniany z zewnątrz. Zagadnienie do przedyskutowania 9 Jeśli korzystasz z języka, który nie zezwala na umieszczanie atrybutów w interfejsie publicz- nym, to w jaki sposób możesz osiągnąć taki sam efekt, używając komunikatów w celu uzyska- nia dostępu do danych? Czy są jakieś zalety stosowania takiego rozwiązania nawet w językach, które dopuszczają używanie atrybutów w interfejsie? A wady? Często jest tak, że nie każdy element systemu powinien mieć możliwość wysyłania do obiektu wszystkich komunikatów, które dany obiekt mógłby zrozumieć. Dlatego też obiekt może zwykle zrozumieć pewne komunikaty, które nie są częścią jego publicznego interfejsu. Jak już na przykład wyjaśniliśmy w rozdziale 1., struktura danych używana przez moduł po- winna być hermetyzowana, co jest zgodne z założeniem, że interfejs publiczny obiektu nie powinien zazwyczaj zawierać atrybutów. Obiekt zawsze może wysłać sam do siebie komunikat, który będzie w stanie zrozumieć. Wysyłanie komunikatów samemu sobie może wydawać się dziwne lub zbyt skomplikowane, Rozdział 2. ¨ Koncepcje obiektów 39 jednak powód takiego postępowanie wyjaśnimy w dalszej części niniejszego rozdziału przy okazji omawiania wiązania dynamicznego. Zazwyczaj obiekt ma przynajmniej dwa interfejsy: publiczny, z którego może korzystać dowolny element systemu, oraz obszerniejszy interfejs prywatny, z którego może korzystać zarówno sam obiekt, jak i inne uprzywilejowane elementy systemu. Czasami może być jesz- cze przydatny interfejs pośredni, udostępniający więcej możliwości niż interfejs publiczny, ale mniej niż interfejs prywatny. Czasami w danym kontekście jest potrzebna tylko część publicznego interfejsu obiektu, co powoduje wzrost liczby obiektów, które potencjalnie mo- głyby być używane zastępczo. Może być zatem przydatne zapisywanie naprawdę potrzeb- nych funkcji w mniejszym interfejsie, zamiast umieszczania ich w całym interfejsie publicz- nym obiektu. Z tego względu obiekt może mieć (lub realizować) więcej niż tylko jeden interfejs. I odwrotnie — wiele różnych obiektów może realizować taki sam interfejs. W tej książce określenie „interfejs” zawsze będzie oznaczać interfejs publiczny. Jeśli bę- dzie inaczej, zostanie to wyraźnie określone. 2.1.4. Klasy Do tej pory omawialiśmy obiekty, jak gdyby każdy z nich był osobno definiowany, każdy miał swój własny interfejs i sposób sprawdzania, który inny obiekt może wysyłać do niego komu- nikaty. Oczywiście taki sposób tworzenia typowego systemu nie jest rozsądny, ponieważ obiekty mają ze sobą wiele wspólnego. Jeśli przedsiębiorstwo ma 10 000 klientów i potrzeb- ne jest zbudowanie systemu z obiektami reprezentującymi każdą z tych osób, to wszystkie obiekty reprezentujące klientów będą posiadały wiele wspólnych cech. Ich zachowania po- winny być spójne, aby programiści i osoby opiekujące się systemem mogły je zrozumieć. Potrzebna będzie klasa obiektów reprezentująca klientów. Klasa opisuje zestaw obiektów pełniących w systemie takie same funkcje. W opartych na klasach, zorientowanych obiektowo językach programowania każdy obiekt należy do klasy, a klasa obiektu determinuje jego interfejs3. Obiekt mojZegar może należeć do klasy Zegar, której interfejs publiczny określa, że każdy obiekt klasy Zegar będzie udostępniał operację ustawCzasNa(nowyCzas: Czas). Znaczy to, że będzie rozumiał komunikaty z selekto- rem ustawCzasNa i pojedynczym argumentem, który jest obiektem klasy (typu) Czas. W rzeczywistości nawet sposób, w jaki obiekt reaguje na komunikaty, jest zdeterminowany przez jego klasę, łącznie z wartościami atrybutów obiektu. Metoda jest określonym frag- mentem kodu, w którym są zaimplementowane operacje. W interfejsie obiektu widoczne jest jedynie to, że obiekt wykonuje operację; metoda, w której jest zaimplementowana funk- cja, jest ukryta. Podobnie zestaw atrybutów posiadanych przez obiekt jest zdeterminowany przez klasę, chociaż oczywiście wartości przyjmowane przez atrybuty obiektu nie są określone w klasie i mogą ulegać zmianom. Być może na przykład obiekty należące do klasy Zegar mają pry- watny atrybut o nazwie czas. Jeśli taki sam komunikat zostanie wysłany do dwóch obiektów tej samej klasy, w obu przypadkach zostanie wykonana ta sama metoda, chociaż efekt jej wykonania może być znacząco różny, gdy atrybuty obiektów będą mieć inne wartości. 3 W rzeczywistości obiekt może należeć do więcej niż jednej klasy, z których klasa najbardziej szczególna decyduje o jego interfejsie. 40 Część I ¨ Tło koncepcyjne Podsumowując, obiekty tej samej klasy mają takie same interfejsy. Publiczne i prywatne interfejsy klasy Zegar mogłyby być opisane następująco: - czas : Czas + podajCzas() : Czas + ustawCzasNa (nowyCzas: Czas) W skład interfejsu publicznego wchodzą wiersze oznaczone znakiem +, a w skład inter- fejsu prywatnego także wiersz ze znakiem –. P: W jaki sposób definiuje się klasę, taką jak Zegar w Twoim języku? Czy interfejs i implementacja są definiowane oddzielnie? Jak jest nazywany interfejs publiczny, a jak prywatny (może właśnie: pu- bliczny i prywatny)? Czy są może jeszcze jakieś inne możliwości? Co one oznaczają? Proces tworzenia nowego obiektu należącego do klasy Zegar jest nazywany tworzeniem egzemplarza klasy Zegar, a powstały w wyniku obiekt egzemplarzem klasy Zegar. To właśnie dlatego zmienne, których wartości należą do obiektu i które mogą ulegać zmianie w czasie życia obiektu, są nazywane zmiennymi egzemplarza. Utworzenie obiektu oznacza utworze- nie nowego egzemplarza klasy posiadającego własny stan i tożsamość, które będą pozosta- wać spójne w obrębie wszystkich obiektów klasy. Proces tworzenia zazwyczaj obejmuje także nadanie wartości atrybutom. Wartości mogą zostać określone w zleceniu utworzenia lub na- dane przez klasę obiektu jako domyślne wartości początkowe. W językach takich jak C++ i Java klasa odgrywa bezpośrednią rolę podczas tworzenia nowych obiektów — w rzeczy- wistości wykonuje całą pracę, nie ograniczając się jedynie do roli szablonu. Dlatego klasa może być często uważana za fabrykę obiektów. P: W jaki sposób jest tworzony w Twoim języku nowy obiekt danej klasy? W wielu językach klasy mogą zachowywać się, jak gdyby same były obiektami. Klasa Klient mogłaby mieć atrybut liczbaEgzemplarzy, który byłby liczbą całkowitą zwiększaną za każdym razem, gdy tworzony jest nowy obiekt typu Klient. Takie rozwiązanie konsekwentnie przyjęto w języku Smalltalk, a w językach C++ i Java można odnaleźć jego ślady. W Smalltalk na przykład nowy obiekt typu Klient zostałby utworzony przez wysłanie komunikatu (przy- kładowo new) do klasy Klient. Reakcją klasy byłoby utworzenie nowego obiektu i zwrócenie go do metody wywołującej. Zagadnienie do przedyskutowania 10 Zastanów się, co by było, gdyby konsekwentnie stosować takie rozwiązanie. Stwierdziliśmy już, że każdy obiekt ma swoją klasę. Jeśli więc klasa k zostanie uznana za obiekt, to co będzie klasą dla k? I co będzie klasą tej klasy? P: Czy Twój język posiada takie funkcje? Jakie dokładnie? Dygresja: po co istnieją klasy? Dlaczego nie wystarczą obiekty, które posiadają wymagany stan, zachowanie i tożsamość? Klasy w zorientowanych obiektowo językach programowania służą dwóm celom. Po pierw- sze, są wygodnym sposobem na opisanie zbioru (klasy) obiektów posiadających takie same właściwości. W językach zorientowanych obiektowo klasy są używane przede wszystkim dla Rozdział 2. ¨ Koncepcje obiektów 41 wygody. Nie ma na przykład potrzeby przechowywania kopii kodu opisującego zachowania obiektu w każdym obiekcie, chociaż można wyobrażać sobie, że w każdym obiekcie znajduje się jego kod. Zamiast tego programista może jednorazowo napisać definicję klasy, a kompi- lator utworzy pojedynczą reprezentację klasy i pozwoli obiektom na uzyskiwanie dostępu do reprezentacji klasy w celu pobierania potrzebnego kodu. Należy pamiętać, że taka wygoda wcale nie jest czymś błahym. Zasadniczym celem jest przecież uczynienie systemów łatwiejszymi do zrozumienia, aby ich projektowanie i pielę- gnacja były jak najbardziej tanie, łatwe i niezawodne. Sprawienie, że podobne obiekty dzielą ten sam projekt oraz implementację, jest ważnym krokiem w tym kierunku. W taki sposób przejawia się zasada4, która jest tak ważna w inżynierii oprogramowania — nie tylko w odniesieniu do kodu — że ją wykrzyczymy: PISZ TYLKO RAZ! Oznacza to, że jeśli dwie kopie jakiegoś produktu inżynierii oprogramowania, na przy- kład fragment kodu, fragment diagramu czy fragment tekstu pochodzący z dokumentu, po- winny być spójne, to nie powinny istnieć w dwóch egzemplarzach. Za każdym razem, gdy ta sama informacja jest zapisywana w więcej niż jednym miejscu, nie tylko marnuje się wysiłek na powtórne robienie tego samego, zamiast zrobienia czegoś nowego, ale też naraża się na kłopoty związane z pielęgnacją, ponieważ dwie wersje nigdy nie będą zsynchronizowane bez żadnych starań. Sztuka stosowania tej zasady polega na stwierdzeniu, czy dwie kopie infor- macji są rzeczywiście takie same, czy też zdarzyło się, że potencjalnie różne informacje są akurat w danym momencie identyczne. W tym drugim przypadku skopiowanie i wklejenie odpowiedniego fragmentu jest jak najbardziej prawidłowe. W pierwszym przypadku niechęć do powielania informacji w więcej niż jednym miejscu jest zaletą. Należy tak postąpić wy- łącznie wtedy, gdy istnieją ku temu dobre powody. Zagadnienie do przedyskutowania 11 Czy ta zasada oznacza, że powielanie danych w rozproszonych bazach danych jest złym pomy- słem? Dlaczego? Zauważmy, że istnieją inne sposoby na tworzenie wielu podobnych obiektów, pisząc ich kod tylko raz. Można na przykład zdefiniować prototyp obiektu, a następnie definiować ko- lejne obiekty jako będące „takie jak tamten, ale z następującymi różnicami”. W takim przy- padku również wystarczyłoby przechowywanie tylko jednej kopii kodu. Mniej więcej w taki sposób postępuje się, programując w eleganckim, opartym na prototypach, języku Self. Ję- zyki programowania oparte na klasach zdominowały jednak obecnie zorientowanie obiekto- we i zapewne tak już pozostanie. Po drugie, w większości zorientowanych obiektowo językach programowania klasy są używane w taki sam sposób, jak w wielu innych językach są wykorzystywane typy — w celu określenia, jakie wartości są dopuszczalne w określonych kontekstach, umożliwiając tym samym kompilatorowi (oraz, co jest równie ważne, osobie czytającej kod) zrozumienie in- tencji programisty i sprawdzenie, czy pewne rodzaje błędów nie wystąpią w programie. 4 Na którą kładzie nacisk zwłaszcza Kent Beck. 42 Część I ¨ Tło koncepcyjne Wiele osób uważa, że klasy i typy oznaczają tę samą rzecz. Rzeczywiście, jest to wygod- ne i często nie prowadzi do żadnych nieporozumień, niemniej taki sposób myślenia jest błędny. Należy pamiętać, że klasa definiuje nie tylko to, jakie komunikaty zrozumie obiekt, co tak naprawdę wystarcza, aby sprawdzać, czy jest on akceptowalny w danym kontekście. Określa również czynności obiektu wykonywane w odpowiedzi na komunikaty. 2.2. Jaki to ma związek z celami poprzedniego rozdziału? Szukamy modułów, najlepiej nadających się do wielokrotnego używania wymiennych mo- dułów, które mogłyby być dobrymi komponentami. Gdzie można je znaleźć w systemie obiektowo zorientowanym? Poszczególne obiekty mogłyby być uważane za moduły, ale nie byłyby one dobre. W syste- mie znajduje się bowiem zazwyczaj wiele różnych modułów, które są blisko spokrewnione pojęciowo. Gdyby każdy obiekt był uważany za odrębny moduł, to albo istniałyby wprowa- dzające w błąd nieścisłości między pojęciowo powiązanymi modułami, albo potrzeba za- chowania spójności powodowałaby tworzenie silnych skojarzeń. Klasy powinny być słabo skojarzonymi, wysoce spójnymi modułami. Można zatem mieć nadzieję (być może na próżno, co przedyskutujemy w następnym podrozdziale), że będzie realne uzyskanie korzyści przedstawionych w rozdziale 1., a mianowicie niskiego kosztu i krótkiego czasu opracowywania, łatwości pielęgnacji i wysokiej niezawodności. Zalety te nie są cechą charakterystyczną zorientowania obiektowego, chociaż jest ono obecnie najle- piej poznaną ścieżką do nich prowadzącą. Kolejna uznana zaleta zorientowania obiektowego należy do innej kategorii. Naturalne jest postrzeganie otaczającego świata w kategoriach obiektów. Warto przypomnieć sobie, że głównym wymogiem stawianym przed dobrym systemem jest spełnianie oczekiwań użyt- kowników i że prawidłowe uchwycenie tych oczekiwań oraz śledzenie ich zmian należą do najtrudniejszych zadań związanych z tworzeniem systemów. Ważne jest, aby model systemu (model domeny problemu i zachodzących procesów) był zgodny z modelem użytkownika. Wydaje się, że obiekty z domeny problemu rzadziej ulegają zmianom, a same zmiany są mniej dramatyczne, niż jest to w przypadku działania systemu wymaganego przez użytkow- nika. Jeśli zatem system jest zbudowany w oparciu o te obiekty, to zmiany w systemie praw- dopodobnie będą mniej rewolucyjne, niż gdyby system powstał w oparciu o bardziej ulotne aspekty funkcjonalne. Podsumowując, należy mieć nadzieję, że system będzie zgodny z mo- delem świata użytkownika, dzięki czemu będzie możliwe: łatwiejsze i dokładniejsze uchwycenie wymagań; · lepsze nadążanie za zmianami wymagań użytkownika; · · tworzenie systemów, które prowadzą interakcje w bardziej naturalny sposób. Łatwiejsze jest zaimplementowanie na przykład interfejsu użytkownika, który pozwala użytkowni- kowi na interakcję z plikiem, zegarem albo drukarką jako całością (co ma sens z punktu widzenia użytkownika, ponieważ te przedmioty są podobne do obiektów z rzeczywistego świata), jeśli są one spójnymi obiektami także z punktu widzenia systemu. Z tego powo- du interfejsy użytkownika były jednymi z pierwszych głównych obszarów, w których zo- rientowanie obiektowe stało się popularne. Rozdział 2. ¨ Koncepcje obiektów 43 Należy jednak zaznaczyć, że te argumenty nie są bezdyskusyjne. W niektórych przypad- kach, takich jak na przykład systemy obsługi zamówień, podejście zorientowane obiektowo wydaje się bardzo naturalne, w innych (na przykład kompilatory) taka argumentacja jest mniej przekonująca. W każdym jednak przypadku gdy zorientowanie obiektowe osiąga swój cel, zwykle nie jest tak z powodu charakterystycznych cech zorientowania obiektowego. Jest tak, ponieważ: podstawami zorientowania obiektowego są modularność, hermetyzacja i abstrakcja, · · zorientowane obiektowo języki programowania sprawiają, że osiąganie celów staje się względnie proste, ponieważ istnieje uzasadnione prawdopodobieństwo, że oczywisty sposób zrobienia czegoś jest również dobrym sposobem na zrobienie tego. Zorientowanie obiektowe jest religią: to ludzie zostają zorientowani w stronę obiektów. Zagadnienie do przedyskutowania 12 Istnienie jakich konsekwencji, dobrych i złych, może sugerować stwierdzenie, że „zorientowanie obiektowe jest religią”? 2.2.1. Co wspólnego z komponentami mają obiekty? Euforia towarzysząca zorientowaniu obiektowemu mogłaby czasami sugerować, że każda klasa jest automatycznie komponentem, nadającym się do wielokrotnego używania. Oczywi- ście nie jest to prawdą. W rozdziale 1. omówiliśmy powody, dla których możliwość wielo- krotnego używania komponentu nie jest po prostu faktem o komponencie jako takim, ale zależy od kontekstu projektu i proponowanego sposobu jego powtórnego użycia. Innym ważnym czynnikiem jest to, że struktura klasy może być zbyt szczegółowa, aby mogła być efektywnie wielokrotnie wykorzystywana. Aby na przykład można było wielokrotnie korzystać z poje- dynczej klasy w sposób praktyczny i łatwy, należałoby pisać programy w tym samym języku i sięgać do zgodnej architektury. Nie zawsze jest to niewykonalne. Istnieją powszechnie używa- ne biblioteki klas, które odniosły sukces, i ich biblioteki mogą być uważane za komponenty do wielokrotnego używania. Często jednak określenie komponentu odnosi się do grupy po- wiązanych klas. Im więcej wysiłku włoży się w dostosowanie komponentu do kontekstu, tym więcej korzyści powinien przynieść dany komponent, jeśli ten wysiłek ma być opłacalny. Celowo rozmyliśmy kwestię tego, czy komponenty są zbudowane z obiektów, czy z klas; nie dokonaliśmy jeszcze wyraźnego rozróżnienia między typem a egzemplarzem. Powód jest taki, że wziąwszy pod uwagę szeroką definicję komponentu, oba te przypadki mogą być prawdziwe. Klasa albo zbiór klas może być komponentem na poziomie kodu źródłowego. Kontekst, w którym jest używany komponent, korzysta z udogodnień danego języka w celu tworzenia obiektów klasy. W innych przypadkach komponent może realizować dostęp do określonego, gotowego obiektu jakiejś klasy, realizując również dostęp do funkcji związa- nych z tworzeniem kolejnych obiektów tej klasy. Należy pamiętać, że sam komponent ma dobrze zdefiniowany interfejs. Jeśli komponent składa się z obiektów i (lub) klas, to interfejs komponentu zwykle nie pozwala na dostęp do wszystkiego, co znajduje się w interfejsach obiektu i wewnątrz klas. Komponent sam stara się być hermetyzowaną abstrakcją i prawdo- podobnie jest właściwe, że ukrywa część lub całość swojej wewnętrznej struktury — na przykład czy i jak składa się z obiektów i klas. 44 Część I ¨ Tło koncepcyjne Zagadnienie do przedyskutowania 13 Skorzystaj z sieci Web i innych dostępnych zasobów w celu odszukania popularnych kompo- nentów architektury, takich jak JavaBeans, CORBA albo .NET. Co to jest architektura? Jaką wewnętrzną strukturę może mieć komponent i jak jest zdefiniowany interfejs komponentu? 2.3. Dziedziczenie Do tej pory omówiliśmy jedynie pojęciowe podstawy tego, co czasami jest nazywane pro- jektem opartym na obiektach. W tym podrozdziale weźmiemy pod uwagę dziedziczenie, które będąc pojęciowym elementem leżącym u podstaw obiektowo zorientowanego pro- jektu, jest niczym lukier dla pączka. Jak wskazuje metafora, pojęcie to jest uważane za atrak- cyjne i ważne, ale tak naprawdę jest mniej treściwe niż to, co do tej pory opisaliśmy w książce. W niniejszym podrozdziale rozpatrzymy dziedziczenie jako techniczną właściwość języ- ków zorientowanych obiektowo, użyteczną (w ograniczonym zakresie) podczas niskopozio- mowego wielokrotnego wykorzystywania. W rozdziale 5. omówimy korzystanie z dziedzi- czenia w modelowaniu. Poniższy przykład został zaczerpnięty ze studium przypadku z rozdziału 15. W rozważa- nym systemie istnieje klasa, której obiekty reprezentują wykładowców, oraz klasa, której obiekty reprezentują opiekunów studiów. Opiekun studiów jest kimś w rodzaju wykładowcy, a dokładniej jest wykładowcą, który oprócz pełnienia zwykłych obowiązków jest odpowiedzialny także za nadzorowanie postępów poszczególnych studentów. W systemie OpiekunStudiow powinien rozumieć takie same komunikaty jak Wykladowca i dodatkowo powinien być w sta- nie odpowiedzieć na komunikat podopieczni, zwracając zbiór obiektów typu Student. Załóżmy, że klasa Wykladowca została już zaimplementowana i teraz należy zaprojektować klasę OpiekunStudiow. Załóżmy też (wyłącznie dla skonkretyzowania przykładu), że używany jest język podobny do C++, w którym interfejs klasy i jego implementacja są przechowywane w oddzielnych plikach. Co jest potrzebne do zaimplementowania nowej klasy tak szybko jak to tylko możliwe? Można skopiować i wkleić kod definiujący interfejs klasy Wykladowca do nowego pliku z interfejsem i dodać u dołu opis dodatkowego komunikatu. Podobnie można skopiować do pliku z implementacją nowej klasy kod, w którym zaimplementowano reakcję obiektów klasy Wykladowca na komunikat, a następnie dokonać niezbędnych zmian. Jak już jednak wspomnieliśmy, wielokrotne używanie kodu przez jego kopiowanie ma wady. Naj- ważniejsza z nich jest taka, że w przypadku konieczności dokonania zmian w zduplikowa- nym kodzie (na przykład wykryto błąd w programie) należy wprowadzić zmiany w dwóch miejscach zamiast w jednym. Jest to uciążliwe i prawdopodobnie doprowadzi do błędów. Zamiast tego obiektowo zorientowane języki programowania dopuszczają utworzenie nowej klasy OpiekunStudiow na podstawie istniejącej klasy Wykladowca. Wystarczy zadekla- rować, że klasa OpiekunStudiow jest podklasą klasy Wykladowca, a następnie dopisać jedynie to, co ma związek z dodatkowymi atrybutami lub operacjami klasy OpiekunStudiow 5. Co więcej, ponieważ w zorientowaniu obiektowym wiedza na temat kodu, jaki zostanie wykonany przez obiekt po tym, gdy otrzyma on komunikat, jest hermetyzowana, istnieje 5 W niektórych językach, a zwłaszcza w języku Eiffel, można w podklasach usuwać atrybuty i operacje nadklas, jednak takie postępowanie nie jest zazwyczaj uważane za dobry zwyczaj. Rozdział 2. ¨ Koncepcje obiektów 45 możliwość, aby w klasie OpiekunStudiow zaimplementować w odpowiedzi na komunikat inne zachowania niż te, które są zaimplementowane w klasie Wykladowca. Oznacza to, że w klasie OpiekunStudiow można przesłonić niektóre z metod klasy Wykladowca. Oprócz dziedziczenia metod po klasie Wykladowca, klasa OpiekunStudiow może zawierać nową metodę implemen- tującą taką samą operację, dla której klasa Wykladowca miała już metodę. Kiedy obiekt klasy OpiekunStudiow otrzyma komunikat z żądaniem wykonania operacji, wywołana metoda bę- dzie wyspecjalizowaną wersją metody udostępnianej przez klasę OpiekunStudiow. Podklasa jest rozszerzoną, wyspecjalizowaną wersją swojej nadklasy. Zawiera operacje oraz atrybuty nadklasy i możliwie jeszcze inne, dodatkowe elementy. P: W jaki sposób jest definiowana podklasa w Twoim języku? Czy klasa może być bezpośrednią podklasą kilku klas (dziedziczenie wielokrotne), czy nie? Terminologia Mówi się, że: klasa OpiekunStudiow dziedziczy po klasie Wykladowca, · klasa OpiekunStudiow jest podklasą (lub klasą pochodną) klasy Wykladowca, · klasa OpiekunStudiow jest specjalizacją klasy Wykladowca, · klasa OpiekunStudiow jest bardziej wyspecjalizowana niż klasa Wykladowca, · klasa Wykladowca jest nadklasą (lub klasą bazową) klasy OpiekunStudiow, · klasa Wykladowca jest generalizacją klasy OpiekunStudiow. · Wszystkie powyższe określenia mają niemal to samo znaczenie. Często pojęcia podklasy i nad- klasy są używane przy opisie konkretnych relacji pomiędzy pojęciami reprezentowanymi w klasach. Zazwyczaj zachodzi między nimi związek. Związki pojęciowe jednak niekoniecz- nie muszą być widoczne w strukturze klasy. Przeciwnie, niektórzy programiści używają dziedziczenia w strukturze klasy w przypadkach, w których nie ma pojęciowego związku dziedziczenia pomiędzy klasami (nie zawsze można polecać takie rozwiązanie. Może być ono wygodne w krótszym okresie czasu, jednak niemal zawsze spowoduje nieporozumienia po upływie dłuższego czasu). Czy można powiedzieć, że klasa OpiekunStudiow należy do klasy Wykladowca? Można, jeśli myśli się o klasach jak o zbiorach obiektów. Gdy mówi się o obiektach klasy Wykladowca, z pewnością chce się uwzględnić także obiekty klasy OpiekunStudiow — po prostu ciągłe pi- sanie o „klasie Wykladowca i dowolnych podklasach” jest zbyt niewygodne. Co więcej, zasa- da, że obiekt podklasy powinien być zastępowalny obiektem nadklasy, jest fundamentalna. Za każdym razem więc, gdy będzie mowa o obiektach należących do klasy, będzie to ozna- czać także obiekty należące do podklas. Z drugiej strony bardzo wygodna byłaby możliwość mówienia o „klasie tego obiektu”, jak gdyby należał on wyłącznie do jednej klasy. Przez określenie „klasa” obiektu będziemy więc rozumieć najbardziej wyspecjalizowaną klasę, do której należy dany obiekt. Oznacza to, że twierdzenie, iż zachowanie obiektu jest określone przez jego klasę, pozostaje prawdziwe. 46 Część I ¨ Tło koncepcyjne 2.4. Polimorfizm i wiązanie dynamiczne Te dwa określenia są często w środowisku zorientowanym obiektowo używane zamiennie. W rzeczywistości oznaczają one całkiem różne koncepcje. Ogólnie w językach programowa- nia jedno pojęcie może istnieć bez drugiego, chociaż w językach zorientowanych obiektowo są one spokrewnione i mają związek z dziedziczeniem. Przede wszystkim należy zauważyć, że sam fakt, iż jedną klasę można definiować na podstawie innej klasy, korzystając ponownie z jej kodu, nie musi mieć żadnego wpływu na to, w jaki sposób kod-klient będzie traktował obiekty tych klas. Możliwy byłby język, w którym dziedziczenie byłoby tylko sposobem na wielokrotne wykorzystywanie kodu. Można by zdefi- niować klasę OpiekunStudiow na podstawie klasy Wykladowca, lecz cały kod klienta (a także kompilator) musiałby dokładnie znać klasę każdego obiektu, z którym by wchodził w inte- rakcję. Technicznie rzecz biorąc oznacza to, że można by utworzyć język z takim rodzajem dziedziczenia, w którym występowałyby wyłącznie typy monomorficzne. Języki zoriento- wane obiektowo radzą sobie jednak lepiej. Polimorfizm Określenie to, wywodzące się z języka greckiego, oznacza mający wiele kształtów. W języ- kach obiektowo zorientowanych odnosi się do sytuacji, w której obiekt może należeć do jednego z kilku typów. W obiektowo zorientowanej sytuacji zmienna polimorficzna mogłaby odnosić się (w różnych przypadkach) do obiektów kilku różnych klas. Funkcja polimorficzna może pobierać argumenty różnych typów. Powiedzieliśmy już, że obiekt podklasy powinien być stosowany w każdej sytuacji, w której mógłby zostać użyty obiekt nadklasy. Powinno to oznaczać w szczególności, że obiekt podklasy powinien być akceptowany jako wartość zmiennej, jeśli jest akceptowany jako obiekt klasy bazowej. Innymi słowy, w obiektowo zorientowanym ję- zyku każda zmienna jest polimorficzna — przynajmniej w tym ograniczonym znaczeniu. Podobnie, jeśli jakaś funkcja (na przykład metoda) może pobierać argument klasy B, powin- na być w stanie pobrać argument dowolnej klasy C, która jest podklasą klasy B; tak więc również każda funkcja jest polimorficzna w tym ograniczonym sensie. Funkcja, która na przykład oczekuje jako arg
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

UML. Inżynieria oprogramowania. Wydanie II
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ą: