Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00258 007633 13275793 na godz. na dobę w sumie
Wzorce implementacyjne - książka
Wzorce implementacyjne - książka
Autor: Liczba stron: 184
Wydawca: Helion Język publikacji: polski
ISBN: 978-83-246-8644-5 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> wzorce projektowe
Porównaj ceny (książka, ebook, audiobook).

Sprawdzone rozwiązania Twoich problemów!

Przy nauce programowania warto uczyć się na cudzych błędach. Programiści tworzący aplikację codziennie natykają się na przeróżne problemy oraz zagadnienia do rozwiązania. Rzadko jednak zdarza się, żeby były one wyjątkowe i niespotykane wcześniej. Jeżeli masz problem, możesz być prawie pewien, że ktoś też już go miał - i w dodatku rozwiązał. Właśnie w ten sposób powstały wzorce, które w jasny sposób opisują sposoby rozwiązywania typowych problemów.

W tej książce znajdziesz 77 wzorców, które pozwolą Ci uniknąć wielu pułapek oraz rozwiązać najczęściej spotykane problemy. W trakcie lektury dowiesz się, w jaki sposób przechowywać stan oraz gdzie umieścić logikę Twojej aplikacji. Ponadto poznasz najefektywniejsze sposoby sterowania przebiegiem programu oraz wybierzesz rodzaj kolekcji odpowiedni do Twoich potrzeb. Nauczysz się dobierać właściwe nazwy dla zmiennych i metod oraz przekonasz się, że można sprawnie opanować wysyp wyjątków. Książka ta jest obowiązkową lekturą każdego programisty. Dzięki niej Twoje życie stanie się prostsze, a Twoje oprogramowanie bardziej przejrzyste!

Dzięki tej książce:

Poznaj najlepsze wzorce, które ulepszą Twoje oprogramowanie!

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

Darmowy fragment publikacji:

