Programowanie zorientowane obiektowo - pdf.helion.plpdf.helion.pl/prozor/prozor-1.pdf · †...

34
Wydawnictwo Helion ul. Chopina 6 44-100 Gliwice tel. (32)230-98-63 e-mail: [email protected] PRZYK£ADOWY ROZDZIA£ PRZYK£ADOWY ROZDZIA£ IDZ DO IDZ DO ZAMÓW DRUKOWANY KATALOG ZAMÓW DRUKOWANY KATALOG KATALOG KSI¥¯EK KATALOG KSI¥¯EK TWÓJ KOSZYK TWÓJ KOSZYK CENNIK I INFORMACJE CENNIK I INFORMACJE ZAMÓW INFORMACJE O NOWOŒCIACH ZAMÓW INFORMACJE O NOWOŒCIACH ZAMÓW CENNIK ZAMÓW CENNIK CZYTELNIA CZYTELNIA FRAGMENTY KSI¥¯EK ONLINE FRAGMENTY KSI¥¯EK ONLINE SPIS TREŒCI SPIS TREŒCI DODAJ DO KOSZYKA DODAJ DO KOSZYKA KATALOG ONLINE KATALOG ONLINE Programowanie zorientowane obiektowo Poznaj regu³y projektowania i programowania obiektowego • Elementy techniki obiektowej • Metodyka tworzenia oprogramowania • Implementacja mechanizmów obiektowych Programowanie zorientowane obiektowo to technika, która w ci¹gu ostatnich lat zyska³a niezwyk³¹ popularnoœæ. Jêzyki programowania obiektowego œwiêc¹ triumfy, a metodologie projektowania oparte na analizie obiektowej staj¹ siê standardami przemys³owymi. Za³o¿enia analizy i programowania obiektowego s¹ pozornie proste, jednak¿e bez ich w³aœciwego zrozumienia nie mo¿na zaprojektowaæ prawid³owo aplikacji implementowanej w obiektowym jêzyku programowania. Technologia obiektowa zmieni³a ca³y przemys³ programistyczny, wiêc jej opanowanie jest niezbêdnym elementem wiedzy ka¿dego informatyka, który chce wykorzystywaæ w pracy nowoczesne metody i techniki. Ksi¹¿ka „Programowanie zorientowane obiektowo” to wyczerpuj¹ce omówienie wszystkich zagadnieñ zwi¹zanych z projektowaniem i programowaniem obiektowym. Opisuje g³ówne elementy techniki obiektowej oraz wiele spoœród ich potencjalnych zastosowañ. Dziêki ksi¹¿ce poznasz równie¿ metodykê projektowania oprogramowania, dowiesz siê, czym s¹ wzorce projektowe, i nauczysz siê, w jaki sposób zaimplementowaæ lub zasymulowaæ techniki obiektowe w ró¿nych jêzykach programowania. • Podstawowe elementy projektowania obiektowego • Wielokrotne wykorzystywanie kodu • Analiza obiektowa • Abstrakcyjne typy danych • Klasy i obiekty • Zarz¹dzanie pamiêci¹ • Mechanizmy dziedziczenia • Obs³uga wyj¹tków • Metodyka projektowania obiektowego • Programowanie wspó³bie¿ne • Obiektowe bazy danych • Zastosowanie technik obiektowych w ró¿nych jêzykach programowania Wykorzystaj techniki obiektowe i popraw jakoœæ tworzonego przez siebie oprogramowania Autor: Bertrand Meyer T³umaczenie: Micha³ Dadan (wstêp, rozdz. 1–6, 9, 10, 15, dod. A, C, D), Jaros³aw Dobrzañski (rozdz. 7, 17–25), Jan Ostrowski (rozdz. 26–32), Jaromir Senczyk (rozdz. 16, 33–36, dod. B), Krzysztof Szafranek (rozdz. 8, 11–14) ISBN: 83-7361-738-8 Tytu³ orygina³u: Object-Oriented Software Construction Second Edition Format: B5, stron: 1464

Transcript of Programowanie zorientowane obiektowo - pdf.helion.plpdf.helion.pl/prozor/prozor-1.pdf · †...

Wydawnictwo Helionul. Chopina 644-100 Gliwicetel. (32)230-98-63e-mail: [email protected]

PRZYK£ADOWY ROZDZIA£PRZYK£ADOWY ROZDZIA£

IDZ DOIDZ DO

ZAMÓW DRUKOWANY KATALOGZAMÓW DRUKOWANY KATALOG

KATALOG KSI¥¯EKKATALOG KSI¥¯EK

TWÓJ KOSZYKTWÓJ KOSZYK

CENNIK I INFORMACJECENNIK I INFORMACJE

ZAMÓW INFORMACJEO NOWOŒCIACH

ZAMÓW INFORMACJEO NOWOŒCIACH

ZAMÓW CENNIKZAMÓW CENNIK

CZYTELNIACZYTELNIAFRAGMENTY KSI¥¯EK ONLINEFRAGMENTY KSI¥¯EK ONLINE

SPIS TREŒCISPIS TREŒCI

DODAJ DO KOSZYKADODAJ DO KOSZYKA

KATALOG ONLINEKATALOG ONLINE

Programowaniezorientowane obiektowo

Poznaj regu³y projektowania i programowania obiektowego

• Elementy techniki obiektowej• Metodyka tworzenia oprogramowania• Implementacja mechanizmów obiektowych

Programowanie zorientowane obiektowo to technika, która w ci¹gu ostatnich lat zyska³a niezwyk³¹ popularnoœæ. Jêzyki programowania obiektowego œwiêc¹ triumfy,a metodologie projektowania oparte na analizie obiektowej staj¹ siê standardami przemys³owymi. Za³o¿enia analizy i programowania obiektowego s¹ pozornie proste, jednak¿e bez ich w³aœciwego zrozumienia nie mo¿na zaprojektowaæ prawid³owo aplikacji implementowanej w obiektowym jêzyku programowania. Technologia obiektowa zmieni³a ca³y przemys³ programistyczny, wiêc jej opanowanie jest niezbêdnym elementem wiedzy ka¿dego informatyka, który chce wykorzystywaæw pracy nowoczesne metody i techniki.

Ksi¹¿ka „Programowanie zorientowane obiektowo” to wyczerpuj¹ce omówienie wszystkich zagadnieñ zwi¹zanych z projektowaniem i programowaniem obiektowym. Opisuje g³ówne elementy techniki obiektowej oraz wiele spoœród ich potencjalnych zastosowañ. Dziêki ksi¹¿ce poznasz równie¿ metodykê projektowania oprogramowania, dowiesz siê, czym s¹ wzorce projektowe, i nauczysz siê, w jaki sposób zaimplementowaæ lub zasymulowaæ techniki obiektowe w ró¿nych jêzykach programowania.

• Podstawowe elementy projektowania obiektowego• Wielokrotne wykorzystywanie kodu• Analiza obiektowa• Abstrakcyjne typy danych• Klasy i obiekty• Zarz¹dzanie pamiêci¹• Mechanizmy dziedziczenia• Obs³uga wyj¹tków• Metodyka projektowania obiektowego• Programowanie wspó³bie¿ne• Obiektowe bazy danych• Zastosowanie technik obiektowych w ró¿nych jêzykach programowania

Wykorzystaj techniki obiektowe i popraw jakoϾ tworzonego przez siebie oprogramowania

Autor: Bertrand MeyerT³umaczenie: Micha³ Dadan (wstêp, rozdz. 1–6, 9, 10, 15,dod. A, C, D), Jaros³aw Dobrzañski (rozdz. 7, 17–25),Jan Ostrowski (rozdz. 26–32), Jaromir Senczyk (rozdz. 16,33–36, dod. B), Krzysztof Szafranek (rozdz. 8, 11–14)ISBN: 83-7361-738-8Tytu³ orygina³u: Object-Oriented SoftwareConstruction Second EditionFormat: B5, stron: 1464

SPIS TREŚCI

O Autorze .............................................................................................................15Wstęp ....................................................................................................................17

Część I Podstawy 27

1.Jakość oprogramowania .....................................................................................291.1. Czynniki zewnętrzne i wewnętrzne ........................................................................................................291.2. Przegląd czynników zewnętrznych ........................................................................................................301.3. Konserwacja oprogramowania ...............................................................................................................451.4. Kluczowe pojęcia wprowadzone w tym rozdziale .................................................................................471.5. Bibliografia ............................................................................................................................................48

2.Kryteria obiektowości .........................................................................................512.1. O kryteriach ...........................................................................................................................................522.2. Technika i język .....................................................................................................................................532.3. Implementacja i środowisko ...................................................................................................................632.4. Biblioteki ................................................................................................................................................652.5. Rzut oka na konkretny projekt ...............................................................................................................672.6. Bibliografia (w tym materiały na temat obiektów) .................................................................................67

Część II W stronę obiektowości 69

3.Modułowość .........................................................................................................713.1. Pięć kryteriów ........................................................................................................................................723.2. Pięć reguł ...............................................................................................................................................793.3. Pięć zasad ...............................................................................................................................................86

4 SPIS TREŚCI

3.4. Kluczowe pojęcia wprowadzone w tym rozdziale .................................................................................973.5. Bibliografia ............................................................................................................................................98Ćwiczenia .......................................................................................................................................................99

4.Wielokrotne wykorzystywanie kodu ...............................................................1014.1. Cele wielokrotnego wykorzystywania kodu .........................................................................................1024.2. Jakie elementy systemów nadają się do wielokrotnego wykorzystywania? .........................................1054.3. Powtórzenia w procesie tworzenia systemu .........................................................................................1094.4. Problemy nietechniczne .......................................................................................................................1104.5. Problem natury technicznej ..................................................................................................................1184.6. Pięć wymagań dotyczących struktury modułów ..................................................................................1204.7. Tradycyjne struktury modułowe ..........................................................................................................1264.8. Przeciążanie i generyczność .................................................................................................................1314.9. Kluczowe pojęcia wprowadzone w tym rozdziale ...............................................................................137

4.10. Bibliografia ..........................................................................................................................................138

5.W stronę techniki obiektowej ..........................................................................1415.1. Składniki „obliczeń” ............................................................................................................................1415.2. Dekompozycja funkcjonalna ................................................................................................................1435.3. Dekompozycja obiektowa ....................................................................................................................1555.4. Programowanie zorientowane obiektowo ............................................................................................1575.5. Pytania .................................................................................................................................................1585.6. Kluczowe pojęcia wprowadzone w tym rozdziale ...............................................................................1605.7. Bibliografia ..........................................................................................................................................161

6.Abstrakcyjne typy danych ...............................................................................1636.1. Kryteria ................................................................................................................................................1646.2. Możliwe implementacje .......................................................................................................................1646.3. W stronę abstrakcyjnego postrzegania obiektów .................................................................................1686.4. Formalizacja specyfikacji .....................................................................................................................1726.5. Od abstrakcyjnych typów danych do klas ............................................................................................1866.6. Nie tylko oprogramowanie ...................................................................................................................1916.7. Informacje uzupełniające .....................................................................................................................1926.8. Kluczowe pojęcia wprowadzone w tym rozdziale ...............................................................................2046.9. Bibliografia ..........................................................................................................................................205Ćwiczenia .....................................................................................................................................................206

Część III Techniki obiektowe 209

7.Klasy — struktura statyczna ...........................................................................2117.1. Obiekty nie są najważniejsze ...............................................................................................................2117.2. Unikanie typowych nieporozumień ......................................................................................................212

SPIS TREŚCI 5

7.3. Znaczenie klas ......................................................................................................................................2167.4. Jednolity system typów ........................................................................................................................2177.5. Prosta klasa ..........................................................................................................................................2187.6. Podstawowe konwencje .......................................................................................................................2237.7. Przebieg wykonania programu obiektowego ........................................................................................2277.8. Eksportowanie wybiórcze a ukrywanie informacji ..............................................................................2387.9. Składanie wszystkiego w całość ...........................................................................................................241

7.10. Analiza .................................................................................................................................................2507.11. Kluczowe pojęcia wprowadzone w tym rozdziale ...............................................................................2627.12. Bibliografia ..........................................................................................................................................263Ćwiczenia .....................................................................................................................................................264

8.Struktury czasu wykonywania: obiekty .........................................................2658.1. Obiekty .................................................................................................................................................2668.2. Obiekty jako narzędzie do modelowania ..............................................................................................2778.3. Manipulowanie obiektami i referencjami .............................................................................................2808.4. Procedury tworzące ..............................................................................................................................2858.5. Więcej o referencjach ...........................................................................................................................2898.6. Operacje na referencjach ......................................................................................................................2918.7. Obiekty złożone i typy rozszerzone .....................................................................................................3038.8. Wiązanie: semantyka referencji i wartości ...........................................................................................3108.9. Korzystanie z referencji: korzyści i zagrożenia ....................................................................................315

8.10. Analiza .................................................................................................................................................3208.11. Kluczowe pojęcia wprowadzone w tym rozdziale ...............................................................................3258.12. Bibliografia ..........................................................................................................................................326Ćwiczenia .....................................................................................................................................................327

9.Zarządzanie pamięcią .......................................................................................3299.1. Co dzieje się z obiektami? ....................................................................................................................3299.2. Podejście klasyczne ..............................................................................................................................3429.3. Zagadnienia związane z odzyskiwaniem pamięci ................................................................................3459.4. Dealokacja kontrolowana przez programistę ........................................................................................3469.5. Rozwiązanie na poziomie komponentów .............................................................................................3499.6. Automatyczne zarządzanie pamięcią ...................................................................................................3549.7. Zliczanie referencji ...............................................................................................................................3559.8. Oczyszczanie pamięci ..........................................................................................................................3579.9. Mechanizm oczyszczania pamięci w praktyce .....................................................................................364

9.10. Środowisko z zaimplementowanym odzyskiwaniem pamięci .............................................................3679.11. Kluczowe pojęcia wprowadzone w tym rozdziale ...............................................................................3709.12. Bibliografia ..........................................................................................................................................371Ćwiczenia .....................................................................................................................................................372

10.Generyczność .....................................................................................................37310.1. Pozioma i pionowa generalizacja typów ............................................................................................37410.2. Potrzeba parametryzacji typów ..........................................................................................................37410.3. Klasy generyczne ...............................................................................................................................377

6 SPIS TREŚCI

10.4. Tablice ................................................................................................................................................38210.5. Koszt generyczności ...........................................................................................................................38610.6. Analiza — to jeszcze nie koniec ........................................................................................................38710.7. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................38710.8. Bibliografia ........................................................................................................................................388Ćwiczenia .....................................................................................................................................................388

11.Projektowanie kontraktowe: tworzenie niezawodnego oprogramowania ....39111.1. Proste mechanizmy niezawodności ....................................................................................................39211.2. O poprawności oprogramowania ........................................................................................................39311.3. Specyfikacja .......................................................................................................................................39411.4. Wprowadzanie asercji do kodu ..........................................................................................................39711.5. Warunki początkowe i warunki końcowe ..........................................................................................39811.6. Używanie kontraktów dla poprawy niezawodności ...........................................................................40211.7. Praca z asercjami ................................................................................................................................40811.8. Niezmienniki klas ...............................................................................................................................42211.9. Kiedy klasa jest poprawna? ................................................................................................................428

11.10. Związek z ATD ..................................................................................................................................43211.11. Instrukcja asercji ................................................................................................................................43611.12. Niezmienniki i zmienne pętli .............................................................................................................43911.13. Korzystanie z asercji ..........................................................................................................................44711.14. Analiza ...............................................................................................................................................45611.15. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................46511.16. Bibliografia ........................................................................................................................................466Ćwiczenia .....................................................................................................................................................467Postscriptum: katastrofa Ariane 5 .................................................................................................................469

12.Gdy kontrakt nie zostaje dotrzymany: obsługa wyjątków ...........................47112.1. Podstawy obsługi wyjątków ...............................................................................................................47112.2. Obsługa wyjątków ..............................................................................................................................47412.3. Mechanizm wyjątków ........................................................................................................................47912.4. Przykłady obsługi wyjątków ..............................................................................................................48212.5. Zadanie klauzuli ratunkowej ..............................................................................................................48812.6. Zaawansowana obsługa wyjątków .....................................................................................................49112.7. Analiza ...............................................................................................................................................49612.8. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................49812.9. Bibliografia ........................................................................................................................................498Ćwiczenia .....................................................................................................................................................499

13.Mechanizmy pomocnicze ..................................................................................50113.1. Komunikacja z oprogramowaniem nieobiektowym ...........................................................................50113.2. Przekazywanie argumentów ...............................................................................................................50713.3. Instrukcje ............................................................................................................................................50913.4. Wyrażenia ..........................................................................................................................................515

SPIS TREŚCI 7

13.5. Łańcuchy znaków ...............................................................................................................................52013.6. Wejście i wyjście ................................................................................................................................52113.7. Konwencje leksykalne ........................................................................................................................52113.8. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................521Ćwiczenia .....................................................................................................................................................522

14.Wprowadzenie do dziedziczenia ......................................................................52314.1. Wielokąty i prostokąty .......................................................................................................................52414.2. Polimorfizm .......................................................................................................................................53114.3. Kontrola typów a dziedziczenie .........................................................................................................53614.4. Dynamiczne wiązanie ........................................................................................................................54514.5. Cechy i klasy abstrakcyjne .................................................................................................................54714.6. Techniki ponownej deklaracji ............................................................................................................55614.7. Znaczenie dziedziczenia .....................................................................................................................56014.8. Rola klas abstrakcyjnych ....................................................................................................................56614.9. Analiza ...............................................................................................................................................573

14.10. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................58314.11. Bibliografia ........................................................................................................................................584Ćwiczenia .....................................................................................................................................................585

15.Dziedziczenie wielokrotne ................................................................................58715.1. Przykłady dziedziczenia wielokrotnego .............................................................................................58715.2. Zmiana nazw cech ..............................................................................................................................60415.3. Spłaszczanie struktury ........................................................................................................................61115.4. Powtórne dziedziczenie ......................................................................................................................61415.5. Analiza ...............................................................................................................................................63515.6. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................63815.7. Bibliografia ........................................................................................................................................638Ćwiczenia .....................................................................................................................................................639

16.Techniki dziedziczenia ......................................................................................64316.1. Dziedziczenie i asercje .......................................................................................................................64416.2. Globalna struktura dziedziczenia .......................................................................................................65616.3. Cechy zamrożone ...............................................................................................................................65916.4. Generyczność ograniczona .................................................................................................................66116.5. Próba przypisania ...............................................................................................................................66716.6. Zgodność typów i ponowne deklaracje ..............................................................................................67216.7. Deklaracje kotwiczone .......................................................................................................................67516.8. Dziedziczenie i ukrywanie informacji ................................................................................................68316.9. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................688

16.10. Bibliografia ........................................................................................................................................689Ćwiczenia .....................................................................................................................................................689

8 SPIS TREŚCI

17.Kontrola typów ..................................................................................................69117.1. Problem z kontrolą typów ..................................................................................................................69117.2. Statyczna kontrola typów — kiedy i jak? ...........................................................................................69617.3. Kowariancja i ukrywanie u potomków ...............................................................................................70317.4. Pierwsze podejście do kwestii poprawności systemu .........................................................................71117.5. Bazowanie na typach zakotwiczonych ...............................................................................................71317.6. Analiza globalna .................................................................................................................................71717.7. Uwaga na polimorficzne wywołania ZDLT! ......................................................................................71917.8. Ocena .................................................................................................................................................72217.9. Idealny typ .........................................................................................................................................723

17.10. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................72517.11. Bibliografia ........................................................................................................................................725

18.Obiekty i stałe globalne ....................................................................................72718.1. Stałe podstawowych typów ................................................................................................................72818.2. Korzystanie ze stałych ........................................................................................................................72918.3. Stałe o typach będących klasami ........................................................................................................73018.4. Zastosowanie podprogramów jednorazowych ...................................................................................73218.5. Stałe typu łańcuchowego ....................................................................................................................73818.6. Wartości unikatowe ............................................................................................................................73818.7. Analiza ...............................................................................................................................................74018.8. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................74418.9. Bibliografia ........................................................................................................................................745Ćwiczenia .....................................................................................................................................................745

Część IV Metodyka obiektowa— prawidłowe stosowanie metody 747

19.O metodyce ........................................................................................................74919.1. Metodyka programowania — jak i dlaczego? ....................................................................................74919.2. Wymyślanie dobrych reguł — porady dla radzących .........................................................................75019.3. O użyciu metafor ................................................................................................................................75819.4. Znaczenie pokory ...............................................................................................................................76019.5. Bibliografia ........................................................................................................................................761Ćwiczenia .....................................................................................................................................................761

20.Wzorzec projektowy — wielopanelowe systemy interaktywne ....................76320.1. Systemy wielopanelowe .....................................................................................................................76320.2. Proste rozwiązanie .............................................................................................................................765

SPIS TREŚCI 9

20.3. Rozwiązanie hierarchiczne z funkcjami .............................................................................................76620.4. Krytyka rozwiązania ..........................................................................................................................77020.5. Architektura obiektowa ......................................................................................................................77220.6. Analiza ...............................................................................................................................................78120.7. Bibliografia ........................................................................................................................................782

21.Dziedziczenie — studium przypadku:operacja „cofnij” w systemie interaktywnym ................................................78321.1. Perseverare diabolicum ......................................................................................................................78321.2. Wyszukiwanie abstrakcji ....................................................................................................................78721.3. Wielopoziomowy mechanizm cofnij-powtórz ...................................................................................79321.4. Aspekty implementacyjne ..................................................................................................................79621.5. Interfejs użytkownika dla operacji cofania i powtarzania ..................................................................80021.6. Analiza ...............................................................................................................................................80221.7. Bibliografia ........................................................................................................................................804Ćwiczenia .....................................................................................................................................................805

22.Jak odnaleźć klasy? ..........................................................................................80922.1. Analiza dokumentu z wymogami .......................................................................................................81022.2. Oznaki zagrożenia ..............................................................................................................................81622.3. Ogólna heurystyka odnajdywania klas ...............................................................................................82222.4. Inne źródła klas ..................................................................................................................................82622.5. Wielokrotne zastosowanie ..................................................................................................................83222.6. Metoda uzyskiwania klas ...................................................................................................................83322.7. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................83522.8. Bibliografia ........................................................................................................................................835Ćwiczenia .....................................................................................................................................................836

23.Zasady projektowania klas ..............................................................................83923.1. Skutki uboczne w funkcjach ...............................................................................................................84023.2. Ile argumentów powinna mieć cecha? ................................................................................................85623.3. Rozmiar klasy — metoda listy zakupów ............................................................................................86323.4. Aktywne struktury danych .................................................................................................................86723.5. Cechy eksportowane selektywnie .......................................................................................................89223.6. Postępowanie w przypadkach nietypowych .......................................................................................89323.7. Ewolucja klasy — klauzula OBSOLETE ...........................................................................................89823.8. Dokumentowanie klasy i systemu ......................................................................................................89923.9. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................902

23.10. Bibliografia ........................................................................................................................................902Ćwiczenia .....................................................................................................................................................903

10 SPIS TREŚCI

24.Prawidłowe stosowanie dziedziczenia .............................................................90724.1. Jak używać dziedziczenia? .................................................................................................................90724.2. Kupić czy odziedziczyć? ....................................................................................................................91024.3. Przykład zastosowania — technika uchwytów ...................................................................................91624.4. Taksomania ........................................................................................................................................91924.5. Zastosowanie dziedziczenia — taksonomia taksonomii .....................................................................92124.6. Jeden czy więcej mechanizmów? .......................................................................................................93324.7. Dziedziczenie podtypów i ukrywanie u potomków ............................................................................93524.8. Dziedziczenie implementacji .............................................................................................................94424.9. Dziedziczenie udogodnień .................................................................................................................947

24.10. Wielość kryteriów i dziedziczenie perspektywy ................................................................................95224.11. Jak opracowywać struktury dziedziczenia? ........................................................................................95824.12. Podsumowanie — prawidłowe stosowanie dziedziczenia ..................................................................96224.13. Kluczowe pojęcia wprowadzone w tym rozdziale .............................................................................96324.14. Bibliografia ........................................................................................................................................96424.15. Dodatek — historia taksonomii ..........................................................................................................964Ćwiczenia .....................................................................................................................................................970

25.Przydatne techniki ............................................................................................97325.1. Filozofia projektowania ......................................................................................................................97325.2. Klasy ..................................................................................................................................................97425.3. Techniki dziedziczenia .......................................................................................................................976

26.Poczucie stylu ....................................................................................................97926.1. Kwestie kosmetyczne mają znaczenie! ..............................................................................................97926.2. Dobór odpowiednich nazw .................................................................................................................98326.3. Stałe ...................................................................................................................................................98926.4. Komentarze nagłówkowe i klauzule indeksujące ...............................................................................99126.5. Układ i prezentacja tekstu ..................................................................................................................99726.6. Czcionki ...........................................................................................................................................100626.7. Bibliografia ......................................................................................................................................1008Ćwiczenia ...................................................................................................................................................1008

27.Analiza obiektowa ...........................................................................................101127.1. Cele analizy ......................................................................................................................................101227.2. Zmienna natura analizy ....................................................................................................................101427.3. Wkład technologii obiektowej ..........................................................................................................101527.4. Programowanie stacji telewizyjnej ...................................................................................................101627.5. Użyteczność analizy — wielokrotność postaci ................................................................................102327.6. Metody analizy .................................................................................................................................102727.7. Notacja obiektów biznesowych — NOB ..........................................................................................103027.8. Bibliografia ......................................................................................................................................1033

SPIS TREŚCI 11

28.Proces tworzenia oprogramowania ...............................................................103528.1. Klastry ..............................................................................................................................................103528.2. Inżynieria symultaniczna ..................................................................................................................103628.3. Kroki i zadania .................................................................................................................................103828.4. Klastrowy model cyklu życia oprogramowania ...............................................................................103928.5. Uogólnienie ......................................................................................................................................104028.6. Jednolitość i odwracalność ...............................................................................................................104328.7. Wśród nas wszystko jest twarzą .......................................................................................................104628.8. Kluczowe pojęcia wprowadzone w tym rozdziale ...........................................................................104728.9. Bibliografia ......................................................................................................................................1047

29.Nauczanie .........................................................................................................104929.1. Szkolenia przemysłowe ....................................................................................................................104929.2. Kursy wprowadzające ......................................................................................................................105229.3. Inne kursy .........................................................................................................................................105629.4. W kierunku nowych sposobów nauczania tworzenia oprogramowania ...........................................105829.5. Plan wydziału związany z obiektowością ........................................................................................106229.6. Kluczowe zagadnienia wprowadzone w rozdziale ...........................................................................106429.7. Bibliografia ......................................................................................................................................1064

Część V Zagadnienia zaawansowane 1067

30.Współbieżność, rozproszenie, klient-serwer i internet ................................106930.1. Krótkie podsumowanie ....................................................................................................................107030.2. Narodziny współbieżności ...............................................................................................................107130.3. Od procesów do obiektów ................................................................................................................107530.4. Wykonywanie współbieżne ..............................................................................................................108330.5. Kwestie synchronizacji ....................................................................................................................109730.6. Dostęp do obiektów niezależnych ....................................................................................................110330.7. Warunki oczekiwania .......................................................................................................................111230.8. Żądania obsługi w trybie specjalnym ...............................................................................................112130.9. Przykłady .........................................................................................................................................1126

30.10. W kierunku reguły dowodzenia poprawności ..................................................................................114430.11. Podsumowanie przedstawionego mechanizmu współbieżności .......................................................114630.12. Analiza .............................................................................................................................................114930.13. Kluczowe pojęcia wprowadzone w tym rozdziale ...........................................................................115430.14. Bibliografia ......................................................................................................................................1155Ćwiczenia ...................................................................................................................................................1157

31.Trwałość obiektów i bazy danych ..................................................................116131.1. Trwałość jako element języka ..........................................................................................................116131.2. Granice implementacji trwałości ......................................................................................................1163

12 SPIS TREŚCI

31.3. Ewolucja schematu ...........................................................................................................................116531.4. Od trwałości do baz danych .............................................................................................................117231.5. Współpraca obiektowo-relacyjna .....................................................................................................117331.6. Podstawy obiektowych baz danych ..................................................................................................117631.7. Systemy obiektowych baz danych — przykłady ..............................................................................118231.8. Analiza — pozaobiektowe bazy danych ..........................................................................................118531.9. Kluczowe pojęcia wprowadzone w tym rozdziale ...........................................................................1187

31.10. Bibliografia ......................................................................................................................................1188Ćwiczenia ...................................................................................................................................................1189

32.Wybrane techniki obiektowe wykorzystywane w interaktywnychaplikacjach z graficznym interfejsem użytkownika ....................................119132.1. Potrzebne narzędzia .........................................................................................................................119232.2. Przenośność i adaptacja do platformy ..............................................................................................119532.3. Abstrakcje graficzne .........................................................................................................................119732.4. Mechanizmy interakcji .....................................................................................................................120032.5. Obsługa zdarzeń ...............................................................................................................................120232.6. Model matematyczny .......................................................................................................................120632.7. Bibliografia ......................................................................................................................................1206

Część VI Zastosowanie metody w różnychjęzykach i środowiskach programowania 1207

33.Programowanie obiektowe i Ada ...................................................................120933.1. Trochę historii ..................................................................................................................................121033.2. Pakiety ..............................................................................................................................................121133.3. Implementacja stosu .........................................................................................................................121233.4. Ukrywanie reprezentacji ..................................................................................................................121633.5. Wyjątki .............................................................................................................................................121833.6. Zadania .............................................................................................................................................122233.7. Ada 95 ..............................................................................................................................................122333.8. Kluczowe pojęcia wprowadzone w tym rozdziale ...........................................................................122833.9. Bibliografia ......................................................................................................................................1228Ćwiczenia ...................................................................................................................................................1229

34.Emulacja technologii obiektowej w środowiskach nieobiektowych ...........123134.1. Poziomy obsługi koncepcji obiektowych .........................................................................................123234.2. Programowanie obiektowe w Pascalu? ............................................................................................123334.3. Fortran ..............................................................................................................................................123434.4. Programowanie obiektowe i język C ................................................................................................123934.5. Bibliografia ......................................................................................................................................1245Ćwiczenia ...................................................................................................................................................1246

SPIS TREŚCI 13

35.Od Simuli do Javy: główne języki i środowiska obiektowe ........................124735.1. Simula ..............................................................................................................................................124835.2. Smalltalk ..........................................................................................................................................126135.3. Rozszerzenia języka Lisp .................................................................................................................126535.4. Rozszerzenia języka C .....................................................................................................................126735.5. Java ..................................................................................................................................................127135.6. Inne języki obiektowe ......................................................................................................................127235.7. Bibliografia ......................................................................................................................................1273Ćwiczenia ...................................................................................................................................................1275

Część VII W praktyce 1277

36.Środowisko obiektowe ....................................................................................127936.1. Komponenty .....................................................................................................................................128036.2. Język ................................................................................................................................................128036.3. Technologia kompilacji ....................................................................................................................128136.4. Narzędzia .........................................................................................................................................128536.5. Biblioteki ..........................................................................................................................................128936.6. Mechanizmy interfejsu .....................................................................................................................129036.7. Bibliografia ......................................................................................................................................1297

Epilog ujawnia język ......................................................................................1299

Dodatki 1301

AWybrane klasy bibliotek Base .......................................................................1303

BGeneryczność a dziedziczenie ........................................................................1355B.1. Generyczność ....................................................................................................................................1356B.2. Dziedziczenie ....................................................................................................................................1361B.3. Emulacja dziedziczenia za pomocą generyczności ............................................................................1363B.4. Emulacja generyczności za pomocą dziedziczenia ............................................................................1364B.5. Łączenie generyczności z dziedziczeniem .........................................................................................1372B.6. Kluczowe pojęcia wprowadzone w tym dodatku ..............................................................................1376B.7. Bibliografia ........................................................................................................................................1376Ćwiczenia ...................................................................................................................................................1377

14 SPIS TREŚCI

CZasady, reguły, nakazy i definicje .................................................................1379

DOkreślenia stosowane w technice obiektowej ...............................................1385

EBibliografia ......................................................................................................1397E.1. Prace innych autorów ........................................................................................................................1397E.2. Prace autora książki ...........................................................................................................................1416

Skorowidz ........................................................................................................ 1421

1JAKOŚĆ OPROGRAMOWANIA

Słowo inżynieria nieodzownie kojarzy się z jakością. Inżynieria oprogramowania totworzenie wysokich jakościowo programów. Ta książka opisuje techniki, które poten-cjalnie mogą przyczynić się do znacznego podniesienia jakości aplikacji komputerowych.

Zanim zacznę je omawiać, muszę napisać, w jakim celu zostały wymyślone. Jakośćoprogramowania najlepiej pojmować jako sumę wielu czynników. W tym rozdziale opi-szę kilka z nich, zidentyfikuję obszary, jakie najpilniej wymagają usprawnień, i wskażękierunek, w którym wspólnie będziemy szukać rozwiązań w trakcie dalszej lektury.

1.1. CZYNNIKI ZEWNĘTRZNE I WEWNĘTRZNE

Wszyscy chcemy, aby nasze oprogramowanie było szybkie, niezawodne, łatwe w obsłu-dze, czytelne, modułowe, sensownie skonstruowane itd. Tyle tylko, że te przymiotnikiopisują dwa różne rodzaje zalet.

Po jednej stronie mamy zalety, takie jak szybkość czy łatwość obsługi, którychobecność lub brak może z łatwością stwierdzić każdy użytkownik. Tego rodzaju właści-wości możemy nazwać zewnętrznymi czynnikami decydującymi o jakości.

Pod pojęciem „użytkownicy” należy rozumieć nie tylko osoby, które będą fizyczniekorzystały z gotowych programów (na przykład pracownik linii lotniczych obsługującysystem rezerwacji lotów), ale także decydentów, którzy podjęli decyzję o ich zakupiebądź zlecili ich opracowanie (analogicznie dyrektor linii lotniczych, którego uprawnieniana to pozwalają). Tak więc taka właściwość jak łatwość, z jaką oprogramowaniedaje się dostosowywać do zmian w specyfikacji (w dalszej części tego rozdziałunazywana rozszerzalnością), jest zaliczana do kategorii czynników zewnętrznych,mimo iż „użytkownicy końcowi”, tacy jak pracownik dokonujący rezerwacji,mogą nie być nią bezpośrednio zainteresowani.

Inne możliwe zalety programu komputerowego, takie jak czytelność czy modu-łowość, zaliczamy do czynników wewnętrznych, ponieważ są one dostrzegalne jedyniedla informatyków mających dostęp do kodu źródłowego programu.

30 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

W ostatecznym rozrachunku liczą się tylko czynniki zewnętrzne. Gdy korzystamz przeglądarki internetowej lub mieszkam w pobliżu elektrowni atomowej sterowanejprzez program komputerowy, tak naprawdę nie obchodzi mnie to, czy jego kod źró-dłowy jest modularny i czytelny. Ważne, żeby obrazki w przeglądarce nie wczyty-wały się godzinami, a błędne dane wejściowe nie mogły doprowadzić do wysadzeniaelektrowni. Jednak kluczem do osiągnięcia satysfakcjonujących czynników zewnętrz-nych są czynniki wewnętrzne. Aby użytkownicy mogli cieszyć się widocznymi ozna-kami jakości aplikacji, ich projektanci i implementatorzy muszą stosować techniki gwa-rantujące wysoką jakość wewnętrzną.

W kolejnych rozdziałach przedstawiam zbiór współczesnych technik pozwalają-cych na uzyskanie właśnie wewnętrznej jakości aplikacji. Czytając ten rozdział, niepowinieneś jednak tracić z oczu szerszego obrazu. Techniki wewnętrzne nie są naszymcelem same w sobie. Są to jedynie środki, za pomocą których możemy uzyskać wysokąjakość zewnętrzną tworzonych aplikacji. Dlatego też musimy zacząć od omówieniaczynników zewnętrznych. Przeznaczyłem na to pozostałą część tego rozdziału.

1.2. PRZEGLĄD CZYNNIKÓW ZEWNĘTRZNYCH

Poniżej opisuję najważniejsze czynniki zewnętrzne decydujące o jakości, które powinnybyć obecne w każdym programie komputerowym. Doprowadzenie do takiego stanu jestgłównym celem programowania zorientowanego obiektowo.

Poprawność

Definicja poprawnościPoprawność to zdolność programów komputerowych do wykonywania dokładnietych zadań, które im powierzono i które zdefiniowano w ich specyfikacjach.

Poprawność jest zdecydowanie najważniejszym czynnikiem. Jeżeli system nie robitego, czego się po nim oczekuje, wszystko inne — czy jest szybki, czy ma przyjemnyinterfejs użytkownika itd. — nie ma większego znaczenia.

Łatwo o niej pisać, ale znacznie trudniej ją osiągnąć. Już pierwszy krok na dro-dze do poprawności jest trudny. Trzeba bowiem precyzyjnie określić wymagania sta-wiane systemowi.

Techniki stosowane w celu zapewnienia poprawności zazwyczaj odnoszą się je-dynie do pewnego obszaru systemu. Poważne współczesne programy komputerowe,nawet te mniejsze, odnoszą się do zagadnień z tak wielu dziedzin, że niemożliwe byłobyzagwarantowanie ich poprawności po przeanalizowaniu komponentów i właściwościtylko na jednej płaszczyźnie. Dlatego konieczne jest podejście warstwowe, w którymwyższe warstwy polegają na niższych (patrz rysunek 1.1).

1.2. PRZEGLĄD CZYNNIKÓW ZEWNĘTRZNYCH 31

RYSUNEK 1.1.Warstwyw procesie tworzeniaoprogramowania

W tak zwanym warunkowym podejściu do poprawności interesuje nas jedyniezagwarantowanie poprawności danej warstwy przy założeniu, że wszystkie warstwyleżące niżej na pewno są poprawne. Jest to jedyne realistyczne podejście, ponieważpozwala rozbić problem na kilka części i koncentrować się w danym momencie tylkona jednej z nich. Nie możesz twierdzić, że program napisany w języku wysokiego po-ziomu X jest poprawny, jeżeli nie masz pewności, że kompilator, którym dysponu-jesz, prawidłowo implementuje język X. Nie oznacza to wcale, że musisz ślepo ufaćkompilatorowi. Po prostu problem zostaje tu rozbity na dwie części. Poprawność kom-pilatora i poprawność programu z punktu widzenia semantyki języka.

W technice opisywanej w tej książce poprawność zależy od jeszcze większej liczbywarstw (patrz rysunek 1.2), ponieważ tworząc programy komputerowe, będziemy polegalina bibliotekach komponentów przeznaczonych do wielokrotnego użycia, które mogą byćwykorzystywane do budowy wielu różnych aplikacji.

RYSUNEK 1.2.Warstwy w procesietworzenia aplikacji,w którym posługujemysię komponentamiwielokrotnego użytku

Również w tym przypadku stosuje się podejście warunkowe. Powinniśmy za-gwarantować poprawność bibliotek, a następnie — w oparciu o nią — poprawnośćaplikacji.

Wielu praktykom stykającym się z zagadnieniem poprawności oprogramowaniaprzychodzi na myśl testowanie i lokalizowanie błędów. Jednak do problemu możnapodejść bardziej ambitnie. W dalszych rozdziałach przyjrzymy się wielu technikom,w szczególności kontroli typów i asercjom, które wymyślono po to, aby ułatwić two-rzenie oprogramowania, które jest poprawne od samego początku. Jest to znacznielepsze podejście, niż zmuszanie programu do poprawności dopiero na pewnym etapie.Jednak nie zwalnia nas ono z testowania i lokalizowania błędów, czyli czynności, którew tym przypadku pozwalają na upewnienie się, że program faktycznie jest poprawny.

32 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

Można iść jeszcze dalej i przyjąć całkiem sformalizowane podejście do tworze-nia oprogramowania. Postanowiłem stosować w książce dość potoczny język, dlategowspomnę jedynie, że wiele technik, które opisuję w dalszych rozdziałach, wywodzisię bezpośrednio ze ścisłych, matematycznych technik formułowania specyfikacji pro-gramów i ich weryfikacji, które pozwalają bardzo mocno zbliżyć się do ideału w pełnipoprawnego oprogramowania.

Odporność

Definicja odpornościOdporność to zdolność systemów komputerowych do prawidłowego reagowaniana niestandardowe sytuacje.

Odporność stanowi uzupełnienie poprawności (patrz rysunek 1.3). Poprawnośćokreśla zachowanie systemów w sytuacjach przewidzianych w specyfikacji. Z koleiodporność charakteryzuje działania podejmowane po napotkaniu sytuacji wykraczają-cych poza specyfikację.

RYSUNEK 1.3.Odpornośćkontra poprawność

Już sama definicja pokazuje, że odporność nie jest tak ścisłym pojęciem jak po-prawność. Ponieważ mówimy tu o przypadkach nieprzewidzianych w specyfikacji, niemożemy powiedzieć, że system powinien wówczas po prostu „wykonywać swoje za-dania”. Gdyby te zadania były znane, każdy taki niestandardowy przypadek stałby sięczęścią specyfikacji, co przeniosłoby nas z powrotem w obszar poprawności.

Definicja „niestandardowej sytuacji” przyda się jeszcze, gdy będziemy omawiali obsługęwyjątków. Wynika z niej, że to, co nazywamy sytuacją standardową, a co niestandardową,zależy od przyjętej specyfikacji. Sytuacja niestandardowa to po prostu taka, która niezostała w niej przewidziana. Jeżeli poszerzymy specyfikację, wówczas sytuacje, którebyły niestandardowe, staną się standardowe, nawet jeśli dotyczą takich okoliczności jakwprowadzenie przez użytkownika nieprawidłowych danych. Tak więc „standardowe” nieoznacza w tym przypadku „pożądane”, a jedynie „przewidziane na etapie projektowaniaprogramu”. Mimo iż nazywanie wprowadzenia błędnych danych „standardową sytuacją”może z początku wydawać się paradoksalne, każde inne rozwiązanie wymagałobyustalenia obiektywnych kryteriów, a tym samym byłoby bezużyteczne.

Zawsze mogą zdarzyć się sytuacje, których specyfikacja bezpośrednio nie prze-widuje. Znaczenie odporności polega na gwarancji, że pojawienie się takich okolicz-ności nie spowoduje żadnej katastrofy. Program powinien po prostu wyświetlić sto-sowne komunikaty o błędzie i zakończyć w normalny sposób swoje wykonywanie lubwejść w tak zwany „tryb łagodnego zejścia”.

Informacjena tematobsługiwyjątkówznajdzieszw rozdziale 12.

1.2. PRZEGLĄD CZYNNIKÓW ZEWNĘTRZNYCH 33

Rozszerzalność

Definicja rozszerzalnościRozszerzalność to możliwość łatwego dostosowywania programu komputerowegodo zmian w specyfikacji.

Oprogramowanie, w przeciwieństwie do sprzętu, z założenia powinno dawać się łatwomodyfikować. Tak właśnie jest, jeśli tylko mamy dostęp do kodu źródłowego. Jego zmia-na jest w takiej sytuacji banalnie prosta. Wystarczy posłużyć się dowolnym edytoremtekstów.

Z zagadnieniem rozszerzalności wiąże się problem skali. W małych aplikacjachwprowadzenie zmian zazwyczaj nie stanowi problemu. Jeśli jednak mamy do czynie-nia z coraz bardziej rozbudowanymi programami, to coraz trudniej je modyfikować.Tego rodzaju aplikacje przypominają czasami ogromne domki z kart, a wyciągnięcietylko jednego elementu może spowodować zawalenie się całej konstrukcji.

Rozszerzalność jest potrzebna ze względu na to, że u podstaw każdego programukomputerowego leży czynnik ludzki, co czyni go podatnym na błędy, które trzebapóźniej poprawiać. Weźmy pod uwagę na przykład programy biznesowe (takie jakinformacyjne systemy zarządzania). Wystarczy, że zmienią się jakieś przepisy prawalub firma zostanie przejęta przez konkurencję, a już założenia, na których oparty byłsystem, przestaną być aktualne. Jest to dość sztampowy przykład, ale niewiele osóbzdaje sobie sprawę z tego, że z podobną sytuacją mamy do czynienia nawet w pro-gramach naukowych, w przypadku których możemy zakładać, że za miesiąc lub dwabędą nadal obowiązywały te same prawa fizyki co dzisiaj. Jednak może ulec zmianiesposób, w jaki je pojmujemy, lub procedura modelowania pewnych zjawisk.

W tradycyjnym podejściu do inżynierii oprogramowania nie przykładano wy-starczająco dużej wagi do zmian. Zamiast tego opierano się na idealistycznym po-strzeganiu cyklu życia oprogramowania, w którym wymagania były zamrażane już naetapie analizy potrzeb. Na dalszych etapach skupiano się już wyłącznie na projekto-waniu i tworzeniu rozwiązania. Jest to zrozumiałe. Pierwszym krokiem na drodzerozwoju inżynierii programowania było opracowanie przejrzystych technik formuło-wania i rozwiązywania stałych, niezmiennych problemów. Dopiero później zaczętosię martwić, co należy robić w sytuacji, gdy problem ulega zmianie w czasie, kiedywciąż szukamy rozwiązania. Obecnie podstawowe techniki inżynierii oprogramowa-nia są już opracowane i dlatego pora zająć się opisywanym problemem. Zmiany sąnieodłącznym elementem procesu tworzenia oprogramowania. Możemy mieć do czy-nienia ze zmianami wymagań, sposobu ich pojmowania, algorytmów, sposobu pre-zentacji danych lub technik implementacyjnych. Umożliwienie łatwego ich wprowa-dzania jest głównym zadaniem techniki obiektowej i tematem przewodnim tej książki.

Choć wiele technik zwiększających rozszerzalność można prezentować na pro-stych przykładach, ich znaczenie staje się jasne dopiero w przypadku większych pro-jektów. Przy zwiększaniu rozszerzalności kluczową rolę odgrywają dwie zasady:

• Prostota projektu — proste architektury zawsze łatwiej zaadaptować do zmian niżzłożone.

• Decentralizacja — im większa autonomia poszczególnych modułów, tym więk-sze prawdopodobieństwo, że prosta zmiana specyfikacji będzie wymagała zmo-dyfikowania tylko jednego lub kilku modułów i nie wywoła reakcji łańcuchowejw całym systemie.

34 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

Technika programowania zorientowanego obiektowo jest przede wszystkim tech-niką tworzenia takich architektur systemów, które pomagają projektantom w tworzeniuzdecentralizowanych programów o prostej strukturze (nawet jeśli są to duże projekty).Prostota i decentralizacja to kluczowe zagadnienia, które będą się przewijały w naszejdyskusji do czasu, aż w kolejnych rozdziałach sformułujemy zasady rządzące technikąobiektową.

Przystosowanie do wielokrotnego użycia

Definicja przystosowania do wielokrotnego użyciaPrzystosowanie do wielokrotnego użycia to zdolność elementów składowych opro-gramowania do pełnienia roli elementów konstrukcyjnych wielu różnych aplikacji.

Potrzeba przystosowania do wielokrotnego użycia wynika z obserwacji, że w wieluprogramach komputerowych przewijają się te same wzorce. Dlatego powinna istniećmożliwość wykorzystania tych podobieństw, pozwalająca na uniknięcie ponownegowynajdywania koła. Dostrzegając taki wzorzec, możemy wyodrębnić element pro-gramu, który nadaje się do wykorzystania w wielu różnych projektach.

Przystosowanie do wielokrotnego użycia ma wpływ na wszystkie inne aspektyjakości oprogramowania, ponieważ dzięki niemu nie trzeba pisać tak dużo kodu jakdawniej i można skupić się (przy takim samym całkowitym koszcie projektu) na po-prawianiu innych czynników, takich jak poprawność czy odporność.

Jest to przykład kolejnego zagadnienia, na które nie położono wystarczająco du-żego nacisku w tradycyjnym pojmowaniu cyklu życia aplikacji. Powody historycznesą tu takie same jak w poprzednim przypadku. Przyjęto, że najpierw trzeba znaleźćrozwiązanie jednego problemu, a dopiero potem można stosować je w odniesieniu doinnych problemów. Jednak rozrastanie się programów komputerowych i próba uczy-nienia z informatyki prawdziwego przemysłu doprowadziły do tego, że przystosowaniekodu do wielokrotnego użycia stało się palącą potrzebą.

Przystosowanie do wielokrotnego użycia będzie odgrywało kluczową rolę przyomawianiu zagadnień przedstawionych w następnych rozdziałach. Jeden z nich jest prak-tycznie w całości poświęcony dogłębnej analizie tego czynnika decydującego o jakości,omówieniu wymiernych korzyści, jakie on daje, i problemów, jakie się z nim wiążą.

Zgodność

Definicja zgodnościZgodność to łatwość, z jaką można ze sobą łączyć poszczególne składniki oprogra-mowania.

Zgodność jest bardzo istotna, ponieważ składniki programistyczne nie powstają w próżni.Muszą ze sobą współpracować. Jednak bardzo często mają z tym problemy, ponieważich twórcy poczynili sprzeczne założenia dotyczące świata zewnętrznego. Jednym z przy-

O przystoso-waniu dowielokrotnegoużycia piszęw rozdziale 4.

1.2. PRZEGLĄD CZYNNIKÓW ZEWNĘTRZNYCH 35

kładów tego typu sytuacji jest ogromna różnorodność niezgodnych ze sobą formatówplików, obsługiwanych przez różne systemy operacyjne. Każdy program komputerowymoże bezpośrednio przyjmować wyniki działania innego programu tylko wtedy, jeżeliformaty plików stosowane przez obie aplikacje są ze sobą zgodne.

Brak zgodności może odprowadzić do prawdziwej katastrofy. Oto skrajny przykład.

DALLAS. W zeszłym tygodniu AMR, spółka będąca właścicielem firmy AmericanAirlines, Inc., przyznała, że połamała zęby na próbie stworzenia doskonałego,uniwersalnego systemu rezerwacji lotów, który miał też umożliwiać rezerwowaniesamochodów i pokoi hotelowych.

AMR zaprzestała rozwijania swojego nowego systemu rezerwacji Confirm w parętygodni po upływie pierwotnego terminu oddania go do użytku, kiedy to miała ruszyćwspółpraca w zakresie obsługi rezerwacji z partnerami firmy: Budget Rent-A-Car,HiltonHotels Corp. oraz Marriott Corp. Zawieszenie czteroletniego projektu, którypochłonął 125 milionów dolarów, doprowadziło do zmniejszenia zysków netto firmyo 165 milionów dolarów i zrujnowało jej reputację lidera branży. […]

Już w styczniu kierownictwo projektu Confirm zdało sobie sprawę z tego, że wysiłkiponad 200 programistów, analityków systemowych i inżynierów poszły na marne.Najważniejsze elementy tego ogromnego projektu, których dokumentacja zajęła 47 000stron, były rozwijane niezależnie od siebie i w dodatku przy użyciu różnych technik.Po złożeniu ich w jedną całość okazało się, że mimo wysiłków programistów, nie chcąze sobą współpracować. Poszczególne „moduły” aplikacji nie dawały sobie radyz „wyciąganiem” potrzebnych im informacji z innych modułów.

Firma AMR Information Services zwolniła wtedy ośmiu głównych programistów,w tym kierownika projektu.[…] Pod koniec czerwca firmy Budget i Hilton ogłosiły,że wycofują się z projektu.

Kluczem do zgodności jest homogeniczność projektu i wypracowanie jednego stan-dardu przesyłania informacji wewnątrz aplikacji. W tym celu należy zastosować:

• standaryzowane formaty plików, tak jak w systemie operacyjnym Unix, w którymkażdy plik tekstowy jest po prostu sekwencją znaków,

• standaryzowane struktury danych, tak jak w programach napisanych w języku Lisp,w których wszystkie dane i programy są reprezentowane przez drzewa binarne,nazywane listami,

• standaryzowane interfejsy użytkownika, tak jak w różnych wersjach systemu Win-dows, OS/2 czy MacOS, w których wszystkie narzędzia komunikują się z użytkow-nikiem w taki sam sposób, oparty na wykorzystaniu standardowych komponentów,takich jak okna, ikony, menu itd.

Bardziej ogólne rozwiązania uzyskujemy, definiując standaryzowane protokołydostępu do wszystkich istotnych elementów, na których operuje oprogramowanie.Właśnie ta idea stoi za abstrakcyjnymi typami danych i podejściem obiektowym, a takżeza tak zwanymi protokołami warstwy pośredniczącej, takimi jak CORBA czy OLE-COM(ActiveX) Microsoftu.

San Jose(Kalifornia),MercuryNews,20 czerwca1992. Artykułcytowanyna grupiedyskusyjnej„comp.risks”,13.67,w czerwcu1992. Niektórefragmentypominąłem.

Informacjena temat abs-trakcyjnychtypów danychznajdzieszw rozdziale 6.

36 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

Wydajność

Definicja wydajnościWydajność to zdolność programu do stawiania komputerowi jak najmniejszychwymagań sprzętowych, rozumianych między innymi jako czas procesora, prze-strzeń zajmowana w pamięci wewnętrznej i zewnętrznej, szerokość pasma wyko-rzystywanego przy przesyłaniu danych itd.

Środowisko programistów wykazuje zazwyczaj dwa różne podejścia do problemu wy-dajności.

• Niektórzy programiści mają na tym punkcie obsesję, w związku z czym poświę-cają mnóstwo czasu na optymalizację kodu i wkładają w nią wiele wysiłku.

• Jednak istnieje również inna tendencja, przejawiająca się w mądrościach ludo-wych, takich jak „najpierw spraw, żeby to działało, a dopiero potem zajmij sięprzyspieszaniem”, czy „za rok komputery i tak będą o połowę szybsze”.

Często zdarza się, że ta sama osoba raz jest zwolennikiem pierwszej, a raz dru-giej teorii. To swego rodzaju programistyczne rozdwojenie jaźni (Dr Abstrakcja i MrMikrosekunda).

Które podeście jest lepsze? Cóż, programiści udowadniali już wielokrotnie, żekwestię optymalizacji kodu potrafią traktować przesadnie. Jak już wspomniałem, wy-dajność nie na wiele się zda, jeżeli oprogramowanie nie jest poprawne (to prowadzi dosformułowania kolejnej złotej zasady: „nie przejmuj się tym, czy program jest szybki,dopóki nie jest poprawny”, która przypomina poprzednią, ale nie do końca znaczy tosamo). Mówiąc bardziej ogólnie, musimy wprowadzić pewną równowagę międzypotrzebami w zakresie wydajności a pozostałymi celami, takimi jak rozszerzalność czyprzystosowanie do wielokrotnego użycia. Przesadne optymalizacje mogą uczynić apli-kację tak wyspecjalizowaną, że nie będzie się poddawała modyfikacjom, ani nada-wała do wielokrotnego wykorzystania. Ponadto stale rosnąca szybkość komputerówpozwala przyjąć bardziej luźne podejście do kwestii wydajności i zwalnia z walki o każdybajt i każdą mikrosekundę.

Jednak żaden z tych czynników nie umniejsza znaczenia wydajności. Nikt nielubi czekać na reakcję interaktywnych aplikacji ani dokupywać pamięci tylko po to,żeby w ogóle można było uruchomić dany program. Także luźne podejście do wydaj-ności często jest tylko pozą. Jeżeli końcowa wersja aplikacji jest tak wolna, że trudnoz niej normalnie korzystać, to nawet osoby twierdzące, że „szybkość nie ma znaczenia”,zaczynają narzekać.

Ta kwestia odzwierciedla coś, co — moim zdaniem — najlepiej charakteryzujeinżynierię oprogramowania (i myślę, że to się szybko nie zmieni). Tworzenie opro-gramowania jest trudne głównie dlatego, że wymaga brania pod uwagę wielu różnychczynników, z których jedne, takie jak poprawność, są abstrakcyjne i względne, a inne,takie jak wydajność, bardzo konkretne i związane z właściwościami konkretnegosprzętu komputerowego.

Dla niektórych naukowców tworzenie oprogramowania jest dziedziną matema-tyki. Dla innych jest to gałąź techniki. W rzeczywistości obie grupy mają rację. Pro-gramista musi pogodzić abstrakcyjne idee i założenia z niedoskonałymi możliwościamiich implementacji, a teorie matematyczne niezbędne do przeprowadzenia poprawnych

1.2. PRZEGLĄD CZYNNIKÓW ZEWNĘTRZNYCH 37

obliczeń z ograniczeniami czasowymi i przestrzennymi, wynikającymi z praw fizykii z niedoskonałości współczesnego sprzętu. Prawdopodobnie ta potrzeba zadowoleniazarówno wilków, jak i owiec, stanowi największe wyzwanie inżynierii oprogramowania.

Choć stale rosnąca szybkość komputerów robi duże wrażenie, nie można z jejpowodu zaniechać wysiłków na rzecz uzyskania wysokiej wydajności i to co najmniejz trzech powodów.

• Ktoś, to kupuje większy i szybszy komputer, chce w ten sposób osiągnąć jakieśkonkretne korzyści — mieć możliwość rozwiązywania nowych problemów bądźszybszego rozwiązywania dotychczasowych lub też rozwiązywania starych pro-blemów w takim samym czasie jak dawniej, tyle że rozpatrywanych w większejskali. Natomiast kupowanie nowego komputera po to, aby rozwiązywać stareproblemy w takim samym czasie co poprzednio, po prostu nie ma sensu!

• Jednym z najbardziej widocznych skutków zwiększania się szybkości komputerówjest wzrost przewagi dobrych algorytmów nad kiepskimi. Załóżmy, że nowy kom-puter jest dwa razy szybszy od starego. Niech n określa rozmiary problemu, którynależy rozwiązać, zaś N będzie maksymalnym n, jakie dany algorytm jest w sta-nie obsłużyć w danym czasie. Jeżeli algorytm ma złożoność O(n), to znaczy wy-konuje się w czasie proporcjonalnym do n, to wówczas nowy komputer pozwolirozwiązać problem o rozmiarze 2∗N (dla dużego N). W przypadku algorytmóww postaci O(n2) nowy komputer pozwoli zwiększyć N jedynie o 41%. Natomiastalgorytm typu O(2n), taki jak pewne algorytmy wyszukiwania, zwiększy N jedy-nie o jeden. Nie za dużo, jak na wydane pieniądze.

• W niektórych sytuacjach wydajność może wpływać na poprawność. W specyfi-kacji może być na przykład napisane, że komputer musi zareagować na określonezdarzenie nie później niż po upływie określonego czasu. Na przykład komputerpokładowy w samolocie musi być przygotowany na wykrycie i przetworzeniekomunikatu od czujnika przepustnicy w czasie na tyle krótkim, aby było możli-we przeprowadzenie ewentualnej korekty lotu. Takie powiązanie między wydaj-nością a poprawnością nie jest ograniczone jedynie do programów, które potocz-nie nazywa się aplikacjami czasu rzeczywistego. Mało kto uświadamia sobie, żez podobną sytuacją mamy do czynienia w programach przewidujących pogodęna następny dzień, które analizują na bieżąco dane napływające przez 24 godziny.

Inna przykładowa sytuacja, która może nie stanowiła wielkiego problemu, ale straszniemnie denerwowała. Używałem kiedyś systemu zarządzania oknami, który był na tylewolny, że zdarzało mu się nie zarejestrować przesunięcia kursora myszy z jednego oknado drugiego. W rezultacie znaki wpisywane przeze mnie na klawiaturze nie trafiałydo tego okna, do którego powinny.

W tym przypadku ograniczenia wydajności powodują naruszenie specyfikacji, a konkretniewpływają na poprawność, a to nawet w niewinnych, używanych na co dzień aplikacjachmoże mieć niemiłe konsekwencje. Pomyśl, co mogłoby się stać, gdyby dwa otwarte naekranie okna, o których wspomniałem, były oknami nowych wiadomości pocztowych,skierowanych do dwóch różnych odbiorców. Wojny wybuchały już z dużo bardziejbłahych powodów.

Ponieważ w tej książce skupiam się na założeniach inżynierii obiektowej, a niena kwestiach implementacyjnych, tylko w kilku podrozdziałach piszę wprost o kosztachw zakresie wydajności aplikacji. Musisz jednak pamiętać, że problem istnieje i że jestem

38 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

jego świadomy. Za każdym razem gdy omawiam przykładowe obiektowe rozwiązaniejakiegoś problemu, możesz być pewien, że przemyślałem je tak, aby było nie tylkoeleganckie, ale też wydajne. Zawsze gdy wprowadzam jakiś nowy mechanizm obiek-towy, taki jak odzyskiwanie pamięci (i inne techniki zarządzania pamięcią w aplika-cjach obiektowych), wiązanie dynamiczne, generyczność czy wielokrotne dziedziczenie,pamiętam o tym, że musi on być zaimplementowany w taki sposób, aby był wydajnypod względem czasu i wymaganej przestrzeni. Dlatego tam, gdzie uznam to za przy-datne, będę wspominał o wpływie przyjętego podejścia na wydajność.

Wydajność jest tylko jednym z czynników składających się na jakość. Dlatego niepowinniśmy (jak niektórzy nasi koledzy po fachu) dopuszczać do tego, żeby kierowałanaszymi działaniami. Niemniej jednak należy o niej pamiętać, zarówno przy tworzeniukonkretnej aplikacji, jak i na etapie projektowania nowego języka programowania.Jeżeli powiesz wydajności: „Do widzenia”, wydajność to samo powie Tobie.

Przenośność

Definicja przenośnościPrzenośność to łatwość, z jaką dane oprogramowanie daje się przenosić międzyróżnymi środowiskami sprzętowymi i programowymi.

Tak więc przenośność nie odnosi się jedynie do różnic między fizycznymi urządzeniamisprzętowymi, ale do bardziej ogólnej, sprzętowo-programowej natury komputera.Tej, z którą mamy styczność, pisząc aplikacje, a więc między innymi do systemu ope-racyjnego, systemu okien (jeśli jest on stosowany) i innych podstawowych narzędzi.W dalszej części książki tego rodzaju urządzenie sprzętowo-programowe nazywaćbędziemy „platformą”. Przykładem platformy jest na przykład „komputer z proceso-rem Intel X86, pracujący pod kontrolą Windows NT”, w skrócie „Wintel”.

Wiele obecnych niezgodności między różnymi platformami wydaje się nie miećsensownego usprawiedliwienia. Naiwny obserwator mógłby nawet stwierdzić, że z pew-nością chodzi o spisek przeciwko ludzkości, a w szczególności przeciw programistom.W każdym razie, niezależnie od przyczyn takiego stanu rzeczy, różnorodność sprawia,że przenośność oprogramowania jest wielkim problemem zarówno dla programistów,jak i użytkowników.

Łatwość obsługi

Definicja łatwości obsługiŁatwość obsługi to łatwość, z jaką ludzie o różnym doświadczeniu i kwalifikacjachmogą nauczyć się korzystania z aplikacji i stosowania ich do rozwiązywania pro-blemów. Termin ten obejmuje też łatwość instalacji i nadzorowania pracy systemu.

1.2. PRZEGLĄD CZYNNIKÓW ZEWNĘTRZNYCH 39

W definicji tej położono nacisk na zróżnicowanie poziomu umiejętności potencjalnychużytkowników. Stanowi to jedno z największych wyzwań dla projektantów aplikacjizajmujących się kwestiami łatwości obsługi. W jaki sposób zapewnić odpowiednią po-moc początkującym i wszystko im wyjaśnić, a przy tym nie zanudzić doświadczonychużytkowników, którzy od razu chcą zabrać się do pracy?

Podobnie jak w przypadku wielu innych czynników opisywanych w tym roz-dziale, jednym z kluczy do osiągnięcia łatwości obsługi jest zastosowanie prostej strukturyprogramu. Dobrze zaprojektowany system, zbudowany w oparciu o przejrzystą, prze-myślaną strukturę, będzie łatwiejszy do poznania niż program, w którym panuje dużybałagan. Oczywiście nie jest to warunek wystarczający (to, co może być proste i jasnedla projektanta, użytkownikom może wydawać się dziwne i trudne, zwłaszcza jeśli zo-stanie opisane językiem, jakim posługują się projektanci, a nie użytkownicy), ale za-stosowanie się do niego bardzo pomaga.

Jest to jeden z obszarów, w których technika obiektowa jest szczególnie przy-datna. Pewne metody, które na pierwszy rzut oka wydają się dotyczyć zagadnieńprojektowych i implementacyjnych, pozwalają też stworzyć nowego rodzaju interfejsyużytkownika, które ułatwiają obsługę aplikacji. W następnych rozdziałach podam wielekonkretnych przykładów.

Projektanci oprogramowania zajmujący się zagadnieniem łatwości obsługi po-winni ostrożnie podchodzić do sloganu najczęściej cytowanego w literaturze fachowej,pochodzącego ze starego artykułu Hansena, który brzmi: „Poznaj użytkownika”. Stoiza nim argument, że dobry projektant powinien poświęcić czas na poznanie docelowejspołeczności użytkowników programu. Jednak takie podeście nie uwzględnia jednejz charakterystycznych cech programów, które odnoszą rynkowy sukces. Po jakimśczasie są one wykorzystywane przez szerszą grupę użytkowników, niż pierwotnie są-dzono. (Dwoma dobrymi przykładami są tu Fortran, który miał być początkowo na-rzędziem służącym do rozwiązywania problemów, jakie napotkała mała grupa na-ukowców i inżynierów zajmujących się pisaniem programów na komputer IBM 704,oraz system operacyjny Unix, który pierwotnie miał służyć jedynie do wewnętrznychzastosowań w firmie Bell Laboratories). Każdy system zaprojektowany z myślą o specy-ficznej grupie użytkowników będzie oparty na założeniach, które po prostu przestanąbyć adekwatne dla szerszego grona odbiorców.

Dlatego dobrzy projektanci interfejsów użytkownika trzymają się bardziej ostroż-nej zasady. Czynią oni tak mało założeń dotyczących przyszłych użytkowników, jakto możliwe. Projektując interaktywny program komputerowy, możesz oczekiwać, żejego użytkownicy będą przedstawicielami rasy ludzkiej i będą potrafili czytać, poru-szać myszą, klikać przycisk i pisać (powoli), nic ponadto. Jeżeli aplikacja ma służyćdo rozwiązywania problemów z jakiejś konkretnej dziedziny, można też pewnie zało-żyć, że jej użytkownicy będą mieli choć podstawową wiedzę w tym zakresie. Ale nawettakie założenie jest już ryzykowne. Parafrazując radę Hansena, mogę sformułowaćzasadę projektowania interfejsu użytkownika.

Zasada projektowania interfejsu użytkownikaNie udawaj, że znasz użytkownika. Nie znasz.

Patrz WilfredJ.Hansen,„User Engi-neeringPrinciples forInteractiveSystems”,Sprawozdaniez FJCC 39,AFIPS Press,Montvale(NJ), 1971,s. 523 – 532.

40 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

Funkcjonalność

Definicja funkcjonalnościFunkcjonalność to zbiór możliwości oferowanych przez system.

Jednym z największych problemów, przed jakimi stają szefowie projektów, jest okre-ślenie, jak duża funkcjonalność jest już wystarczająca. W przemyśle programistycz-nym stale odczuwa się nacisk na dodawanie do programów kolejnych możliwości, copowszechnie nazywane jest pogonią za wodotryskami. Jej konsekwencje są złe już dlawewnętrznych projektów, w których naciski pochodzą ze strony pracowników tej samejfirmy, a w przypadku produktów komercyjnych jeszcze gorsze. Niestety większość pismkomputerowych przy sporządzaniu recenzji kilku konkurencyjnych produktów zazwy-czaj skupia się jedynie na przedstawieniu tabeli, w której porównuje się ich możliwości.

Pogoń za możliwościami to właściwie dwa oddzielne problemy, z których jedenjest trudniejszy do rozwiązania. Prostszy problem polega na tym, że, dodając nowe funk-cje, możemy utracić spójność, co odbije się na łatwości obsługi. Użytkownicy częstonarzekają, że wszystkie te „wodotryski” dodawane do kolejnych wersji znanych pro-gramów czynią je jedynie niesamowicie złożonymi. Tego rodzaju uwagi trzeba jednaktraktować z przymrużeniem oka, ponieważ nowe funkcje nie biorą się z próżni. Zwykleproszą o nie użytkownicy, tyle że niekoniecznie ci sami. To, co mnie wydaje się świet-nym ułatwieniem, dla Ciebie może być tylko nieprzydatnym gadżetem.

Jedynym rozwiązaniem jest tu stała praca nad zachowaniem spójności całegoprogramu i podejmowanie prób wciśnięcia wszystkich funkcji w już wyznaczone ramy.Każdy dobry program opiera się na kilku nowatorskich pomysłach. Jeśli nawet ma onwiele funkcji, powinny one wynikać z podstawowych założeń. W konstrukcji pro-gramu musi być widoczny jakiś konkretny plan, w którym każdy element ma swojemiejsce.

Trudniejszy problem polega na tym, iż można tak bardzo zaangażować się w do-dawanie nowych funkcji, że zapomni się o innych czynnikach. Jest to powszechniepopełniany błąd, zobrazowany przez Rogera Osmonda na wykresie w postaci dwóchmożliwych ścieżek prowadzących do ukończenia projektu (patrz rysunek 1.4).

RYSUNEK 1.4.Krzywe Osmonda,za [Osmond 1995]

1.2. PRZEGLĄD CZYNNIKÓW ZEWNĘTRZNYCH 41

W życiu sytuacja wygląda najczęściej tak, jak pokazuje to dolna (czarna) krzywa.W szaleńczym wyścigu za dodawaniem nowych funkcji programiści zapominają o ogól-nej jakości programu. Ostatnia faza projektu, w której wszystko powinno być już do-prowadzone do porządku, potrafi być długa i stresująca. Jeżeli pod wpływem presjiużytkowników lub konkurencji jesteś zmuszony do wypuszczenia programu we wcze-snej fazie produkcji, na jednym z etapów oznaczonych na wykresie czarnymi kwa-dratami, pamiętaj, że może to zaszkodzić Twojej reputacji.

Osmond sugeruje (krzywa linią przerywaną), abyś — korzystając z możliwości,jakie daje programowanie zorientowane obiektowo — utrzymywał ogólną jakośćprogramu (poza funkcjonalnością) przez cały czas na takim samym poziomie. Chodziwięc o to, abyś nigdy nie oszczędzał na niezawodności, rozszerzalności itp. Nie wolnoCi dodawać nowych funkcji, dopóki te, które już masz, będą działać, tak jak trzeba.

Takie podejście jest trudniejsze do stosowania na co dzień ze względu na wspo-mniane naciski, ale prowadzi do wydajniejszego procesu tworzenia aplikacji, a częstotakże do uzyskania w ostatecznym rozrachunku lepszego produktu. Jeśli nawet koń-cowe rezultaty są w obu przypadkach takie same, tak jak na przytoczonym wykresie,to postępując zgodnie z podanymi zasadami, powinniśmy uzyskać je szybciej (wykresnie uwzględnia czasu). Gdy trzymamy się sugerowanej ścieżki rozwoju projektu,ewentualne wypuszczenie wczesnej wersji programu (na jednym z etapów oznaczo-nych ukośnie kreskowanymi kwadratami) jest znacznie łatwiejsze. Trzeba jedynieodpowiedzieć sobie na pytanie, czy zakres funkcjonalności, który został już zaim-plementowany w programie, jest wystarczająco szeroki, aby przyciągnąć do niegoklientów i nie zrazić niektórych z nich. Natomiast nie musimy już zastanawiać się„czy to jest wystarczająco dobre”.

Każdy czytelnik, który miał już okazję kierować jakimś projektem programi-stycznym, przyzna, że dużo łatwiej dawać takie rady, niż je stosować. Niemniej jednakw przypadku każdego projektu powinno się dążyć do ideału reprezentowanego przezwyższą krzywą Osmonda. Doskonale współgra on z modelem klastrowym wprowa-dzonym w jednym z kolejnych rozdziałów i będącym jednym ze schematów prowa-dzenia projektu programistycznego.

Adekwatność czasowa

Definicja adekwatności czasowejAdekwatność czasowa to gotowość programu komputerowego do wypuszczenia na ry-nek wtedy, gdy użytkownicy go potrzebują, lub jeszcze zanim pojawi się taka potrzeba.

W przemyśle programistycznym jednym z najbardziej stresujących czynników jestadekwatność czasowa. Doskonały produkt, który pojawi się na rynku za późno, możeokazać się całkowitą klapą. Oczywiście tak samo jest też w innych gałęziach przemysłu,ale niewiele z nich podlega tak szybkim zmianom.

Adekwatność czasowa jest czymś rzadko spotykanym, nawet w przypadku du-żych projektów programistycznych. Gdy Microsoft ogłosił, że najnowsza wersja jegosztandarowego systemu operacyjnego, tworzonego przez wiele lat, zostanie wypusz-czona na rynek o miesiąc wcześniej, niż zakładano, uznano to za tak sensacyjną wia-domość, że zamieszczono ją na okładce magazynu ComputerWorld (wraz z komenta-rzem na temat długich opóźnień, które zdarzały się tej firmie w przeszłości).

„NT 4.0 Beat-sClock”, Com-puter-World,nr 30, 22czerwca 1996.

42 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

Inne czynniki

Poza już omówionymi czynnikami decydującymi o jakości, istnieją też inne, mającewpływ na użytkowników, decydentów zamawiających systemy komputerowe i pro-gramistów. Oto niektóre z nich.

• Weryfikowalność, czyli łatwość przygotowywania procedur pozwalających okre-ślić, czy produkt znajduje się na akceptowalnym poziomie. W szczególności chodzitu o dane testowe i procedury pozwalające na wykrywanie niepowodzeń i odnaj-dywanie tych błędów popełnionych na etapie walidacji danych i w fazie operacyjnej,które są przyczyną niepowodzeń.

• Integralność, czyli zdolność oprogramowania do chronienia swoich składników(programów, danych) przed nieautoryzowanym dostępem i modyfikacjami.

• Naprawialność, czyli udostępnianie możliwości naprawiania defektów.• Ekonomiczność, będąca uzupełnieniem adekwatności czasowej, czyli zdolność

systemu do zmieszczenia się w założonym budżecie.

Dokumentacja

Analizując listę czynników decydujących o jakości, możesz dojść do wniosku, że jednymz wymagań powinna być dobra dokumentacja. Jednak nie jest to odrębny składnik.Potrzeba takiej dokumentacji wynika z pozostałych czynników, które już omówiłem.Możemy wyróżnić trzy rodzaje dokumentacji.

• Dokumentacja zewnętrzna, dzięki której użytkownicy mogą zrozumieć możliwo-ści systemu i wygodnie z nich korzystać. Jest to konsekwencja wymagania zde-finiowanego jako łatwość obsługi.

• Dokumentacja wewnętrzna, która pozwala zrozumieć strukturę i implementacjęsystemu programistom. Jest to konsekwencja wymagania zdefiniowanego jakorozszerzalność.

• Dokumentacja interfejsów poszczególnych modułów, dzięki której programiścimogą zrozumieć działanie funkcji dostarczanych przez dany moduł bez potrzebyzagłębiania się w jego implementację. Jest to konsekwencja wymagania zdefi-niowanego jako przystosowanie do wielokrotnego użycia. Wynika ona równieżz rozszerzalności, ponieważ dokumentacja interfejsów modułów pozwala określić,czy dana zmiana będzie miała wpływ na konkretny moduł.

Dlatego, zamiast traktować dokumentację jako osobny produkt, lepiej pisać mak-symalnie samodokumentujący się kod. Zasada ta odnosi się do wszystkich trzech ro-dzajów dokumentacji.

• Uwzględniając w programie podsystem pomocy ekranowej, a także trzymając sięjasnych i spójnych konwencji przy tworzeniu interfejsu użytkownika, ułatwiamyzadanie autorom podręczników użytkownika i innych materiałów dydaktycznych.

1.2. PRZEGLĄD CZYNNIKÓW ZEWNĘTRZNYCH 43

• Zaimplementowanie programu w dobrym języku programowania zlikwiduje w dużejmierze konieczność tworzenia wewnętrznej dokumentacji, jeśli tylko język tenbędzie sprzyjał organizacji i przejrzystości kodu. Są to jedne z najważniejszychczynników wpływających na wygląd notacji obiektowej, którą będę wprowadzałw tej książce.

• Notacja ta będzie obsługiwała ukrywanie informacji i inne techniki (takie jak aser-cje) pozwalające oddzielić interfejsy modułów od ich implementacji. Pozwoli tozastosować narzędzia, które automatycznie wygenerują dokumentację interfej-sów modułów na podstawie ich kodów źródłowych. Tym zagadnieniem równieżzajmiemy się dokładnie w dalszych rozdziałach.

Wszystkie te techniki ograniczają znaczenie tradycyjnej dokumentacji, ale oczywi-ście nie możemy od nich oczekiwać, aby całkowicie ją zastąpiły.

KompromisyW tym przeglądzie zewnętrznych czynników składających się na jakość oprogramo-wania pojawiły się już wymagania, które kłócą się z innymi.

Czy jest możliwe osiągnięcie integralności bez wprowadzania żadnych zabezpieczeń?Z kolei wprowadzenie ich musi się negatywnie odbić na łatwości obsługi. Ekonomicz-ność często wydaje się stać w sprzeczności z funkcjonalnością. Uzyskanie optymalnejwydajności wymagałoby perfekcyjnego wykorzystania możliwości oferowanych przezdane środowisko sprzętowe i programowe, co kłóci się z przenośnością. Z jednej strony,mówi się nam, żebyśmy trzymali się ściśle specyfikacji, a z drugiej, popycha się nasw kierunku tworzenia ogólnych rozwiązań, które nadawałyby się do wielokrotnegoużycia. Naciski na adekwatność czasową mogą skłaniać ku środowiskom szybkiegotworzenia aplikacji (RAD), przy których mamy mocno ograniczoną rozszerzalność.

Choć w wielu przypadkach daje się znaleźć rozwiązanie pozwalające pogodzićze sobą sprzeczne wymagania, czasami trzeba poświęcić pewne czynniki na rzeczdrugich. Niestety zbyt często programiści robią to niejawnie, nie zastanowiwszy sięwcześniej nad wszystkimi dostępnymi możliwościami i ich konsekwencjami. W re-zultacie najczęściej skupiają się na wydajności. Natomiast prawdziwy inżynier oprogra-mowania powinien zadać sobie trud jawnego sformułowania kryteriów, którymi będzieposługiwał się przy wyborze, i podjąć w pełni świadome decyzje.

Choć między czynnikami decydującymi o jakości trzeba często dokonywać wy-borów, nie wolno nigdy zapomnieć, że najważniejszym z nich jest poprawność. Nicnie usprawiedliwia zaniedbania poprawności na rzecz innych czynników, na przykładtakich jak wydajność. Jeżeli oprogramowanie nie spełnia swojej roli, to reszta nie maznaczenia.

Kluczowe zagadnieniaWszystkie opisywane dotychczas czynniki są ważne. Ale w obecnym stanie przemy-słu programistycznego cztery z nich wydają się mieć szczególne znaczenie. Są to:

44 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

• Poprawność i odporność. W dalszym ciągu tworzenie oprogramowania pozba-wionego defektów jest zbyt trudne, podobnie jak usuwanie błędów, gdy już udasię je zlokalizować. Wszystkie techniki służące zwiększaniu poprawności i od-porności opierają się na tych samych pomysłach — zastosowaniu bardziej usys-tematyzowanego podejścia do tworzenia oprogramowania, stosowaniu bardziejformalnych specyfikacji, użyciu wbudowanych mechanizmów kontrolnych jużna etapie tworzenia oprogramowania (a nie bazowanie jedynie na testowaniu i usu-waniu błędów już po zakończeniu projektu), wykorzystanie lepszych mechani-zmów językowych, takich jak statyczna kontrola typów, asercje, automatycznezarządzanie pamięcią czy zdyscyplinowana obsługa wyjątków, które pozwalająprogramistom spełniać wymagania dotyczące poprawności i odporności, a na-rzędziom programistycznym wykrywać wszelkie niespójności, zanim doprowadząone do powstania defektów. Ze względu na tak bliskie powiązanie poprawnościz odpornością, wygodniej stosować bardziej ogólny termin — obejmujący swymznaczeniem oba te czynniki — niezawodność.

• Rozszerzalność i przystosowanie do wielokrotnego użycia. Oprogramowanie po-winno dawać się łatwiej modyfikować. Tworzone przez nas komponenty pro-gramistyczne powinny stwarzać możliwość zastosowania w większej liczbie sytu-acji. Powinno ich też być więcej. Również w przypadku tych dwóch czynnikówźródłem usprawnień są te same pomysły. Ogólnie można by rzec, że pomocne sąwszystkie techniki, które przyczyniają się do tworzenia bardziej zdecentralizo-wanych architektur, w których komponenty mają budowę zamkniętą i komunikująsię ze sobą jedynie za pomocą ograniczonych i ściśle zdefiniowanych kanałów.Rozszerzalność i przystosowanie do wielokrotnego użycia będziemy określaliwspólnym terminem modułowości.

Technika obiektowa, z którą zapoznasz się dokładnie w kolejnych rozdziałach,pozwala wyraźnie ulepszyć te cztery czynniki decydujące o jakości, co czyni ją takatrakcyjną. Przyczynia się ona również w znacznym stopniu do spełnienia pozostałychwymagań, szczególnie takich jak:

• Zgodność. Technika obiektowa sprzyja stosowaniu jednolitego stylu projektowa-nia i tworzeniu standaryzowanych modułów i interfejsów, co z kolei pomaga two-rzyć systemy, które mają ze sobą współpracować.

• Przenośność. Kładąc nacisk na abstrakcyjność i ukrywanie informacji, technikaobiektowa zachęca projektantów do rozróżniania specyfikacji i implementacji,co ułatwia przenoszenie aplikacji na różne platformy. Techniki, takie jak polimor-fizm i wiązanie dynamiczne, pozwalają nawet tworzyć systemy, które automatyczniedostosowują się do zastanych komponentów platformy sprzętowo-programowej, naprzykład do różnych systemów zarządzania oknami czy bazami danych.

• Łatwość obsługi. Wpływ, jaki narzędzia obiektowe wywarły na współczesne in-teraktywne programy komputerowe, a w szczególności na ich interfejsy użyt-kownika, jest powszechnie znany. Czasami przypisuje się temu nawet większeznaczenie, niż by wypadało (twórcy reklam nie są jedynymi osobami, które każ-dy program, w jakim są ikony i okna, obsługiwany za pomocą myszy, nazywająobiektowym).

• Wydajność. Jak już wspomniałem, mimo iż z zakupem szybkiego komputera i zestosowaniem technik obiektowych wiąże się pewien koszt, możliwość wykorzy-stywania w procesie tworzenia oprogramowania profesjonalnych komponentówwielokrotnego użytku pozwala znacznie zyskać na wydajności.

1.3. KONSERWACJA OPROGRAMOWANIA 45

• Adekwatność czasowa, ekonomiczność i funkcjonalność. Techniki obiektowe po-zwalają tym, którzy opanują je do perfekcji, tworzyć programy szybciej i przymniejszych kosztach. Ułatwiają one dodawanie nowych funkcji, a czasem wręczsugerują, jakie możliwości przydałoby się jeszcze wprowadzić.

Mimo oczywistego postępu, jaki niosą ze sobą techniki obiektowe, powinniśmypamiętać, że nie stanowią one panaceum i że w dalszym ciągu musimy rozwiązywaćwiele klasycznych problemów inżynierii programowania. To, że coś nam w tym pomaga,nie oznacza jeszcze, że rozwiąże to problem za nas.

1.3. KONSERWACJA OPROGRAMOWANIA

Być może zauważyłeś, że nie wymieniłem dotąd często wspominanego czynnika de-cydującego o jakości, jakim jest łatwość konserwacji. Aby zrozumieć, dlaczego takpostąpiłem, musisz przyjrzeć się bliżej temu, czym właściwie jest konserwacja opro-gramowania.

Terminem konserwacja określamy wszystko, co robi się już po przekazaniu pro-gramu odbiorcom. Wszystkie dyskusje na temat metodyki tworzenia oprogramowaniaz reguły skupiają się jedynie na programowaniu. Podobne podejście obserwuje się nakursach programowania dla początkujących. Tymczasem powszechnie wiadomo, że70% kosztów tworzenia oprogramowania pochłania właśnie jego konserwacja. Żadneomówienie zagadnienia jakości oprogramowania nie jest wystarczające, jeżeli pomijasię w nim ten aspekt.

Zatem co rozumiemy przez „konserwację” w odniesieniu do oprogramowania?Programy komputerowe nie zużywają się od ciągłego korzystania, a tym samym nietrzeba ich „konserwować”, tak jak samochodów czy telewizorów. Można by więc rzec,że jest to dość nietrafione określenie. Tym bardziej, że odnosi się ono zarówno do bar-dziej, jak i do mniej chwalebnych zajęć. Do pierwszej grupy zaliczyć można wszelkiemodyfikacje. Wiadomo, że specyfikacje systemów komputerowych zmieniają się poto, aby odzwierciedlać zmiany zachodzące w świecie zewnętrznym. Pociąga to za so-bą konieczność modyfikowania samych programów. Natomiast do drugiej grupy zali-czamy czynności służące do lokalizowania i usuwania błędów, których na tym etapieprojektu w ogóle nie powinno już być.

Wykres przedstawiony na rysunku 1.5, pochodzący z pamiętnego opracowaniaLientza i Swansona, pokazuje już bardziej konkretnie, jakie zagadnienia mieszczą siępod pojęciem konserwacji. Autorzy przepytali 487 zespołów programistycznych roz-wijających aplikacje różnych typów. Mimo iż badanie odbyło się już jakiś czas temu,wyniki najnowszych ankiet potwierdzają ich odkrycia. Wykres pokazuje, jaka częśćkosztów konserwacji oprogramowania przypada na poszczególne zagadnienia, wyod-rębnione przez autorów.

Ponad dwie piąte kosztów przeznaczane jest na rozbudowywanie i modyfikowa-nie aplikacji na życzenie użytkowników. Są to czynności, których praktycznie nie dasię uniknąć. Natomiast bez odpowiedzi pozostaje pytanie, ilu spośród tych wysiłkówmożna by uniknąć, gdyby oprogramowanie było od początku projektowane z myśląo rozszerzalności. Mamy pełne podstawy sądzić, że technika obiektowa pozwoli po-prawić tę sytuację.

46 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

RYSUNEK 1.5.Koszty konserwacjioprogramowania.Źródło: [Lientz 1980]

Szczególnie interesująca jest druga pozycja — zmiany w formatach danych. Gdyzmienia się fizyczna struktura plików i innych elementów przechowujących dane, trze-ba zaadaptować do tych zmian istniejące aplikacje. Gdy na przykład poczta w StanachZjednoczonych przydzieliła parę lat temu dużym firmom kody pocztowe w postaci„5+4” (złożone z dziewięciu znaków zamiast pięciu), trzeba było przepisać od nowawiele programów, które „wiedziały”, że kody pocztowe składają się dokładnie z pięciuznaków. Prasa oszacowała, że kosztowało to kilkaset milionów dolarów.

Zapewne wielu czytelników otrzymało swego czasu piękne zaproszenia na cykl konferencji(nie jedną czy dwie, ale cały cykl, prowadzony w wielu miastach) poświęconych„problemowi roku 2000”. Mówiono na nich, w jaki sposób unowocześnić wieleprogramów służących do przechowywania bardzo istotnych danych, których autorzynawet przez chwilę nie pomyśleli, że po upływie XX wieku również trzeba będzie jakośwprowadzać daty. W porównaniu z tym problem kodów pocztowych wydaje się błahostką.Jorge Luis Borges stwierdził, że skoro dziś mało kto zastanawia się, co stanie się 1 stycznia3000 roku, to prawdopodobnie możemy uznać, że był to jedyny cykl konferencjiw historii ludzkości poświęcony tak niepozornemu tematowi — jednej dziesiętnej cyfrze.

Nie chodzi o to, że jakaś część programu zna fizyczną strukturę danych. To jestakurat nieuniknione, ponieważ w pewnym momencie program musi mieć dostęp dodanych po to, aby mógł przeprowadzić na nich jakieś operacje. Jednak w tradycyj-nych technikach projektowania ta wiedza jest dostępna w zbyt wielu częściach syste-mu, przez co po zmianie fizycznej struktury danych (a to zawsze kiedyś następuje)trzeba modyfikować wiele fragmentów programu, a wcale nie musi tak być. Innymi sło-wy, jeżeli kody pocztowe zostaną wydłużone z pięciu do dziewięciu znaków, a datyzaczną wymagać stosowania dodatkowej cyfry, będzie można mieć uzasadnione po-dejrzenia, że należy zaadaptować do tych zmian programy operujące na tych wielko-ściach. Natomiast nie do zaakceptowania jest sytuacja, w której informacje na tematdokładnej długości danych są umieszczone w bardzo wielu miejscach w programie, także zmiana tej długości pociąga za sobą konieczność modyfikowania niewspółmierniewielu fragmentów kodu.

Inny przykładznajdzieszw podroz-dziale:„Jak długijest środkowyinicjał?”, nastronie 167.

1.4. KLUCZOWE POJĘCIA WPROWADZONE W TYM ROZDZIALE 47

Rozwiązaniem tego problemu są abstrakcyjne typy danych, dzięki którym pro-gramy mogą odwoływać się do danych za pośrednictwem swych zewnętrznych wła-ściwości, a nie fizycznych implementacji.

Kolejną ciekawą rzeczą dającą się zaobserwować na wykresie jest niski udział re-dagowania dokumentacji w całkowitych kosztach konserwacji (5,5%). Pamiętaj, żemówimy tu jedynie o kosztach czynności konserwacyjnych. Ponieważ na ten tematnie mamy bardziej precyzyjnych danych, możemy jedynie spekulować, iż wynika toz tego, że albo dokumentacja tworzona jest na etapie rozwijania kodu, albo nie piszesię jej wcale. W dalszej części książki poznasz styl projektowania, dzięki któremu większaczęść dokumentacji trafia bezpośrednio do kodu źródłowego. Powiem też o specjalnychnarzędziach, które pozwalają ją stamtąd wydobyć.

Kolejne pozycje na liście Lientza i Swansona również są bardzo interesujące, choćnie są, tak jak pozostałe, bezpośrednio związane z zagadnieniami poruszanymi w tejksiążce. Awaryjne poprawki błędów (opracowywane w pośpiechu po tym, jak któryśz użytkowników zgłosi, że program nie zwraca oczekiwanych wyników lub zachowujesię w nieprawidłowy sposób) kosztują więcej niż rutynowe, zaplanowane poprawki.Wynika to nie tylko z tego, że wymagają one pracy pod dużą presją, ale również z tego,że konieczność ich przygotowania zmienia ustalony harmonogram wypuszczania no-wych wersji programu, a w dodatku może prowadzić do wprowadzenia nowych błędów.Ostatnie dwie czynności mają niewielki udział w kosztach.

• Pierwszą z nich jest zwiększanie wydajności. Wykres zdaje się sugerować, że gdysystem już działa, szef projektu i programiści nie chcą go ruszać, żeby go nie ze-psuć, nawet jeśli potencjalnie mogliby zwiększyć jego wydajność. Gdy przy-pomnimy sobie zasadę: „najpierw spraw, żeby to działało, a dopiero potem zajmijsię przyspieszaniem”, dojdziemy do wniosku, że widocznie większość projektówzatrzymuje się na tej pierwszej czynności.

• Podobnie niski udział w kosztach ma również „przenoszenie do nowych środo-wisk”. Można to interpretować w ten sposób (podobnie jak poprzednio nie mamybardziej szczegółowych danych), że pod względem przenośności programy dzieląsię zasadniczo na dwie kategorie, a między nimi właściwie nic nie ma, czyli naprogramy, które od początku były projektowane z myślą o przenośności, gdzieprzeprowadzenie takiej operacji nie jest zbyt kosztowne, oraz programy tak mocnoprzywiązane do swoich pierwotnych platform, że przeniesienie ich na inne byłobytak trudne, iż programiści nawet nie próbują tego robić.

1.4. KLUCZOWE POJĘCIAWPROWADZONE W TYM ROZDZIALE

• Zadaniem inżynierii oprogramowania jest opracowywanie sposobów tworzeniawysokich jakościowo programów komputerowych.

• Jakość oprogramowania nie jest pojedynczą wielkością. Należy ją raczej rozpa-trywać jako sumę wielu różnych czynników, które w każdym programie występująw nieco innych proporcjach.

Szczegółoweomówienieabstrakcyjnychtypów danychznajdzieszw rozdziale 6.

48 ROZDZIAŁ 1. JAKOŚĆ OPROGRAMOWANIA

• Należy odróżniać zewnętrzne czynniki składające się na jakość, czyli te dostrze-gane przez użytkowników i klientów, od czynników wewnętrznych, widocznychjedynie dla projektantów i implementatorów.

• Liczą się jedynie czynniki zewnętrzne, ale do ich uzyskania niezbędne są odpo-wiednie czynniki wewnętrzne.

• Przedstawiłem listę najważniejszych czynników zewnętrznych decydujących o ja-kości aplikacji. Te z nich, które najwięcej zyskałyby na wprowadzeniu nowychtechnik i do których bezpośrednio odnosi się metoda obiektowa, to czynniki zwią-zane z bezpieczeństwem (poprawność i odporność), określane wspólnie mianemniezawodności, oraz czynniki wymagające stosowania zdecentralizowanych ar-chitektur oprogramowania (przystosowanie do wielokrotnego użycia i rozszerzal-ność), określane mianem modułowości.

• Konserwacja oprogramowania, na którą przypada większa część kosztów pro-jektu, jest trudna ze względu na fakt, że niełatwo implementuje się zmiany w ist-niejących programach, oraz z powodu nadmiernego uzależnienia programów odfizycznej struktury danych, na których one operują.

1.5. BIBLIOGRAFIA

Próbę zdefiniowania jakości oprogramowania podjęło już wielu autorów. Spośródpierwszych opracowań na ten temat dwa pozostają wciąż zaskakująco aktualne: arty-kuł [Hoare 1972] oraz [Boehm 1978] — wyniki pierwszych usystematyzowanych ba-dań na temat tworzenia oprogramowania, prowadzonych przez ludzi z TRW.

Rozróżnienie między czynnikami zewnętrznymi a wewnętrznymi zostało wpro-wadzone w materiałach przekazanych w 1977 roku lotnictwu Stanów Zjednoczonychprzez firmę General Electric [McCall 1977]. To, co my nazywamy czynnikami ze-wnętrznymi, McCall określa po prostu mianem „czynników”, zaś na czynniki we-wnętrzne mówi „kryteria”. Wiele (choć nie wszystkie) spośród opisanych przeze mnieczynników stanowi bezpośrednie odpowiedniki czynników McCalla. Jeden z jegoczynników pominąłem (łatwość konserwacji), ponieważ, jak już wyjaśniłem, pokrywasię on z rozszerzalnością i weryfikowalnością. W swych rozważaniach McCall nieogranicza się jedynie do czynników zewnętrznych, lecz opisuje też czynniki we-wnętrzne („kryteria”), metryki oraz ilościowe techniki gwarantujące uzyskanie satys-fakcjonujących czynników wewnętrznych. Jednak wraz z pojawieniem się technikiobiektowej wiele z opisywanych przez niego czynników wewnętrznych i metrykprzestało mieć znaczenie ze względu na swe ścisłe powiązanie ze stosowanymi wcze-śniej praktykami programistycznymi. Przystosowanie tej części pracy McCalla dotechnik opisywanych w mojej książce jest całkiem interesującym wyzwaniem. Patrzbibliografia i ćwiczenia w rozdziale 3.

Omówienie zależności względnego wzrostu wydajności systemu (po wymianiekomputera na szybszy) od rodzaju stosowanego algorytmu wywodzi się z [Aho 1974].

Klasyczną pozycją na temat łatwości obsługi jest [Shneiderman 1987], opierającysię na pracy [Shneiderman 1980], poświęconej szerszemu zakresowi zagadnień z dzie-dziny programowania. Odnośniki do wielu materiałów na ten temat można też znaleźćna stronie internetowej laboratorium Shneidermana, pod adresem http://www.cs.umd.edu/projects/hcil/.

1.5. BIBLIOGRAFIA 49

Krzywe Osmonda pochodzą z wykładu wygłoszonego przez Rogera Osmonda nakonferencji TOOLS USA [Osmond 1995]. Zwróć uwagę, że wykres pokazany w tymrozdziale nie uwzględnia czasu, dzięki czemu możesz lepiej przyjrzeć się zależno-ściom między funkcjonalnością a innymi czynnikami, wskazywanymi przez dwie al-ternatywne krzywe. Pamiętaj jednak, że na tym wykresie nie widać, że postępowaniezgodnie z czarną krzywą może doprowadzić do opóźnienia projektu. Oryginalne krzyweOsmonda miały za zadanie ukazywać raczej czas rozwijania aplikacji, a nie zwięk-szanie jej funkcjonalności.

Wykres prezentujący koszty konserwacji programów pochodzi z wyników badańprzeprowadzonych przez Lientza i Swansona, którzy wysłali kwestionariusze do 487firm [Lientz 1980]. Patrz również [Boehm 1979]. Mimo iż niektóre spośród zbiera-nych przez nich danych dziś mogą wydawać się nieadekwatne (badanie dotyczyłowsadowych aplikacji na komputery MIS, które składały się średnio z 23 000 wierszykodu, co jak na dzisiejsze warunki nie jest zbyt dużą liczbą), uzyskane przez nich wy-niki nadal wyglądają sensownie. Stowarzyszenie Software Management Associationprzeprowadza co roku ankietę na temat konserwacji. Wyniki jednej z nich znajdzieszw [Dekleva 1992].

Wyrażenia programowanie w dużej skali i programowanie w małej skali pochodząz [DeRemer 1976].

Ogólne omówienie zagadnień z dziedziny inżynierii oprogramowania znajdzieszw książce, którą napisali Ghezzi, Jazayeri i Mandrioli [Ghezzi 1991]. Dwóch spośródtych autorów napisało też książkę o językach programowania, [Ghezzi 1997], stano-wiącą uzupełnienie niektórych zagadnień poruszanych w tej książce.