Tytuł oryginału: Implementation Patterns Tłumaczenie: Piotr Rajca Projekt okładki: Maciej Pasek Materiały graficzne na okładce zostały wykorzystane za zgodą Shutterstock Images LLC. ISBN: 978-83-246-8644-5 Authorized translation from the English language edition, entitled: IMPLEMENTATION PATTERNS; ISBN 0321413091; by Kent Beck; published by Pearson Education, Inc, publishing as Addison Wesley. Copyright © 2008 by Pearson Education. All rights reserved. No part of this book may by reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. Polish language edition published by HELION S.A. Copyright © 2014. Wszelkie prawa zastrzeżone. Nieautoryzowane rozpowszechnianie całości lub fragmentu niniejszej publikacji w jakiejkolwiek postaci jest zabronione. Wykonywanie kopii metodą kserograficzną, fotograficzną, a także kopiowanie książki na nośniku filmowym, magnetycznym lub innym powoduje naruszenie praw autorskich niniejszej publikacji. Wszystkie znaki występujące w tekście są zastrzeżonymi znakami firmowymi bądź towarowymi ich właścicieli. Wydawnictwo HELION dołożyło wszelkich starań, by zawarte w tej książce informacje były kompletne i rzetelne. Nie bierze jednak żadnej odpowiedzialności ani za ich wykorzystanie, ani za związane z tym ewentualne naruszenie praw patentowych lub autorskich. Wydawnictwo HELION nie ponosi również żadnej odpowiedzialności za ewentualne szkody wynikłe z wykorzystania informacji zawartych w książce. Wydawnictwo HELION ul. Kościuszki 1c, 44-100 GLIWICE tel. 32 231 22 19, 32 230 98 63 e-mail: helion@helion.pl WWW: http://helion.pl (księgarnia internetowa, katalog książek) Drogi Czytelniku! Jeżeli chcesz ocenić tę książkę, zajrzyj pod adres http://helion.pl/user/opinie/wzoimp Możesz tam wpisać swoje uwagi, spostrzeżenia, recenzję. Printed in Poland. • Kup książkę • Poleć książkę • Oceń książkę • Księgarnia internetowa • Lubię to! » Nasza społeczność Spis treści Wstęp ...................................................................................................................................... 11 Podziękowania ....................................................................................................................... 12 Rozdział 1. Wprowadzenie ..................................................................................................... 13 Przewodnik ............................................................................................................................ 15 A teraz… ................................................................................................................................. 16 Rozdział 2. Wzorce ................................................................................................................. 17 Rozdział 3. Teoria programowania ........................................................................................ 21 Wartości ................................................................................................................................. 22 Komunikatywność .......................................................................................................... 22 Prostota ............................................................................................................................ 23 Elastyczność ..................................................................................................................... 24 Zasady ..................................................................................................................................... 25 Lokalne konsekwencje ................................................................................................... 26 Minimalizacja powtórzeń .............................................................................................. 26 Połączenie logiki i danych ............................................................................................. 27 Symetria ........................................................................................................................... 27 Przekaz deklaratywny .................................................................................................... 28 Tempo zmian .................................................................................................................. 29 Wnioski .................................................................................................................................. 30 Rozdział 4. Motywacja ............................................................................................................ 31 Rozdział 5. Klasy ..................................................................................................................... 33 Klasa ........................................................................................................................................ 34 Prosta nazwa klasy bazowej ................................................................................................. 35 Kwalifikowana nazwa klasy pochodnej ............................................................................. 36 Interfejs abstrakcyjny ............................................................................................................ 37 Interfejs ................................................................................................................................... 38 Klasa abstrakcyjna ................................................................................................................. 39 7 Kup książkęPoleć książkę 8 SPIS TREŚCI Interfejs wersjonowany ........................................................................................................ 40 Obiekt wartościowy .............................................................................................................. 41 Specjalizacja ........................................................................................................................... 43 Klasa pochodna ..................................................................................................................... 44 Implementator ....................................................................................................................... 46 Klasa wewnętrzna .................................................................................................................. 47 Zachowanie zależne od instancji ......................................................................................... 48 Konstrukcja warunkowa .......................................................................................................48 Delegacja ..................................................................................................................................50 Selektor dołączany .................................................................................................................52 Anonimowa klasa wewnętrzna ............................................................................................53 Klasa biblioteczna ...................................................................................................................53 Wniosek ...................................................................................................................................54 Rozdział 6. Stan ...................................................................................................................... 55 Stan .......................................................................................................................................... 56 Dostęp ..................................................................................................................................... 57 Dostęp bezpośredni .............................................................................................................. 58 Dostęp pośredni .................................................................................................................... 59 Wspólny stan ......................................................................................................................... 60 Stan zmienny ......................................................................................................................... 60 Stan zewnętrzny ..................................................................................................................... 62 Zmienna ................................................................................................................................. 62 Zmienna lokalna .................................................................................................................... 63 Pole .......................................................................................................................................... 65 Parametr ................................................................................................................................. 66 Parametr zbierający .............................................................................................................. 67 Parametr opcjonalny ............................................................................................................ 68 Zmienna lista argumentów .................................................................................................. 68 Obiekt parametrów ............................................................................................................... 69 Stałe ......................................................................................................................................... 70 Nazwa sugerująca znaczenie ................................................................................................ 71 Zadeklarowany typ ................................................................................................................ 72 Inicjalizacja ............................................................................................................................. 73 Inicjalizacja wczesna ............................................................................................................. 73 Inicjalizacja leniwa ................................................................................................................ 74 Wniosek ...................................................................................................................................75 Rozdział 7. Zachowanie .......................................................................................................... 77 Przepływ sterowania.............................................................................................................. 78 Przepływ główny .................................................................................................................... 78 Komunikat .............................................................................................................................. 79 Komunikat wybierający......................................................................................................... 80 Dwukrotne przydzielanie...................................................................................................... 80 Komunikat dekomponujący (sekwencjonujący)............................................................... 81 Komunikat odwracający ....................................................................................................... 82 Komunikat zapraszający ....................................................................................................... 83 Kup książkęPoleć książkę SPIS TREŚCI 9 Komunikat wyjaśniający ....................................................................................................... 83 Przepływ wyjątkowy .............................................................................................................. 84 Klauzula strażnika.................................................................................................................. 84 Wyjątek.................................................................................................................................... 86 Wyjątki sprawdzane............................................................................................................... 87 Propagacja wyjątków ............................................................................................................. 87 Wniosek....................................................................................................................................88 Rozdział 8. Metody ................................................................................................................. 89 Metoda złożona ..................................................................................................................... 92 Nazwa określająca przeznaczenie ....................................................................................... 93 Widoczność metody ............................................................................................................. 94 Obiekt metody ....................................................................................................................... 96 Metoda przesłonięta ............................................................................................................. 98 Metoda przeciążona .............................................................................................................. 98 Typ wynikowy metody ......................................................................................................... 99 Komentarz do metody ........................................................................................................ 100 Metoda pomocnicza ........................................................................................................... 100 Metoda komunikatu informacyjnego .............................................................................. 101 Konwersja ............................................................................................................................. 102 Metoda konwertująca ......................................................................................................... 102 Konstruktor konwertujący ................................................................................................. 103 Utworzenie ........................................................................................................................... 103 Kompletny konstruktor ...................................................................................................... 104 Metoda wytwórcza .............................................................................................................. 105 Fabryka wewnętrzna ........................................................................................................... 106 Metoda dostępu do kolekcji ............................................................................................... 106 Metoda określająca wartości logiczne .............................................................................. 108 Metoda zapytania ................................................................................................................ 108 Metoda równości ................................................................................................................. 109 Metoda pobierająca ............................................................................................................. 110 Metoda ustawiająca ............................................................................................................. 111 Bezpieczna kopia ................................................................................................................. 112 Wniosek ................................................................................................................................ 113 Rozdział 9. Kolekcje .............................................................................................................. 115 Metafory ............................................................................................................................... 116 Zagadnienia .......................................................................................................................... 117 Interfejsy ............................................................................................................................... 119 Tablice (klasa Array) .................................................................................................... 120 Interfejs Iterable ............................................................................................................ 120 Interfejs Collection — kolekcje ................................................................................... 121 Interfejs List — listy ...................................................................................................... 121 Interfejs Set — zbiory ................................................................................................... 121 Interfejs SortedSet — zbiory posortowane ................................................................ 122 Interfejs Map — mapy ................................................................................................. 123 Implementacje ..................................................................................................................... 123 Kup książkęPoleć książkę 10 SPIS TREŚCI Implementacje interfejsu Collection .......................................................................... 124 Implementacje interfejsu List ..................................................................................... 125 Implementacje interfejsu Set ....................................................................................... 125 Implementacje interfejsu Map .................................................................................... 126 Klasa Collections ................................................................................................................. 128 Wyszukiwanie ............................................................................................................... 128 Sortowanie ..................................................................................................................... 128 Kolekcje niezmienne .................................................................................................... 129 Kolekcje jednoelementowe .......................................................................................... 129 Kolekcje puste ............................................................................................................... 129 Rozszerzanie kolekcji .......................................................................................................... 130 Wniosek ................................................................................................................................ 131 Rozdział 10. Rozwijanie platform ........................................................................................ 133 Modyfikowanie platform bez zmian w aplikacjach ........................................................ 133 Niezgodne aktualizacje ....................................................................................................... 134 Zachęcanie do wprowadzania zgodnych zmian ............................................................. 136 Klasa biblioteczna ......................................................................................................... 137 Obiekty ........................................................................................................................... 137 Wnioski ................................................................................................................................ 146 Dodatek A. Pomiary wydajności .......................................................................................... 149 Przykład ................................................................................................................................ 150 API ......................................................................................................................................... 150 Implementacja ..................................................................................................................... 151 Klasa MethodTimer ............................................................................................................ 152 Eliminacja narzutów czasowych ....................................................................................... 154 Testy ...................................................................................................................................... 154 Porównywanie kolekcji ................................................................................................ 155 Porównywanie kolekcji ArrayList i LinkedList ........................................................ 157 Porównywanie zbiorów ............................................................................................... 158 Porównywanie map ...................................................................................................... 159 Wnioski ................................................................................................................................ 160 Bibliografia ........................................................................................................................... 163 Ogólne zagadnienia programistyczne .............................................................................. 163 Filozofia ................................................................................................................................ 165 Java ........................................................................................................................................ 166 Spis szablonów ...................................................................................................................... 167 Skorowidz ............................................................................................................................. 169 Kup książkęPoleć książkę Rozdział 7 Zachowanie John von Neumann wprowadził jedną z najważniejszych metafor programowania komputerów — sekwencję instrukcji wykonywanych kolejno jedna po drugiej. To właśnie dzięki niej mogły powstać języki programowania, w tym także Java. Ten roz- dział jest poświęcony sposobom przekazywania informacji o zachowaniu programów. Zostały w nim opisane następujące wzorce: (cid:374) Przepływ sterowania (ang. Control Flow) — wyraża obliczenia jako sekwencję czynności. (cid:374) Przepływ główny (ang. Main Flow) — precyzyjnie wyraża główny przepływ stero- wania. (cid:374) Komunikat (ang. Message) — wyraża przepływ sterowania w formie wysyłania komunikatów. (cid:374) Komunikat wybierający (ang. Choosing Message) — zmienia implementujące ko- munikaty w celu wyrażenia wyboru. (cid:374) Podwójne przydzielanie (ang. Double Dispatch) — zmienia elementy implemen- tujące komunikat względem dwóch osi, wyrażając w ten sposób wybór kaskadowy. (cid:374) Komunikat dekomponujący (ang. Decomposing Message) — dzieli złożone obli- czenia na spójne fragmenty. (cid:374) Komunikat odwracający (ang. Reversing Message) — zapewnia symetrię przepływu sterowania poprzez wysyłanie sekwencji komunikatów do tego samego odbiorcy. (cid:374) Komunikat zapraszający (ang. Inviting Message) — zachęca do wprowadzania przyszłych zmian poprzez wysyłanie komunikatu, który może być implementowa- ny na różne sposoby. (cid:374) Komunikat wyjaśniający (ang. Explaining Message) — wysyła komunikat wyja- śniający przeznaczenie pewnego fragmentu logiki. 77 Kup książkęPoleć książkę 78 ROZDZIAŁ 7 ZACHOWANIE (cid:374) Przepływ wyjątkowy (ang. Exceptional Flow) — jak najbardziej precyzyjnie wyraża wyjątkowy przepływ sterowania, bez zakłócania głównego przepływu sterowania. (cid:374) Klauzula strażnika (ang. Guard Clause) — wyraża lokalny przepływ wyjątkowy poprzez wcześniejsze zakończenie wywołania. (cid:374) Wyjątek (ang. Exception) — wyraża nielokalne przepływy wyjątkowe, używając w tym celu wyjątków. (cid:374) Wyjątek sprawdzany (ang. Checked Exception) — wymusza przechwytywanie wy- jątków poprzez ich jawne deklarowanie. (cid:374) Propagacja wyjątków (ang. Exception Propagation) — przekazuje wyjątki, prze- kształcając je w razie konieczności tak, by dostępne w nich informacje były odpo- wiednie dla kodu, który będzie je obsługiwać. Przepływ sterowania Dlaczego przepływ sterowania pojawia się we wszystkich programach? Istnieją języki programowania, takie jak Prolog, w których nie istnieje jawne pojęcie przepływu ste- rowania. W programach pisanych w takich językach wszystkie elementy logiki są wy- mieszane i czekają na zaistnienie odpowiednich warunków, by mogły się uaktywnić. Java należy do rodziny języków programowania, w których sekwencja kontroli jest podstawową zasadą organizacji kodu. Sąsiadujące ze sobą instrukcje są wykonywane kolejno, jedna po drugiej. Warunki sprawiają, że dany kod będzie wykonywany tylko w określonych okolicznościach. Pętle pozwalają na cykliczne wykonywanie fragmentu kodu. Wysyłanie komunikatów powoduje aktywację jednej z kilku podprocedur. Wy- jątki umożliwiają przeskakiwanie do kodu położonego w górze stosu. Wszystkie te mechanizmy sumują się, tworząc wspólnie bogate medium służące do wyrażania sposobu działania obliczeń. Jako autorzy (programiści) decydujemy, czy przepływ sterowania, który sobie wyobrażamy, zostanie wyrażony jako jeden prze- pływ główny, wiele przepływów dodatkowych, z których każdy ma równie duże zna- czenie, czy też jako pewna kombinacja obu powyższych rozwiązań. Grupujemy po- szczególne elementy przepływu sterowania, tak by przeciętny odbiorca mógł je od razu zrozumieć na dosyć abstrakcyjnym poziomie, dodając jednocześnie więcej szcze- gółów dla tych, którzy będą chcieli je zrozumieć dokładniej. Grupowanie to czasami przybiera postać procedur umieszczanych w klasach, a czasami przekazywania stero- wania do innych obiektów. Przepływ główny Programiści zazwyczaj wiedzą, jak ma wyglądać główny przepływ sterowania w two- rzonych programach. Przetwarzanie rozpoczyna się i kończy w precyzyjnie określonych miejscach. W jego trakcie mogą być podejmowane decyzje lub występować wyjątki, Kup książkęPoleć książkę KOMUNIKAT 79 niemniej jednak obliczenia mają ściśle wytyczoną ścieżkę, po której przebiega ich re- alizacja. Jest ona jasno wyrażana przy użyciu wybranego języka programowania. W przypadku niektórych programów, zwłaszcza tych, które mają działać nieza- wodnie w niesprzyjających okolicznościach, przepływ główny nie jest widoczny. Jed- nak takie programy spotyka się raczej sporadycznie. Wykorzystanie dużych możliwości wyrazu używanego języka programowania w celu informowania o rzadko wykonywa- nych i modyfikowanych faktach dotyczących naszego programu sprawia, że mniej za- uważalne stają się jego ważniejsze fragmenty: te, które będą często analizowane, rozu- miane i zmieniane. Nie chodzi o to, że takie wyjątkowe warunki nie mają znaczenia, lecz o to, że dużo cenniejsze jest skoncentrowanie uwagi na precyzyjnym i jasnym wyraża- niu głównego przepływu obliczeń. Dlatego też ten główny przepływ programu należy wyrażać przejrzyście, a wyjątków oraz klauzul strażników używać jedynie w sytuacjach niezwykłych oraz przy błędach. Komunikat Jednym z podstawowych sposobów wyrażania logiki w języku Java są komunikaty. W proceduralnych językach programowania mechanizmem służącym do ukrywania informacji są wywołania procedur: compute() { input(); process(); output(); } Powyższa procedura przekazuje następujące informacje: „W celu zrozumienia tych obliczeń wystarczy wiedzieć, że składają się one z trzech kroków; aktualnie wszelkie pozostałe szczegóły nie mają znaczenia”. Jednym z najpiękniejszych aspektów pro- gramowania obiektowego jest to, że ta sama procedura wyraża także znacznie więcej. Dla każdej metody istnieje potencjalnie cały zbiór obliczeń o podobnej strukturze, różniących się jedynie szczegółami. A dodatkową korzyścią jest to, że tworząc nie- zmienny fragment obliczeń, nie trzeba zwracać uwagi na wszystkie szczegóły ewentu- alnych przyszłych odmian. Wykorzystanie komunikatów jako głównego mechanizmu przepływu sterowania sprawia, że zmiany są podstawową cechą programów. Każdy komunikat jest potencjal- nym miejscem, w którym można coś zmienić bez konieczności modyfikowania kodu bę- dącego źródłem tego komunikatu. Procedury opierające się na idei komunikatów nie stwierdzają: „Tam coś się dzieje, ale szczegóły nie są na razie istotne”; zamiast tego komu- nikują: „W tym miejscu naszej historii z danymi wejściowymi dzieje się coś interesującego. Szczegóły tego, co się dzieje, mogą się jednak zmienić”. Rozważne korzystanie z tej ela- styczności, jasne i bezpośrednie wyrażanie logiki zawsze, gdy to jest możliwe, i odpowied- nie opóźnianie przedstawiania szczegółów to bardzo ważne umiejętności, przydatne, gdy zależy nam na pisaniu programów, które efektywnie wyrażają nasze intencje. Kup książkęPoleć książkę 80 ROZDZIAŁ 7 ZACHOWANIE Komunikat wybierający Czasami wysyłam komunikat służący do wyboru implementacji, podobny do sposobu, w jaki w językach proceduralnych działa instrukcja wyboru switch. Na przykład aby wyświetlić jakiś element graficzny na jeden z kilku dostępnych sposobów i zaznaczyć, że wybór może zostać dokonany w trakcie działania programu, można skorzystać z ko- munikatu polimorficznego. public void displayShape(Shape subject, Brush brush) { brush.display(subject); } Komunikat display() wybiera implementację na podstawie faktycznego typu, który w trakcie działania programu przyjmie parametr brush. Dzięki temu później będzie moż- na zaimplementować różne typy parametrów brush: ScreenBrush, PostscriptBrush itd. Swobodne korzystanie z komunikatów wybierających prowadzi do powstawania kodu, w którym występuje niewiele jawnych warunków. Stosowanie tych komunikatów jest zaproszeniem do późniejszego wprowadzania rozszerzeń. Każdy jawnie podany warunek jest punktem, w którym, w razie chęci zmiany działania całego programu, ko- nieczne będzie wprowadzenie jawnych modyfikacji. Analiza kodu, który w dużym stopniu korzysta z komunikatów wybierających, wymaga nabycia doświadczenia i umiejętności. Jedną z wad stosowania takich komu- nikatów jest to, że zrozumienie konkretnej ścieżki działania programu może wymagać przeanalizowania kilku klas. Twórcy kodu mogą jednak upraszczać życie innym, nadając metodom nazwy informujące o ich przeznaczeniu. Dodatkowo należy także zwracać uwagę na to, kiedy stosowanie komunikatów wybierających będzie przesadą. Jeśli w wy- konywanych obliczeniach nie może się nic zmieniać, to nie należy tworzyć metody tylko po to, by zapewnić możliwość wprowadzenia ewentualnej zmiany. Dwukrotne przydzielanie Komunikaty wybierające dobrze nadają się do wyrażania jednego wymiaru zmienno- ści. W przykładzie podanym w poprzednim podrozdziale wymiarem tym był rodzaj medium, na którym był rysowany kształt. Jeśli jednak konieczne jest wyrażenie dwóch niezależnych wymiarów zmienności, to można to osiągnąć, tworząc kaskadę składają- cą się z dwóch komunikatów wybierających. Załóżmy przykładowo, że należy w jakiś sposób wyrazić, iż postscriptowy owal jest obliczany inaczej niż prostokąt wyświetlany na ekranie. W pierwszej kolejności nale- żałoby określić, gdzie mają się znaleźć obliczenia. Wydaje się, że podstawowe oblicze- nia należą do klasy Brush, dlatego też komunikat wybierający w pierwszej kolejności zostanie wysłany do klasy Shape, a dopiero potem do klasy Brush: displayShape(Shape subject, Brush brush) { subject.displayWith(brush); } Kup książkęPoleć książkę KOMUNIKAT DEKOMPONUJĄCY (SEKWENCJONUJĄCY) 81 Wówczas każdy typ Shape ma możliwość zaimplementowania metody displayWith() w odmienny sposób. Jednak zamiast wykonywać jakieś szczegółowe operacje, dodają one jedynie do komunikatu swój typ i przekazują działanie do klasy Brush: Oval.displayWith(Brush brush) { brush.displayOval(this); } Rectangle.displayWith(Brush brush) { brush.displayRectangle(this); } Dzięki temu do poszczególnych typów pochodnych klasy Brush przekazywane są informacje niezbędne do prawidłowego działania: PostscriptBrush.displayRectangle(Rectangle subject) { writer print(subject.left() + +...+ rect); } Takie rozwiązanie wprowadza pewne powtórzenia, którym towarzyszy utrata ela- styczności. Nazwy typów, do których są przekazywane pierwsze komunikaty wybierające, zostają bowiem podane w kodzie metod obsługujących drugi komunikat wybierający. W powyższym przykładzie oznacza to, że aby dodać nowy kształt — klasę pochodną Shape — konieczne będzie dodanie odpowiednich metod do wszystkich klas pochod- nych klasy Brush. Jeśli wiadomo, że prawdopodobieństwo zmienienia się jednego wy- miaru jest większe niż drugiego, to ten pierwszy wymiar powinien się stać odbiorcą drugiego komunikatu. Naukowiec, który czasami się we mnie odzywa, chciałby uogólnić to rozwiązanie i stworzyć wzorzec przydzielania trzykrotnego, czterokrotnego itd. Niemniej jednak udało mi się jedynie wypróbować rozwiązanie przydzielania trzykrotnego, lecz nawet ono nie zdało egzaminu na dłuższą metę. Zawsze znajdowałem bardziej przejrzyste i zrozumiałem sposoby wyrażania logiki wielowymiarowej. Komunikat dekomponujący (sekwencjonujący) Kiedy pisany program wykorzystuje złożony algorytm, na który składa się wiele kroków, to czasami można pogrupować kroki powiązane ze sobą i wykonywać je, wysyłając je- den komunikat. Taki komunikat jest tworzony w celu zapewnienia możliwości wpro- wadzania specjalizacji lub jakichkolwiek bardziej wyszukanych rozwiązań. Stanowi on odpowiednik staromodnej dekompozycji funkcjonalnej. Komunikat jest w tym przypad- ku stosowany tylko po to, by wywołać podsekwencję kroków umieszczoną w procedurze. Komunikat dekomponujący musi nosić odpowiednią, opisową nazwę. Większość osób analizujących kod powinna uzyskać wszystkie informacje konieczne do określe- nia przeznaczenia procedury wyłącznie na podstawie jej nazwy. Konieczność prze- analizowania całego kodu wywoływanego przez ten komunikat powinna dotyczyć je- dynie osób, które chcą poznać szczegóły implementacyjne. Kup książkęPoleć książkę 82 ROZDZIAŁ 7 ZACHOWANIE Problemy z doborem nazwy komunikatu dekomponującego mogą sugerować, że użycie tego wzorca nie jest właściwym rozwiązaniem. Innym sygnałem może być dłu- ga lista parametrów. Widząc takie sygnały, zastępuję komunikat dekomponujący wy- woływanymi w nim metodami i staram się zastosować inny wzorzec (taki jak obiekt metody), który będzie mi w stanie pomóc właściwie wyrazić strukturę programu. Komunikat odwracający Symetria wpływa na poprawę czytelności kodu. Przeanalizujmy poniższą metodę: void compute() { input(); helper.process(this); output(); } Choć składa się ona z wywołań trzech różnych metod, brakuje w niej symetrii. Jej czytelność można by poprawić, wprowadzając metodę pomocniczą, której użycie za- pewniłoby symetrię. Analizując zmodyfikowaną wersję metody compute(), nie trzeba już śledzić, do kogo jest wysyłany komunikat — wszystkie komunikaty są bowiem kie- rowane do bieżącego obiektu (this). void process(Helper helper) { helper.process(this); } void compute() { input(); process(helper); output(); } W takim przypadku osoba analizująca kod może zrozumieć strukturę metody compute(), przeglądając kod jednej klasy. Czasami zdarza się, że dużego znaczenia nabiera sama metoda wywoływana przez komunikat odwracający. Może się także zdarzyć, że przesadne stosowanie komuni- katów odwracających skutecznie ukryje potrzebę przeniesienia funkcjonalności. Gdy- by w programie pojawił się następujący kod: void input(Helper helper) { helper.input(this); } void output(Helper helper) { helper.output(this); } to najprawdopodobniej można by poprawić całą strukturę kodu, przenosząc metodę compute() do klasy Helper: compute() { new Helper(this).compute(); } Kup książkęPoleć książkę KOMUNIKAT ZAPRASZAJĄCY 83 Helper.compute() { input(); process(); output(); } Osobiście czasami czuję się trochę głupio, tworząc metody „tylko” po to, by zaspo- koić „estetyczne” dążenie do uzyskania symetrii. Jednak ta estetyka ma znacznie głębsze podłoże. Angażuje mózg w większym stopniu niż liniowy proces myślowy. Kiedy już wykształcimy w sobie dążenie do estetyki kodu, to wrażenia estetyczne, które kod bę- dzie nam zapewniał, okażą się cenną informacją o jego jakości. Te odczucia wydosta- jące się spod powierzchni symbolicznych myśli mogą być równie cenne, jak jawnie nazwane i uzasadnione wzorce. Komunikat zapraszający Czasami, pisząc kod, można oczekiwać, że inni programiści będą chcieli zmodyfiko- wać fragment obliczeń przez wprowadzenie klasy pochodnej. Możliwość wprowadzenia takich późniejszych usprawnień da się wyrazić poprzez wysłanie komunikatu o odpo- wiednio dobranej nazwie. Taki komunikat zaprasza innych programistów do uspraw- nienia obliczeń wedle własnych potrzeb. Jeśli dostępna jest jakaś domyślna implementacja logiki, to należy użyć jej jako im- plementacji komunikatu. Jeśli jednak takiej domyślnej implementacji nie ma, to chcąc jawnie przekazać zaproszenie, wystarczy zadeklarować metodę jako abstrakcyjną. Komunikat wyjaśniający W programowaniu zawsze duże znaczenie miało rozróżnienie intencji i implementacji. To właśnie dzięki niemu można najpierw zrozumieć wykonywane obliczenia, a póź- niej, w razie konieczności, poznać ich szczegóły. Rozróżnienie to można utworzyć, ko- rzystając z komunikatów, wystarczy zacząć od wysłania komunikatu, którego nazwa określa rozwiązywany problem, a w obsługującym go kodzie wysłać kolejny komuni- kat o nazwie odpowiadającej sposobowi rozwiązania problemu. Pierwszy raz spotkałem się z takim rozwiązaniem w języku Smalltalk. Konkretnie rzecz biorąc, moją uwagę zwróciła następująca metoda: highlight(Rectangle area) { reverse(area); } Zastanawiałem się: „Dlaczego takie rozwiązanie jest przydatne? Dlaczego nie wywoły- wać metody reverse() bezpośrednio, tylko przy użyciu dodatkowej metody highlight()?”. Jednak po przemyśleniu zagadnienia zrozumiałem, że choć metoda highlight() nie ma żadnego znaczenia z punktu widzenia wykonywanych obliczeń, to jednak służy do wyra- żenia intencji. W kodzie wywołującym tę metodę można było zwrócić uwagę na rozwią- zywany problem, którym w tym przypadku było wyróżnienie fragmentu ekranu. Kup książkęPoleć książkę 84 ROZDZIAŁ 7 ZACHOWANIE Można zastanowić się nad wykorzystaniem komunikatu wyjaśniającego w sytu- acjach, gdy odczuwamy potrzebę skomentowania jakiegoś wiersza kodu. Kiedy widzę następujący wiersz kodu: flags|= LOADED_BIT; // ustawienie warto(cid:258)ci bitu zaj(cid:218)to(cid:258)ci wolałbym użyć następującego wywołania: setLoadedFlag(); Choć implementacja metody setLoadedFlag() jest trywialnie prosta, została ona jednak utworzona w celu wyrażenia intencji. void setLoadedFlag() { flags|= LOADED_BIT; } Zdarza się, że metody pomocnicze wywoływane przez komunikaty wyjaśniające stają się cennymi miejscami dalszego rozwijania kodu. Miło jest móc skorzystać z możli- wości, kiedy się ona nadarzy. Niemniej jednak podstawowym celem, w którym stosuję komunikaty wyjaśniające, jest bardziej precyzyjne wyrażenie moich intencji. Przepływ wyjątkowy Oprócz przepływu głównego programy mają także co najmniej jeden przepływ wyjąt- kowy. Stanowią one ścieżki obliczeń, których wyrażanie nie jest tak ważne, gdyż są rzadziej wykonywane, rzadziej zmieniane, a czasami także mniej istotne od przepływu głównego z koncepcyjnego punktu widzenia. Przepływ główny należy wyrażać w spo- sób przejrzysty, natomiast ścieżki wyjątkowe — w możliwie jak najbardziej przejrzy- sty, lecz jednocześnie taki, by nie zaciemniał przekazu przepływu głównego. Klauzule strażników oraz wyjątki są dwoma sposobami wyrażania przepływu wyjątkowego. Analiza programów jest znacznie łatwiejsza, jeśli tworzące je instrukcje są wyko- nywane sekwencyjnie, jedna po drugiej. W takich przypadkach, aby zrozumieć inten- cję programu, osoby przeglądające kod mogą skorzystać z wygodnych i dobrze zna- nych umiejętności czytania prozy. Czasami jednak może się zdarzyć, że program będzie miał kilka ścieżek realizacji. Wyrażanie ich wszystkich w taki sam sposób może doprowadzić do dużego chaosu i sytuacji, gdy flagi ustawiane w jednym miejscu kod są używane w innych, a wartości wynikowe mogą mieć specjalne znaczenia. Wówczas znale- zienie odpowiedzi na pytanie: „Które instrukcje są wykonywane?” staje się zadaniem z pogranicza archeologii i logiki. Należy zatem wybrać przepływ główny i przejrzyście go wyrazić. A do wyrażenia wszelkich innych ścieżek w programie użyć wyjątków. Klauzula strażnika Choć programy mają pewien przepływ główny, to jednak, w niektórych sytuacjach, może zaistnieć konieczność wykonywania ich innymi ścieżkami. Klauzula strażnika pozwala wyrazić prostą i logiczną sytuację wyjątkową, posiadającą wyłącznie lokalne konse- kwencje. Porównajmy dwa przedstawione poniżej fragmenty kodu: Kup książkęPoleć książkę KLAUZULA STRAŻNIKA 85 void initialize() { if (!isInitialized()) { ... } } oraz: void initialize() { if (isInitialized()) return; ... } W pierwszym z nich, kiedy zaczynam analizować pierwszą klauzulę instrukcji warun- kowej, zwracam uwagę, by później poszukać klauzuli else. Zupełnie jakbym w myślach odłożył warunek na stos. Jest to czynnik, który rozprasza uwagę. W drugim przykła- dzie pierwsze dwa wiersze metody informują mnie jedynie o fakcie — odbiorca nie został zainicjowany. Konstrukcja if-then-else wyraża alternatywne przepływy sterowania, z których oba są równie ważne. Klauzula strażnika nadaje się natomiast do wyrażenia innej sytuacji — sytuacji, w której jeden przepływ sterowania jest ważniejszy od drugiego. W przed- stawionym wyżej przykładzie ze sprawdzaniem inicjalizacji ważniejszym przepływem sterowania jest ten określający, co się stanie, kiedy obiekt będzie zainicjowany. Oprócz niego w kodzie można zwrócić uwagę tylko na jeden prosty fakt, że niezależnie od te- go, ile razy zażądamy zainicjowania obiektu, kod wykonujący tę inicjalizację zostanie wykonany tylko jeden raz. Niegdyś istniało pewne przykazanie programistyczne, nakazujące, by każdy pod- program miał tylko jeden punkt wejścia i jeden punkt wyjścia. Sformułowano go, by za- pobiec zamieszaniu, które mogłoby wystąpić, gdyby realizacja podprogramu mogła się zaczynać w wielu miejscach jego kodu i w wielu miejscach sterowanie mogłoby go opusz- czać. Takie rozwiązanie było sensowne w języku FORTRAN oraz w programach pisanych w języku asemblera, które w dużym stopniu korzystały z danych globalnych i w któ- rych już samo wskazanie wykonywanych instrukcji było trudnym zadaniem. Natomiast w języku Java, w którym tworzone metody są niewielkie i korzystają przeważnie z da- nych lokalnych, takie podejście jest niepotrzebnie konserwatywne. Niemniej jeśli ten swoisty programistyczny folklor będzie rygorystycznie przestrzegany, uniemożliwi stosowanie wzorca klauzuli strażnika. Klauzule strażników są szczególnie użyteczne w sytuacjach, gdy kontrolowanych jest wiele warunków: void compute() { Server server= getServer(); if (server != null) { Client client= server.getClient(); if (client != null) { Request current= client.getRequest(); if (current != null) Kup książkęPoleć książkę 86 ROZDZIAŁ 7 ZACHOWANIE processRequest(current); } } } Zagnieżdżone warunki reprezentują jakieś problemy. W razie wykorzystania klau- zul strażników ten sam kod wskazuje wymagania wstępne, niezbędne do obsługi żądania, a przy tym nie wymaga stosowania żadnych złożonych struktur sterujących: void compute() { Server server= getServer(); if (server == null) return; Client client= server.getClient(); if (client == null) return; Request current= client.getRequest(); if (current == null) return; processRequest(current); } Pewnym wariantem wzorca klauzuli strażnika jest instrukcja continue umieszcza- na w pętlach. Jej użycie stanowi komunikat: „Nie przejmuj się tym elementem i zajmij się następnym”. while (line = reader.readline()) { if (line.startsWith( # ) || line.isEmpty()) continue; // Normalne przetwarzanie } Także w tym przypadku chodzi o wskazanie (jedynie lokalnej) różnicy między przetwarzaniem normalnym i wyjątkowym. Wyjątek Wyjątki są przydatne do wyrażania przeskoków w przepływie programu, przekracza- jących wiele poziomów wywołań. Jeśli w momencie wystąpienia problemu, takiego jak zapełnienie nośnika danych lub utrata połączenia sieciowego, na stosie będzie się znajdo- wało wiele poziomów wywołań, to najprawdopodobniej problem ten będzie można sensownie obsłużyć jedynie na znacznie niższym poziomie stosu. Zgłoszenie wyjątku w momencie wykrycia problemu oraz przechwycenie go w miejscu, gdzie problem ten można obsłużyć, jest znacznie lepszym rozwiązaniem niż umieszczanie w kodzie jaw- nych testów sprawdzających zaistnienie wszelkich możliwych warunków wyjątko- wych, z których i tak w danym miejscu żadnego nie można obsłużyć. Jednak stosowanie wyjątków jest kosztowne. Z punktu widzenia projektu progra- mu są one problematyczne. Fakt, że wywoływana metoda zgłasza wyjątek, ma bowiem wpływ zarówno na projekt, jak i na implementację wszystkich metod od momentu zgło- szenia wyjątku aż do dotarcia do metody, w której zostanie on przechwycony. Wyjątki Kup książkęPoleć książkę WYJĄTKI SPRAWDZANE 87 utrudniają także śledzenie przepływu sterowania, gdyż sąsiadujące ze sobą instrukcje mogą znajdować się w innych metodach, obiektach lub pakietach. Kod, który zamiast z konstrukcji warunkowych i komunikatów korzysta z wyjątków, jest diabelnie trudny do zrozumienia, gdyż bezustannie trzeba starać się odgadnąć, co, oprócz standardowej struktury sterowania, może się w nim jeszcze zdarzyć. Krótko mówiąc, zawsze gdy to tylko możliwe, przepływ sterowania należy wyrażać przy użyciu sekwencji, komunika- tów, iteracji oraz konstrukcji warunkowych (w takiej kolejności). Wyjątków można używać, jeśli zrezygnowanie z nich utrudni proste wyrażenie przepływu głównego. Wyjątki sprawdzane Jednym z niebezpieczeństw stosowania wyjątków jest możliwość wystąpienia sytuacji, gdy zgłoszony wyjątek nigdy nie zostanie przechwycony. Takie sytuacje mają tylko je- den koniec — przerwanie działania programu. Można jednak przypuszczać, że twórca programu chciałby mieć kontrolę nad tym, kiedy program zostanie nieoczekiwanie przerwany, móc wyświetlić wówczas informacje niezbędne do zdiagnozowania pro- blemu i poinformować użytkownika o tym, co się stało. Takie nieprzechwycone wyjątki są jeszcze poważniejszym problemem, kiedy kto inny pisze kod, który je zgłasza, a kto inny kod, który je obsługuje. Wówczas każdy chybio- ny przekaz prowadzi do nagłego i nieuprzejmego zakończenia działania programu. Aby nie dopuścić do takich sytuacji, w języku Java wprowadzono wyjątki spraw- dzane. Są one jawnie deklarowane przez programistę oraz sprawdzane przez kompi- lator. Kod, w którym może się pojawić taki wyjątek, musi go przechwycić lub przeka- zać dalej. Stosowanie wyjątków sprawdzanych wiąże się ze znaczącymi kosztami. Pierwszym z nich jest koszt samej deklaracji. Użycie wyjątku bez trudu może powodować nawet dwukrotne wydłużenie deklaracji metody i dodanie kolejnego elementu, który należy przeczytać, zrozumieć i uwzględnić na wszystkich poziomach pomiędzy momentem zgłoszenia i obsługi. Poza tym wyjątki sprawdzane znacząco utrudniają modyfikowa- nie kodu. Refaktoryzacja kodu korzystającego z takich wyjątków jest znacznie trud- niejsza i bardziej żmudna niż kodu, w którym nie są one stosowane, i to bez względu na to, że nowoczesne narzędzia programistyczne ułatwiają takie zmiany. Propagacja wyjątków Wyjątki pojawiają się na różnych poziomach abstrakcji. Przechwytywanie i raporto- wanie o wyjątkach niskiego poziomu może być kłopotliwe dla osób, które się ich nie spodziewały. Kiedy serwer WWW wyświetla stronę błędu z obrazem stosu rozpoczynają- cym się od NullPointerException, to nie wiem, co mam zrobić z tą informacją. Wo- lałbym zobaczyć komunikat taki jak: „Programista nie przewidział zaistniałego scena- riusza”. Nie miałbym także nic przeciwko temu, żeby na stronie zostały wyświetlone wskazówki dotyczące dodatkowych informacji, które można by przesłać do programisty, Kup książkęPoleć książkę 88 ROZDZIAŁ 7 ZACHOWANIE aby ułatwić mu zdiagnozowanie problemu; natomiast wyświetlanie niewyjaśnionych w żaden sposób technicznych szczegółów nie jest ani użyteczne, ani pomocne. Wyjątki niskiego poziomu często zawierają cenne informacje, przydatne do dia- gnozowania zaistniałych problemów. Takie wyjątki można umieszczać wewnątrz wyjąt- ków wyższych poziomów; dzięki temu podczas prezentowania informacji o wyjątku (na przykład w dzienniku) znajdzie się w nich wszystko, co potrzebne do odnalezienia i roz- wiązania problemu. Wniosek W programach obiektowych sterowanie jest przekazywane pomiędzy metodami. W na- stępnym rozdziale zostało opisane wykorzystanie metod w celu wyrażenia koncepcji występujących w obliczeniach. Kup książkęPoleć książkę Skorowidz A Abstract Class, 34 Abstract Interface, 33 abstrakcja, 138, 140 Access, 55 akcesory, 59 akcje wykonywane na większą odległość, 112 aktualizacja danych, 112 metody ustawiające, 112 komentarzy, 100 powiększenie bazy użytkowników, 136 algorytmy zaimplementowane w obiektach, 111 Anonymous Inner Class, 34 API, 150 klasy biblioteczne, 137 problemy, 137 B bezpieczna kopia, 112 metody ustawiające, 113 bibliografia, 163 biblioteka JUnit, 24 biblioteki stanu, 55 boolean, 145 Boolean Setting Method, 91 C całkowity czas wywołania metody, 153 Checked Exception, 78 Choosing Message, 77 Class, 33 Collecting Parameter, 56 Collection, 72 Collection Accessor Method, 91 Common State, 55 Comparator, 122 Complete Constructor, 91 Composed Method, 90 Conditional, 34 Constant, 56 Control Flow, 77 Conversion, 91 Conversion Constructor, 91 Conversion Method, 91 Creation, 91 czas istnienia zmiennych, 63 D dane a logika, 34, 44 pobieranie, 58 powiązane dostęp pośredni, 59 przeniesienie, 112 stałe w różnych miejscach kodu, 70 szybkość zmian, 29 typu ArrayList, 73 Collection, 73 HashSet, 73 zapisywanie, 58 zmienność, 34 kolekcje, 115 169 Kup książkęPoleć książkę 170 SKOROWIDZ Debug Print Method, 91 Declared Type, 56 Decomposing Message, 77 decyzje programistyczne, 17 projektowe, 37 dekompozycja funkcjonalna, 81 delegacje, 50 konstrukcje warunkowe, 49 odmiana, 51 przechowywanie, 51 Delegation, 34 Direct Access, 55 domyślna wartość parametru, 146 dostęp, 57 bezpośredni, 58 reguły używania, 59 w kodzie klientów, 59 w ramach klasy, 59 czytelność, 58 do elementów projektowych, 38 do kolekcji obiektu, 106 ogólny, 107 do pola, 91 do przechowywanej wartości, 57 do stanu, 59 obiektu, 110 ograniczenie zbioru typów, 63 pośredni, 59 dostosowywanie wysiłku do celu, 149 Double Dispatch, 77 dwukrotne przydzielanie, 80 powtórzenia, 81 dziedziczenie, 44 klasy wewnętrznej, 47 ograniczenia, 44, 46 po klasach kolekcji, 130 równoległe hierarchie klas, 44 wyważone stosowanie, 35 dzielenie logiki, 90 E Eager initialization, 56 Eclipse, 135 efektywność programowania obiektowego, 34 elastyczność, 21, 24, 38 a złożoność, 25 dostęp, 58 do zmiennej, 58 pośredni, 59 dwukrotne przydzielanie, 81 konstruktor bezargumentowy, 104 metoda dostępu do kolekcji, 106 strumień sformatowany, 99 obiekty w kolekcjach, 115 wytwórcze, 144 platformy, 140 sekwencja metod ustawiających, 104 udostępnianie informacji, 73 ujawnianie metod, 94 widoczność metod, 95 wielokrotne dziedziczenie, 38 wykorzystanie delegacji, 50 zapewnienie przekazu, 73 zastosowanie stałych, 154 Equality Method, 91 Exception, 78 Exception Propagation, 78 Exceptional Flow, 78 Explaining Message, 77 Extrinsic State, 55 F fabryka statyczna, 143 wewnętrzna, 106 Factory Method, 91 Field, 56 flaga, 44 bordered, 61 logiczna, 65 funkcja gromadzenie w bibliotece, 53 typ wynikowy, 99 G Getting Method, 91 grupowanie elementów przepływu sterowania, 78 powiązanych ze sobą obiektów, 115 złożony algorytm, 81 Guard Clause, 78 Kup książkęPoleć książkę SKOROWIDZ 171 Helper Method, 90 hierarchia bez powtórzeń, 45 równoległa, 45 uproszczona, 52 horyzont zdarzeń, 104 H I implementacja @RunWith, 140 gniazda, 46 interfejsu Collection, 124 List, 125 Map, 126 Set, 125 kolekcji, 123 niezmiennych, 129 nowych klas, 130 kompletnego konstruktora, 105 komunikat wyboru, 80 konwersji, 102 metoda ustawiająca, 111 platformy, 138 pomiarowej, 152 wielokrotna protokołu, 46 Implementor, 34 Indirect Access, 55 inicjalizacja, 73 deklaracja zmiennej, 73 leniwa, 74 fabryki wewnętrzne, 106 metody pobierające, 111 środowiska, 74 pól obiektu, 74 wczesna, 73 Initialization, 56 Inner Class, 34 Instance-Specific Behavior, 34 instancje interfejsu Command, 40 ReversibleCommand, 40 określanie sposobu działania, 48 tej samej klasy, 48 tworzenie zachowań, 51 instrukcja warunkowa for, 120 if/else, 48 switch, 48 instrukcje continue, 86 wykonywane sekwencyjne, 84 intencje a implementacja, 83 Intention-Revealing Name, 90 Interface, 33 interfejs, 37 a hierarchie klas, 40 a klasy abstrakcyjne, 39 a nazwy metod, 94 abstrakcje platfomry, 140 metody, 145 abstrakcyjny, 39 aktualizacja platformy, 140 anonimowe klasy wewnętrzne, 53 Collection, 119, 121 implementacje, 124 dodanie operacji, 40 elastyczność, 37 instanceof, 41 Iterable, 119, 120 jako klasa bez implementacji, 38 jako obiekt zaimplemetowany, 39 jako typ wynikowy metod, 99 klasy Array, 119, 120 Object, 101 kolekcji, 119 koszty stosowania, 37 List, 119, 121 implementacje, 125 Map, 119, 123 implementacje, 126 testowanie, 159 metoda ustawiająca, 111 wykorzystująca stałe, 70 modyfikowanie implementacji, 38 struktury, 41 nieprzewidywalność oprogramowania, 37 obiektu źródłowego i docelowego, 102 obliczeń alternatywny, 90 określanie nazw, 38 Kup książkęPoleć książkę 172 SKOROWIDZ interfejs operacje publiczne, 38 proceduralny, 42 Set, 119, 121 implementacje, 125 porównanie implementacji, 158 SortedSet, 119, 122, 125, 158 ustawienie wartości pola, 111 wersjonowany, 39, 140 zalety, 140 zarządcy układu, 140 zmienność komunikatów, 70 zmienny, 41 Internal Factory, 91 Inviting Message, 77 iterator, 94, 107 mapy, 123 J Java mechanizmy tworzenia interfejsów, 38 możliwość zmian interfejsu, 39 obiekt parametrów, 69 organizacja kodu, 78 typy podstawowe, 41 wartości parametrów, 68 jawność kodu, 80 język obiektowy, 57 proceduralny mechanizm ukrywania informacji, 79 Smalltalk, 83 JUnit, 133 wykonywanie testów, 152 K klarowność dostęp bezpośredni, 58 klasa abstrakcyjna a interfejsy, 39 dodawanie nowych operacji, 39 ograniczenia, 39 Socket, 46 Account, 147 ArrayList, 123, 124, 125, 143 bazowa, 35 abstrakcja platformy, 141 abstrakcyjna, 39 anonimowa, 53 dostęp klientów, 141 możliwość tworzenia instancji, 40 prosta nazwa, 35 rozdzielenie logiki, 45 testu, 156 biblioteczna, 53, 137 zastąpienie obiektami, 54 Bordered, 61 Brush, 80 Cartesian, 103 Collection, 54, 118 CollectionFactory, 144 Collections, 137 funkcjonalności, 128 jednoelementowe kolekcje, 129 niezmienne kolekcje, 129 puste kolekcje, 129 sortowanie, 128 wyszukiwanie, 128 Comparator, 139 ComplexCalculator, 97 Customer, 94 deklaracja, 34 dobieranie nazwy, 35 Enumerator, 135 Figure, 35 File, 103 Handle, 36 HashMap, 126 HashSet, 123, 124, 125, 159 idea, 33 interfejsy, 38 jako element projektowy, 35 JUnitCore, 139 komunikacja, 33 Library, 54, 130 LinkedHashMap, 126 LinkedHashSet, 125 LinkedList, 125 List, 54 ListTest, 52 Map, 118 MethodsTimer, 150 MethodTimer wydajność, 152 Nothing, 151 Kup książkęPoleć książkę organizowanie w hierarchie, 35 pochodna, 35, 44 awaria, 98 konstrukcje warunkowe, 49 kwalifikowana nazwa, 36 różne testy, 52 usprawnienia, 106 Point, 103 Polar, 103 potomna wywołanie własnego kodu, 98 RectangleTool, 51 Set, 118 SetVsArrayList, 156 Shape, 80 String, 103 Train, 44 Transaction, 147 TreeMap, 126 TreeSet, 125, 138, 158 używana w jednym miejscu, 53 Vector, 135 Vehicle, 44 w pakiecie, 135 wewnętrzna, 47 anonimowa, 53 kopie obiektów, 47 niezależna, 48 Widget, 145 klauzula strażnika, 84 użyteczność, 85 wymagania wstępne obsługi żądania, 86 klucze, 123 kod a dane, 27 a zapewnienie wydajności, 118 abstrakcyjność, 105 aktualizacja, 135 automatyczna, 135 analiza metody konwersji, 103 metod przeciążonych, 99 anonimowej klasy wewnętrznej, 53 czytelność, 82, 93 deklaracje zmiennych, 73, 117 deklaratywny, 28 deklarowanie pól, 65 dostosowanie stylu do kontekstu, 160 fragmenty niezalecane, 135 SKOROWIDZ 173 informacje specjalnego przeznaczenia, 62 inicjalizacja leniwa, 75 instrukcje warunkowe, 48 intencje twórcy, 22 jakość, 12 kolekcje, 117 komentarze, 100 komunikaty, 79 wybierające, 80 komunikatywność, 22 konstrukcje warunkowe, 46 lokalne konsekwencje zmian, 26 mechanizmy optymalizacji, 149 metody określające wartości logiczne, 108 pomocniczej, 101 wytwórcze, 105 nadawanie struktury, 93 obiekty metody, 97 powtórzenia wierszy, 101 wytwórcze, 144 powtarzanie, 26 eliminacja, 28 prostota, 24 przejrzystość, 32 przeniesienie logiki, 109 rozwój platformy, 133 różne kombinacje dostępu, 63 skopiowany, 45 stan, 57 symetria, 27, 82 testy warunków wyjątkowych, 86 usprawnienie obliczeń, 83 w klasie bazowej, 45 wcięcia, 92 wrażliwość, 112 współużytkowanie delegacje, 51 wyjątki sprawdzane, 87 zabezpieczenie, 113 zgodne zmiany, 136 kolejka wiadomości lista, 121 kolekcje, 63, 115 aktualizowanie platform, 135 ArrayList, 157 dodawanie elementów, 116 Kup książkęPoleć książkę 174 SKOROWIDZ kolekcje elementy unikalność, 118 uporządkowanie, 122 usunięcie powtórzeń, 122 usuwanie, 120 znaczenie kolejności, 117 implementacje, 123 inicjalizacja klasy testy, 156 interfejsy, 119 i klasy, 124 jako obiekty, 116 jako zbiór, 121 jako zbiór obiektów, 117 jednoelementowe, 129 kluczy, 123 LinkedList, 157 metafory, 116 modyfikowanie zawartości, 120 niezmienne, 129 odwołanie do obiektów, 116 pojęcia ortogonalne, 117 pola reprezentujące, 116 porównywanie, 157 posiadające tożsamość, 116 przekazywanie, 68 puste, 129 rozszerzanie, 116, 130 równoległe architektury, 135 sortowanie, 128 typu Collection, 155 typu Map elementy, 123 typu Set duplikaty elementów, 121 przechowywanie elementów, 121 w kolekcji, 107 wartości, 123 wielkość, 117 wydajność, 118 pomiary, 149 wyrażanie intencji, 115 wyszukiwanie, 128 zabezpieczenie, 107, 120 zagadnienia, 117 komentarz do metody, 100 dokumentujący, 100 komparator, 122, 126 byFirstName, 139 komputery mainframe, 24 komunikat, 46, 79 a konstrukcje warunkowe, 49 dekomponujący, 81 display(), 80 logika, 49 metoda, 101 odwracający, 82 polimorficzny, 46, 80 sekwencjonujący, 81 wybierający, 80 kaskada, 80 wyjaśniający, 83 komentarz kodu, 84 zapraszający, 83 komunikatywność, 21, 22 a elastyczność, 25 a prostota, 24 określanie nazw klas, 36 podstawa ekonomiczna, 23 stan zmienny, 61 komunikowanie intencji kolekcje, 115 za pośrednictwem kodu, 13 konfiguracja platformy, 138 zastosowanie stałych, 154 konstrukcja if-then-else, 85 konstrukcje warunkowe, 48 konstruktor czteroargumentowy, 105 File(String name), 103 główny, 105 klasy MethodTimer, 152 ServerSocket, 68 wewnętrznej, 47 kompletny, 104 konwertujący, 103 przygotowanie obiektów, 104 StringReader(String contents), 103 tworzenie obiektów platformy, 143 URL(String spec), 103 zamiennik metoda statyczna, 96 zastosowanie metod pomocniczych, 101 Kup książkęPoleć książkę SKOROWIDZ 175 konwersja, 102 a zmiana klienta, 103 cel, 103 implementacja, 102 między obiektami podobnych typów, 102 obiektu źródłowego na docelowy, 102 koszty abstrakcji, 40 aktualizacji niezgodnych, 135 redukcja, 134 testów, 100 analizy i zrozumienia kodu, 32 kolekcja w kolekcji, 107 komentarzy, 100 modyfikowania programów obiekty, 104 napisania, 31 określania zmiennych, 74 oprogramowania, 31 selektora dołączanego, 53 tworzenia oprogramowania, 23 platform, 134 utrzymania, 31 widoczność metod, 95 wydajności, 118 wyjątki sprawdzane, 87 wywoływania obiektów, 95 zachowania zgodności, 134 zachowań zależnych od instancji, 48 zmiany kodu, 133 L Lazy initialization, 56 Library Class, 34 liczba iteracji, 153 potrzebnych konwesji, 102 licznik czasu, 150 logika a metoda pobierająca, 111 anonimowe klasy wewnętrzne, 53 grupowanie w klasy, 34 i dane, 27 zgrupowanie, 29 komunikaty polimorficzne, 115 konstrukcje warunkowe, 115 metody pomocniczej, 101 obiektu, 48 obsługi kliknięcia, 51 operująca na różnych danych, 44 na tych samych danych, 44 parametry obiektowe, 70 podział na metody, 89 przeniesienie, 112 w jednej klasie, 48 w metodach statycznych, 53 w różnych instancjach, 50 warunkowa zastąpienie komunikatami, 49 wyrażanie podobieństw i różnic, 44 przez komunikaty, 79 zmienna, 46 zmienność, 34 lokalne konsekwencje, 26 M Main Flow, 77 mapy, 123 porównywanie, 159 stan zmienny, 60 mechanizm odzwierciedlania, 52, 153 klasy wewnętrzne, 47 optymalizacji, 149 przekazywania zmiennej liczby argumentów, 69 dokładność, 151 narzut, 154 zewnętrzny interfejs, 150 List, 72 listy, 121 literate programming, 22 Local Variable, 56 przepływu sterowania komunikaty, 79 Message, 77 metafora nazywanie klas, 35 Method Comment, 90 Method Object, 90 Method Return Type, 90 Kup książkęPoleć książkę 176 SKOROWIDZ Method Visibility, 90 metoda, 89 abstrakcyjna, 83 dodawanie do klasy bazowej, 141 addAll(), 121 akcesorów, 59 argumenty opcjonalne, 69 calculate(), 97 chroniona, 95, 100 clear(), 130 Collections.binarySearch(list, element), 128 Collections.factory(), 144 Collections.singleton(), 129 complexCalculation(), 97 compute(), 82 contains(), 117, 124 createArrayList(), 144 czas wykonania, 153 display(), 48 displayWith(), 81 długość, 92 do pomiaru czasu, 156 dostępna w pakiecie, 95 dostępu do kolekcji, 106, 113 equal(), 121 equals(), 91, 109 fabryki statycznej, 154 find(), 94 get(int), 157 getDeclaredMethods(), 152 getX(), 103 getY(), 103 hashCode(), 91, 109 hasNext(), 94 highlight(), 83 inactive(), 145 indexOf(),
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Wzorce implementacyjne
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ą: