UNIX to nie tylko system operacyjny, to także społeczność i kultura
Obszerne omówienie niezliczonych problemów związanych z programowaniem w systemie Unix
Niekonwencjonalne przedstawienie kulturotwórczych aspektów programowania
Wszechstronny opis sprawdzonych reguł i wzorców projektowych
Wnioski wypływające z historii Uniksa i jego porównanie z innymi systemami operacyjnymi
Liczne 'studia przypadków' (case studies) przedstawiające komponenty systemu Unix w kontekście programistycznym
Omówienie problematyki przenośności i wieloplatformowości oprogramowania
Unix to nie tylko system operacyjny; to także kultura i tradycja. Grzechem wielu programistów są programy spełniające wprawdzie swe funkcje, lecz zaprojektowane w pośpiechu, niedbale, a przez to trudne w utrzymaniu i rozwoju, oporne przy przenoszeniu na inną platformę i (z biegiem czasu) nieczytelne nawet dla swych autorów. Na temat dobrego programowania napisano już bardzo wiele; z tej książki dowiesz się nie tylko tego, jakie rozwiązania programistyczne warto poznać i naśladować, lecz także -- dlaczego warto to robić.
Ta książka zawiera sporą dawkę wiedzy, lecz jej treść koncentruje się przede wszystkim na doświadczeniu programistycznym. Programowanie przestaje być tylko dyscypliną techniczną, a staje się zagadnieniem o charakterze kulturotwórczym. Doceniając należycie ten fakt, autor nie ogranicza się do technicznego wykładu. Prezentuje poszczególne aspekty profesjonalnego projektowania i implementacji programów w kontekście filozofii i historii Uniksa z jednej strony, a społecznymi uwarunkowaniami kultury uniksowej z drugiej.
Warto przeczytać tę książkę także z tej przyczyny, że mało który podręcznik dla programistów dostarcza tyle historii, folkloru i dygresji -- elementów co prawda niekoniecznych z punktu widzenia meritum (choć i nad tą kwestią można by długo dyskutować), lecz znakomicie uprzyjemniających lekturę i być może ułatwiających zrozumienie tego, co w 'suchym', technicznym tekście może nieraz wydawać się zagadkowe.
Jeżeli więc jesteś programistą (niekoniecznie w systemie Unix) albo tylko interesują Cię zagadnienia związane z programowaniem, niniejsza książka z pewnością będzie stanowić interesującą lekturę, a być może również skłoni Cię do spojrzenia w inny sposób na swą codzienną pracę.
Koncepcja oprogramowania open source
Zagadnienia przenośności i wieloplatformowości programów
Podstawy filozofii uniksowej
Geneza oraz historia Uniksa, Linuksa i oprogramowania open source
Zalety modularności i przezroczystości projektu
Metody optymalizacji programów
Narzędzia programistyczne: edytory, makrogeneratory, debuggery, systemy kontroli wersji, programy dokumentujące itp.
Zagadnienia związane z licencjonowaniem programów
Podstawowe cechy Uniksa w kontekście innych popularnych systemów operacyjnych
Możliwości Uniksa i stojące przed nim zagrożenia
O autorze:
Eric S. Raymond zajmuje się programowaniem w systemie Unix od 1982 roku, jest rzecznikiem oprogramowania open source i ambasadorem 'społeczności open source'.
[więcej...\
Darmowy fragment publikacji:
IDZ DO
IDZ DO
PRZYK£ADOWY ROZDZIA£
PRZYK£ADOWY ROZDZIA£
SPIS TREĎCI
SPIS TREĎCI
KATALOG KSI¥¯EK
KATALOG KSI¥¯EK
KATALOG ONLINE
KATALOG ONLINE
ZAMÓW DRUKOWANY KATALOG
ZAMÓW DRUKOWANY KATALOG
TWÓJ KOSZYK
TWÓJ KOSZYK
DODAJ DO KOSZYKA
DODAJ DO KOSZYKA
CENNIK I INFORMACJE
CENNIK I INFORMACJE
ZAMÓW INFORMACJE
ZAMÓW INFORMACJE
O NOWOĎCIACH
O NOWOĎCIACH
ZAMÓW CENNIK
ZAMÓW CENNIK
CZYTELNIA
CZYTELNIA
FRAGMENTY KSI¥¯EK ONLINE
FRAGMENTY KSI¥¯EK ONLINE
Wydawnictwo Helion
ul. Chopina 6
44-100 Gliwice
tel. (32)230-98-63
e-mail: helion@helion.pl
UNIX. Sztuka
programowania
Autor: Eric S. Raymond
T³umaczenie: Grzegorz Werner (wstêp, rozdz. 1 – 10),
Wojciech Moch (rozdz. 11 – 20, dod. A – D)
ISBN: 83-7361-419-2
Tytu³ orygina³u: The Art of UNIX Programming
Format: B5, stron: 504
UNIX to nie tylko system operacyjny, to tak¿e spo³ecznoġæ i kultura
• Obszerne omówienie niezliczonych problemów zwi¹zanych z programowaniem
w systemie Unix
• Niekonwencjonalne przedstawienie kulturotwórczych aspektów programowania
• Wszechstronny opis sprawdzonych regu³ i wzorców projektowych
• Wnioski wyp³ywaj¹ce z historii Uniksa i jego porównanie z innymi
systemami operacyjnymi
• Liczne „studia przypadków” (case studies) przedstawiaj¹ce komponenty
systemu Unix w kontekġcie programistycznym
• Omówienie problematyki przenoġnoġci i wieloplatformowoġci oprogramowania
Unix to nie tylko system operacyjny; to tak¿e kultura i tradycja. Grzechem wielu
programistów s¹ programy spe³niaj¹ce wprawdzie swe funkcje, lecz zaprojektowane
w poġpiechu, niedbale, a przez to trudne w utrzymaniu i rozwoju, oporne przy
przenoszeniu na inn¹ platformê i (z biegiem czasu) nieczytelne nawet dla swych
autorów. Na temat dobrego programowania napisano ju¿ bardzo wiele; z tej ksi¹¿ki
dowiesz siê nie tylko tego, jakie rozwi¹zania programistyczne warto poznaæ
i naġladowaæ, lecz tak¿e — dlaczego warto to robiæ.
Ta ksi¹¿ka zawiera spor¹ dawkê wiedzy, lecz jej treġæ koncentruje siê przede wszystkim
na doġwiadczeniu programistycznym. Programowanie przestaje byæ tylko dyscyplin¹
techniczn¹, a staje siê zagadnieniem o charakterze kulturotwórczym.
Doceniaj¹c nale¿ycie ten fakt, autor nie ogranicza siê do technicznego wyk³adu.
Prezentuje poszczególne aspekty profesjonalnego projektowania i implementacji
programów w kontekġcie filozofii i historii Uniksa z jednej strony, a spo³ecznymi
uwarunkowaniami kultury uniksowej z drugiej.
Warto przeczytaæ tê ksi¹¿kê tak¿e z tej przyczyny, ¿e ma³o który podrêcznik dla
programistów dostarcza tyle historii, folkloru i dygresji — elementów co prawda
niekoniecznych z punktu widzenia meritum (choæ i nad t¹ kwesti¹ mo¿na by d³ugo
dyskutowaæ), lecz znakomicie uprzyjemniaj¹cych lekturê i byæ mo¿e u³atwiaj¹cych
zrozumienie tego, co w „suchym”, technicznym tekġcie mo¿e nieraz wydawaæ siê
zagadkowe.
Je¿eli wiêc jesteġ programist¹ (niekoniecznie w systemie Unix) albo tylko interesuj¹ Ciê
zagadnienia zwi¹zane z programowaniem, niniejsza ksi¹¿ka z pewnoġci¹ bêdzie
stanowiæ interesuj¹c¹ lekturê, a byæ mo¿e równie¿ sk³oni Ciê do spojrzenia w inny
sposób na sw¹ codzienn¹ pracê.
Spis treści
Przedmowa....................................................................................... 13
Kto powinien przeczytać tę książkę? ...................................................r.............................14
Jak korzystać z tej książki? ...................................................r............................................15
Pokrewne źródła...................................................r...................................................r..........16
Konwencje używane w tej książce...................................................r.................................17
Nasze studia przypadków...................................................r...............................................18
Część I
Kontekst...................................................n.....................19
Rozdział 1. Filozofia: filozofia ma znaczenie ......................................................... 21
1.1. Kultura? Jaka kultura?...................................................r.............................................21
1.2. Trwałość Uniksa...................................................r...................................................r...22
1.3. Argumenty przeciwko nauce kultury uniksowej...................................................r.....23
1.4. Co w Uniksie jest złe?...................................................r.............................................24
1.5. Co w Uniksie jest dobre? ...................................................r........................................25
1.5.1. Oprogramowanie o otwartych źródłach...................................................r.........25
1.5.2. Międzyplatformowa przenośność i otwarte standardy .....................................25
1.5.3. Internet i World Wide Web...................................................r............................26
1.5.4. Społeczność Open Source...................................................r..............................26
1.5.5. Prawdziwa elastyczność...................................................r.................................27
1.5.6. Programowanie Uniksa jest przyjemne ...................................................r.........27
1.5.7. Doświadczenie zdobyte w Uniksie można zastosować gdzie indziej...............28
1.6. Podstawy filozofii uniksowej ...................................................r..................................29
1.6.1. Reguła modularności: Pisz proste części połączone przejrzystymi interfejsami ......31
1.6.2. Reguła przejrzystości: przejrzystość jest lepsza niż spryt ................................32
1.6.3. Reguła kompozycji: Projektuj programy tak, aby dało się je łączyć z innymi.....32
1.6.4. Reguła oddzielania: Oddzielaj politykę od mechanizmu;
oddzielaj interfejsy od głównej części programu...................................................r.33
1.6.5. Reguła prostoty: Projektuj pod kątem prostoty;
uciekaj się do złożoności tylko tam, gdzie to konieczne ........................................34
1.6.6. Reguła powściągliwości: Pisz duży program tylko wtedy,
gdy zostanie jasno udowodnione, że nie da się inaczej ..........................................35
1.6.7. Reguła przezroczystości: Dbaj o zrozumiałość kodu,
aby ułatwić badanie i debugowanie programów...................................................r..35
1.6.8. Reguła odporności: odporność jest pochodną przezroczystości i prostoty.......36
1.6.9. Reguła reprezentacji: Przełóż wiedzę na dane,
aby logika programu mogła być prosta i odporna...................................................r37
1.6.10. Reguła najmniejszego zaskoczenia: Projektując interrfejs,
zawsze postępuj w najmniej zaskakujący sposób ...................................................r37
6
UNIX. Sztuka programowania
1.6.11. Reguła milczenia: Kiedy program
nie ma nic nieoczekiwanego do powiedzenia, nie powinien mówić nic.................38
1.6.12. Reguła naprawy: Naprawiaj, co się da, ale jeśli progrram musi zawieść,
niech zawiedzie z hukiem i jak najszybciej ...................................................r.........38
1.6.13. Reguła ekonomii: Czas programisty jest drogi;
oszczędzaj go zamiast czasu komputera ...................................................r..............39
1.6.14. Reguła generacji: Unikaj programowania ręcznego;
jeśli to możliwe, pisz programy piszące programy.................................................40
1.6.15. Reguła optymalizacji: Napisz prototyp, zanim zaczniesz dopracowywać
program. Sprawdź, czy działa, zanim zaczniesz go optymalizować ............................40
1.6.16. Reguła różnorodności: Nie ufaj żadnym deklaracjom
o „jedynym słusznym sposobie” ...................................................r..........................42
1.6.17. Reguła rozszerzalności: Projektuj programy z myślą o rprzyszłości,
bo nadejdzie ona wcześniej, niż się spodziewasz ...................................................r42
1.7. Filozofia uniksowa w jednej lekcji...................................................r..........................43
1.8. Stosowanie filozofii uniksowej ...................................................r...............................43
1.9. Liczy się też nastawienie...................................................r.........................................44
Rozdział 2. Historia: Opowieść o dwóch kulturach .............................................. 45
2.1. Pochodzenie i historia Uniksa, lata 1969 – 1995 ...................................................r....45
2.1.1. Geneza: lata 1969 – 1971...................................................r...............................46
2.1.2. Exodus: lata 1971 – 1980...................................................r...............................48
2.1.3. TCP/IP i Wojny Uniksowe: lata 1980 – 1990 ..................................................50
2.1.4. Uderzenia w Imperium: lata 1991 – 1995...................................................r......56
2.2. Pochodzenie i historia hakerów, lata 1961 – 1995...................................................r..58
2.2.1. Zabawa w gajach Akademii: lata 1961 – 1980 ...................................................r..58
2.2.2. Fuzja internetowa i ruch wolnego oprogramowania: lata 1981 – 1991............60
2.2.3. Linux i reakcja pragmatyków: lata 1991 – 1998 ...................................................r.62
2.3. Ruch Open Source — od roku 1998 do chwili obecnej................................................64
2.4. Lekcje płynące z historii Uniksa ...................................................r.............................66
Rozdział 3. Kontrasty: porównanie filozofii uniksowej z innymi ............................ 67
3.1. Elementy stylu systemu operacyjnego ...................................................r....................67
3.1.1. Jaka jest idea unifikująca system operacyjny?..................................................68
3.1.2. Wielozadaniowość ...................................................r.........................................68
3.1.3. Współpracujące procesy ...................................................r................................69
3.1.4. Granice wewnętrzne...................................................r.......................................70
3.1.5. Atrybuty plików i struktury rekordów ...................................................r...........71
3.1.6. Binarne formaty plików ...................................................r.................................72
3.1.7. Preferowany styl interfejsu użytkownika...................................................r.......72
3.1.8. Zamierzone grono odbiorców ...................................................r........................73
3.1.9. Bariera oddzielająca użytkownika od programisty...........................................73
3.2. Porównanie systemów operacyjnych ...................................................r......................74
3.2.1. VMS...................................................r...................................................r............76
3.2.2. MacOS ...................................................r...................................................r........77
3.2.3. OS/2 ...................................................r...................................................r............78
3.2.4. Windows NT...................................................r..................................................80
3.2.5. BeOS ...................................................r...................................................r...........83
3.2.6. MVS...................................................r...................................................r............85
3.2.7. VM/CMS...................................................r...................................................r.....87
3.2.8. Linux ...................................................r...................................................r...........89
3.3. Co odchodzi, to wraca...................................................r.............................................90
Spis treści
7
Część II Projekt ...................................................n.......................93
Rozdział 4. Modularność: czystość i prostota ...................................................... 95
4.1. Hermetyzacja i optymalny rozmiar modułu...................................................r............97
4.2. Zwartość i ortogonalność ...................................................r........................................98
4.2.1. Zwartość...................................................r...................................................r......99
4.2.2. Ortogonalność ...................................................r..............................................100
4.2.3. Reguła SPOT ...................................................r...............................................102
4.2.4. Zwartość i jedno silne centrum ...................................................r....................103
4.2.5. Zalety niezaangażowania ...................................................r.............................105
4.3. Oprogramowanie ma wiele warstw...................................................r.......................105
4.3.1. Od góry w dół czy od dołu w górę?...................................................r.............106
4.3.2. Warstwy spajające ...................................................r.......................................108
4.3.3. Studium przypadku: język C jako cienka warstwa kleju ................................108
4.4. Biblioteki...................................................r...................................................r............110
4.4.1. Studium przypadku: wtyczki programu GIMP...............................................111
4.5. Unix i języki obiektowe ...................................................r........................................112
4.6. Kodowanie z myślą o modularności...................................................r.........................114
Rozdział 5. Tekstowość: dobre protokoły to dobra praktyka.............................. 115
5.1. Dlaczego tekstowość jest ważna? ...................................................r.........................117
5.1.1. Studium przypadku: format uniksowego pliku haseł......................................118
5.1.2. Studium przypadku: format pliku .newsrc...................................................r...120
5.1.3. Studium przypadku: format pliku graficznego PNG ......................................121
5.2. Metaformaty plików danych ...................................................r.................................122
5.2.1. Styl DSV ...................................................r...................................................r...122
5.2.2. Format RFC 822 ...................................................r..........................................123
5.2.3. Format „słoika ciasteczek” ...................................................r..........................124
5.2.4. Format „słoika rekordów”...................................................r............................125
5.2.5. XML...................................................r...................................................r..........126
5.2.6. Format plików INI systemu Windows...................................................r.........128
5.2.7. Uniksowe konwencje dotyczące formatu plików tekstowych ........................129
5.2.8. Zalety i wady kompresji plików ...................................................r..................130
5.3. Projektowanie protokołów aplikacyjnych...................................................r.............131
5.3.1. Studium przypadku: SMTP, protokół transferu poczty ..................................132
5.3.2. Studium przypadku: POP3, protokół skrzynki pocztowej..............................133
5.3.3. Studium przypadku: IMAP, internetowy protokół dostępu do poczty ...............134
5.4. Metaformaty protokołów aplikacyjnych ...................................................r...............135
5.4.1. Klasyczny internetowy metaprotokół aplikacyjny..........................................136
5.4.2. HTTP jako uniwersalny protokół aplikacyjny................................................136
5.4.3. BEEP: Blocks Extensible Exchange Protocol ................................................138
5.4.4. XML-RPC, SOAP i Jabber ...................................................r..........................139
Rozdział 6. Przezroczystość: niech stanie się światłość .................................... 141
6.1. Studia przypadków...................................................r................................................143
6.1.1. Studium przypadku: audacity ...................................................r......................143
6.1.2. Studium przypadku: opcja -v programu fetchmail .........................................144
6.1.3. Studium przypadku: GCC...................................................r............................146
6.1.4. Studium przypadku: kmail...................................................r...........................147
6.5.1. Studium przypadku: SNG ...................................................r............................148
6.1.6. Studium przypadku: baza danych terminfo ...................................................r.150
6.1.7. Studium przypadku: pliki danych gry Freeciv................................................153
6.2. Projektowanie pod kątem przezroczystości i odkrywalności...................................154
6.2.1. Zen przezroczystości...................................................r....................................155
6.2.2. Kodowanie pod kątem przezroczystości i odkrywalności ..............................156
6.2.3. Przezroczystość i unikanie nadopiekuńczości ................................................157
8
UNIX. Sztuka programowania
6.2.4. Przezroczystość i edytowalne reprezentacje...................................................r158
6.2.5. Przezroczystość, diagnozowanie błędów i usuwanie skutków błędu .............159
6.3. Projektowanie pod kątem konserwowalności ...................................................r.......160
Rozdział 7. Wieloprogramowość: wyodrębnianie procesów
w celu oddzielenia funkcji ............................................................... 163
7.1. Oddzielanie kontroli złożoności od dostrajania wydajności ....................................165
7.2. Taksonomia uniksowych metod IPC...................................................r........................166
7.2.1. Przydzielanie zadań wyspecjalizowanym programom ...................................166
7.2.2. Potoki, przekierowania i filtry ...................................................r.....................167
7.2.3. Nakładki...................................................r...................................................r....171
7.2.4. Nakładki zabezpieczające i łączenie Bernsteina.............................................172
7.2.5. Procesy podrzędne ...................................................r.......................................174
7.2.6. Równorzędna komunikacja międzyprocesowa...............................................174
7.3. Problemy i metody, których należy unikać...................................................r...........181
7.3.1. Przestarzałe uniksowe metody IPC...................................................r..............182
7.3.2. Zdalne wywołania procedur...................................................r.........................183
7.3.3. Wątki — groźba czy niebezpieczeństwo? ...................................................r...185
7.4. Dzielenie procesów na poziomie projektu ...................................................r............186
Rozdział 8. Minijęzyki: jak znaleźć notację, która śpiewa.................................. 189
8.1. Taksonomia języków...................................................r.............................................191
8.2. Stosowanie minijęzyków...................................................r.......................................193
8.2.1. Studium przypadku: sng ...................................................r..............................193
8.2.2. Studium przypadku: wyrażenia regularne ...................................................r...193
8.2.3. Studium przypadku: Glade ...................................................r..........................196
8.2.4. Studium przypadku: m4...................................................r...............................198
8.2.5. Studium przypadku: XSLT ...................................................r..........................198
8.2.6. Studium przypadku: warsztat dokumentatora.................................................199
8.2.7. Studium przypadku: składnia pliku kontrolnego programu fetchmail ...............204
8.2.8. Studium przypadku: awk ...................................................r.............................205
8.2.9. Studium przypadku: PostScript...................................................r....................206
8.2.10. Studium przypadku: bc i dc ...................................................r.......................207
8.2.11. Studium przypadku: Emacs Lisp ...................................................r...............209
8.2.12. Studium przypadku: JavaScript ...................................................r.................209
8.3. Projektowanie minijęzyków...................................................r..................................210
8.3.1. Wybór odpowiedniego poziomu złożoności...................................................r210
8.3.2. Rozszerzanie i osadzanie języków...................................................r...............212
8.3.3. Pisanie własnej gramatyki...................................................r............................213
8.3.4. Makra — strzeż się! ...................................................r.....................................214
8.3.5. Język czy protokół aplikacyjny?...................................................r..................215
Rozdział 9. Generacja: podwyższanie poziomu specyfikacji ............................... 217
9.1. Programowanie sterowane danymi ...................................................r.......................218
9.1.1. Studium przypadku: ascii...................................................r.............................219
9.1.2. Studium przypadku: statystyczne filtrowanie spamu .....................................220
9.1.3. Studium przypadku: modyfikowanie metaklas w programie fetchmailconf .....221
9.2. Doraźna generacja kodu ...................................................r........................................226
9.2.1. Studium przypadku: generowanie kodu
wyświetlającego tabelę znaków w programie ascii ..............................................226
9.2.2. Studium przypadku: generowanie kodu HTML
na podstawie listy tabelarycznej...................................................r.........................228
Rozdział 10. Konfiguracja: jak zacząć od właściwej nogi..................................... 231
10.1. Co powinno być konfigurowalne? ...................................................r......................231
10.2. Gdzie znajdują się dane konfiguracyjne?...................................................r............233
Spis treści
9
10.3. Pliki kontrolne ...................................................r...................................................r..234
10.3.1. Studium przypadku: plik .netrc...................................................r..................236
10.3.2. Przenoszenie do innych systemów operacyjnych .........................................237
10.4. Zmienne środowiskowe...................................................r.......................................237
10.4.1. Systemowe zmienne środowiskowe ...................................................r..........238
10.4.2. Zmienne środowiskowe definiowane przez użytkownika ............................239
10.4.3. Kiedy używać zmiennych środowiskowych? ...............................................240
10.4.4. Przenoszenie do innych systemów operacyjnych .........................................241
10.5. Opcje wiersza polecenia...................................................r......................................241
10.5.1. Opcje wiersza polecenia od –a do –z...................................................r.........242
10.5.2. Przenoszenie do innych systemów operacyjnych .........................................247
10.6. Którą metodę wybrać? ...................................................r........................................247
10.6.1. Studium przypadku: fetchmail...................................................r...................248
10.6.2. Studium przypadku: serwer XFree86 ...................................................r........249
10.7. O naruszaniu tych reguł...................................................r.......................................251
Rozdział 11. Interfejsy: Wzorce projektowe interfejsu użytkownika
w środowisku uniksowym................................................................ 253
11.1. Stosowanie Reguły Najmniejszego Zaskoczenia...................................................r254
11.2. Historia projektowania interfejsów w systemie Unix ............................................256
11.3. Ocena projektów interfejsów ...................................................r..............................257
11.4. Różnice między CLI a interfejsami wizualnymi...................................................r.259
11.4.1. Studium: Dwa sposoby pisania programu kalkulatora .................................263
11.5. Przezroczystość, wyrazistość i konfigurowalność .................................................264
11.6. Uniksowe wzorce projektowe interfejsów ...................................................r..........266
11.6.1. Wzorzec filtra...................................................r.............................................266
11.6.2. Wzorzec cantrip ...................................................r.........................................268
11.6.3. Wzorzec źródła (source) ...................................................r............................269
11.6.4. Wzorzec drenu (sink)...................................................r.................................269
11.6.5. Wzorzec kompilatora ...................................................r.................................269
11.6.6. Wzorzec ed...................................................r.................................................270
11.6.7. Wzorzec roguelike ...................................................r.....................................271
11.6.8. Wzorzec „rozdzielenia mechanizmu od interfejsu”......................................273
11.6.9. Wzorzec serwera CLI ...................................................r................................278
11.6.10. Wzorce interfejsów oparte na językach ...................................................r...279
11.7. Stosowanie uniksowych wzorców projektowania interfejsów...............................280
11.7.1. Wzorzec programu poliwalencyjnego (wielowartościowego)......................281
11.8. Przeglądarka internetowa i uniwersalny Front End ...............................................282
11.9. Milczenie jest złotem ...................................................r..........................................284
Rozdział 12. Optymalizacja ................................................................................. 287
12.1. Jeżeli masz zrobić cokolwiek, lepiej nie rób nic...................................................r.287
12.2. Zmierz przed optymalizacją ...................................................r................................288
12.3. Nielokalność bywa szkodliwa...................................................r.............................290
12.4. Przepustowość i opóźnienia ...................................................r................................291
12.4.1. Grupowanie operacji...................................................r..................................292
12.4.2. Nakładające się operacje...................................................r............................293
12.4.3. Buforowanie wyników operacji...................................................r.................293
Rozdział 13. Złożoność: Tak prosto, jak tylko można, ale nie prościej ................. 295
13.1. Mówiąc o złożoności...................................................r...........................................295
13.1.1. Trzy źródła złożoności...................................................r...............................296
13.1.2. Wybór między złożonością interfejsu a złożonością implementacji ............298
13.1.3. Złożoność niezbędna, opcjonalna i przypadkowa ........................................299
13.1.4. Mapowanie złożoności...................................................r...............................300
13.1.5. Gdy prostota nie wystarcza...................................................r........................301
10
UNIX. Sztuka programowania
13.2. Opowieść o pięciu edytorach ...................................................r..............................302
13.2.1. ed...................................................r...................................................r.............303
13.2.2. vi ...................................................r...................................................r.............304
13.2.3. Sam ...................................................r...................................................r.........305
13.2.5. Wily...................................................r...................................................r.........307
13.3. Właściwy rozmiar edytora ...................................................r..................................308
13.3.1. Identyfikowanie problemów ze złożonością.................................................308
13.3.2. Nici z kompromisu...................................................r.....................................312
13.3.3. Czy Emacs jest argumentem przeciwko tradycji Uniksa?............................313
13.4. Właściwy rozmiar programu...................................................r...............................315
Część III Implementacja ...................................................n..........317
Rozdział 14. Języki: w C albo nie w C?................................................................ 319
14.1. Uniksowy róg obfitości języków...................................................r.........................319
14.2. Dlaczego nie C? ...................................................r..................................................320
14.3. Języki interpretowane i strategie mieszane ...................................................r.........322
14.4. Ocena języków ...................................................r...................................................r.323
14.4.1. C...................................................r...................................................r..............323
14.4.2. C++ ...................................................r...................................................r.........325
14.4.3. Powłoka...................................................r...................................................r...327
14.4.4. Perl ...................................................r...................................................r..........330
14.4.5. Tcl ...................................................r...................................................r...........332
14.4.6. Python ...................................................r...................................................r.....334
14.4.7. Java ...................................................r...................................................r.........338
14.4.8. Emacs Lisp...................................................r.................................................341
14.5. Trendy na przyszłość...................................................r...........................................342
14.6. Wybór biblioteki systemu X ...................................................r...............................344
Rozdział 15. Narzędzia: Taktyki rozwoju .............................................................. 347
15.1. System operacyjny przyjazny dla programisty ...................................................r...347
15.2. Wybór edytora...................................................r...................................................r..348
15.2.1. Co należy wiedzieć o vi ...................................................r.............................349
15.2.2. Co należy wiedzieć o Emacsie...................................................r...................349
15.2.3. Wybór przeciw religii: używaj obu...................................................r............350
15.3. Generatory kodu do zadań specjalnych...................................................r...............351
15.3.1. yacc i lex ...................................................r...................................................r.351
15.3.2. Studium: Glade ...................................................r..........................................354
15.4. make: automatyzacja przepisów...................................................r..........................355
15.4.1. Podstawowa teoria make...................................................r............................355
15.4.2. Make w językach innych niż C i C++...................................................r........357
15.4.3. Produkcje użytkowe...................................................r...................................357
15.4.4. Generowanie plików makefile ...................................................r...................359
15.5. Systemy kontroli wersji...................................................r.......................................362
15.5.1. Po co kontrolować wersje? ...................................................r........................362
15.5.2. Ręczna kontrola wersji...................................................r...............................363
15.5.3. Automatyczna kontrola wersji ...................................................r...................363
15.5.4. Uniksowe narzędzia kontroli wersji...................................................r...........364
15.6. Debugowanie w czasie działania programu ...................................................r........367
15.7. Profilowanie ...................................................r...................................................r.....368
15.8. Łączenie narzędzi z Emacsem...................................................r.............................368
15.8.1. Emacs i make ...................................................r.............................................369
15.8.2. Emacs i debugowanie w czasie działania programu.....................................369
15.8.3. Emacs i kontrola wersji...................................................r..............................370
15.8.4. Emacs i profilowanie ...................................................r.................................370
15.8.5. Jak IDE, ale lepsze...................................................r.....................................371
Spis treści
11
Rozdział 16. Ponowne wykorzystanie: Nie wyważajmy otwartych drzwi................ 373
16.1. Opowieść o Janie Nowicjuszu...................................................r.............................374
16.2. Przezroczystość jako klucz do ponownego użycia kodu .......................................377
16.3. Od ponownego wykorzystania do otwartych źródeł ..............................................378
16.4. Najlepsze rzeczy w życiu są otwarte...................................................r...................380
16.5. Gdzie szukać?...................................................r...................................................r...382
16.6. Kwestie związane z używaniem otwartego oprogramowania................................383
16.7. Licencje ...................................................r...................................................r............384
16.7.1. Co można uznać za otwarte oprogramowanie ..............................................385
16.7.2. Standardowe licencje otwartego oprogramowania .......................................386
16.7.3. Kiedy potrzebny jest prawnik? ...................................................r..................388
Część IV Społeczność...................................................n..............391
Rozdział 17. Przenośność: Przenośność oprogramowania
i utrzymywanie standardów ........................................................... 393
17.1. Ewolucja języka C...................................................r...............................................394
17.1.1. Wczesna historia języka C ...................................................r.........................395
17.1.2. Standardy języka C ...................................................r....................................396
17.2. Standardy Uniksa ...................................................r................................................398
17.2.1. Standardy i Wojny Uniksów...................................................r......................398
17.2.2. Duch na uczcie zwycięstwa ...................................................r.......................401
17.2.3. Standardy Uniksa w świecie otwartych źródeł .............................................402
17.3. IETF i Proces Standaryzacji RFC ...................................................r.......................403
17.4. Specyfikacja to DNA, kod to RNA...................................................r.....................406
17.5. Programowanie ukierunkowane na przenośność ...................................................r408
17.5.1. Przenośność i wybór języka...................................................r.......................409
17.5.2. Omijanie zależności od systemu...................................................r................412
17.5.3. Narzędzia umożliwiające przenośność ...................................................r......413
17.6. Internacjonalizacja ...................................................r..............................................413
17.7. Przenośność, otwarte standardy i otwarte źródła ...................................................r414
Rozdział 18. Dokumentacja: Objaśnianie kodu w świecie WWW.......................... 417
18.1. Koncepcje dokumentacji ...................................................r.....................................418
18.2. Styl Uniksa ...................................................r...................................................r.......420
18.2.1. Skłonność do wielkich dokumentów ...................................................r.........420
18.2.2. Styl kulturowy...................................................r............................................421
18.3. Zwierzyniec uniksowych formatów dokumentacji ................................................422
18.3.1. troff i narzędzia z Warsztatu Dokumentatora ...............................................422
18.3.2. TEX...................................................r...................................................r.........424
18.3.3. Texinfo...................................................r...................................................r....425
18.3.4. POD...................................................r...................................................r.........425
18.3.5. HTML ...................................................r...................................................r.....425
18.3.6. DocBook ...................................................r...................................................r.426
18.4. Istniejący chaos i możliwe rozwiązania ...................................................r..............426
18.5. DocBook................................................r...................................................r..............427
18.5.1. Definicje typu dokumentu...................................................r..........................427
18.5.2. Inne definicje DTD ...................................................r....................................428
18.5.3. Łańcuch narzędzi DocBook...................................................r.......................429
18.5.4. Narzędzia do migracji ...................................................r................................431
18.5.5. Narzędzia do edycji...................................................r....................................432
18.5.6. Pokrewne standardy i praktyki...................................................r...................432
18.5.7. SGML ...................................................r...................................................r.....433
18.5.8. Bibliografia formatu XML-DocBook ...................................................r........433
18.6. Najlepsze praktyki pisania dokumentacji uniksowej .............................................434
12
UNIX. Sztuka programowania
Rozdział 19. Otwarte źródła: Programowanie w nowej społeczności Uniksa ......... 437
19.1. Unix i otwarte źródła...................................................r...........................................438
19.2. Najlepsze metody pracy z twórcami otwartego oprogramowania .........................440
19.2.1. Dobre praktyki korygowania programów...................................................r..440
19.2.2. Dobre praktyki nazywania projektów i archiwów ........................................444
19.2.3. Dobre praktyki rozwoju projektu...................................................r...............447
19.2.4. Dobre praktyki tworzenia dystrybucji ...................................................r.......450
19.2.5. Dobre praktyki komunikacji ...................................................r......................454
19.3. Logika licencji: jak wybrać ...................................................r.................................456
19.4. Dlaczego należy stosować standardowe licencje ...................................................r457
19.5. Zróżnicowanie licencji otwartego źródła ...................................................r............457
19.5.1. Licencja MIT lub X Consortium...................................................r................457
19.5.2. Klasyczna licencja BSD...................................................r.............................458
19.5.3. Licencja Artistic...................................................r.........................................458
19.5.4. Licencja GPL ...................................................r.............................................458
19.5.5. Licencja Mozilla Public License...................................................r................459
Rozdział 20. Przyszłość: Zagrożenia i możliwości................................................ 461
20.1. Zasadność i przypadki w tradycji Uniksa ...................................................r...........461
20.2. Plan 9: Tak wyglądała przyszłość ...................................................r.......................464
20.3. Problemy w konstrukcji Uniksa ...................................................r..........................466
20.3.1. Plik w Uniksie jest tylko wielkim workiem bajtów......................................466
20.3.2. Unix słabo obsługuje graficzne interfejsy użytkownika...............................468
20.3.3. Plik usunięty na zawsze ...................................................r.............................469
20.3.4. Unix zakłada istnienie statycznego systemu plików.....................................469
20.3.5. Projekt kontroli zadań jest zupełnym nieporozumieniem.............................469
20.3.6. API Uniksa nie stosuje wyjątków ...................................................r..............470
20.3.7. Za wywołania ioctl(2) i fcntl(2) należy się wstydzić....................................471
20.3.8. Model bezpieczeństwa w Uniksie może być zbyt prosty .............................472
20.3.9. W Uniksie jest byt wiele różnych rodzajów nazw........................................472
20.3.10. Systemy plików można by uznać za szkodliwe..........................................472
20.3.11. W kierunku Globalnej Przestrzeni Adresowej Internetu ............................473
20.4. Problemy w środowisku Uniksa...................................................r..........................473
20.5. Problemy w kulturze Uniksa ...................................................r...............................475
20.6. Źródła nadziei...................................................r...................................................r...478
Dodatek A Słownik skrótów ............................................................................. 479
Dodatek B Nawiązania ..................................................................................... 483
Dodatek C Współpracownicy............................................................................ 493
Dodatek D Korzeń bez korzenia: uniksowe koany Mistrza Foo .......................... 495
Wstęp redaktorski...................................................r...................................................r......495
Mistrz Foo i dziesięć tysięcy linii ...................................................r................................496
Mistrz Foo i Script Kiddie...................................................r............................................497
Opowieści Mistrza Foo o dwóch ścieżkach ...................................................r.................498
Mistrz Foo i metodolog ...................................................r................................................499
Opowieści Mistrza Foo o graficznych interfejsach użytkownika ...................................500
Mistrz Foo i fanatyk Uniksa...................................................r.........................................500
Opowieści Mistrza Foo o naturze Uniksa ...................................................r....................501
Mistrz Foo i Użytkownik ...................................................r.............................................502
Skorowidz....................................................................................... 503
Rozdział 16.
Ponowne wykorzystanie:
nie wyważajmy
otwartych drzwi
Gdy wielki człowiek powstrzymuje się od działania,
jego siłę można poczuć z odległości tysięcy mil.
— Tao Te Ching (popularne, choć nieprawidłowe tłumaczgenie)
Niechęć do niepotrzebnej pracy jest wielką zaletą programistów. Jeżeli chiński mędrzec
Lao-cy żyłby dzisiaj i nauczał drogi tao, jego słowa zostałby prawdopodobnie (również
błędnie) przetłumaczone jako: „Gdy wielki programista powstrzymuje się od pisania,
jego siłę można poczuć z odległości tysięcy mil”. W rzeczywistości ostatnie przekłady
sugerują jednak, że chiński zwrot wu-tei, który tradycyjnie był tłumaczony jako „bez-
czynność” lub „powstrzymywanie się od działania”, powinien być oddany jako „mi-
nimalne działania”, „najefektywniejsze operacje” albo „działania w zgodzie z prawami
natury”. Taka wersja doskonale opisuje dobre praktykic inżynieryjne.
Trzeba pamiętać o Regule Ekonomii. Wyważanie otwartych drzwi w każdym nowym
projekcie jest marnotrawstwem. Czas poświęcony na myślenie jest o wiele cenniejszy niż
pozostałe składowe procesu rozwoju oprogramowania, w związku z czym powinien
być przeznaczany na zmaganie się z nowymi problemami, a nie na rozgrzebywanie
starych, dla których rozwiązania już dawno wymyślono. Takie nastawienie sprawdza
się doskonale zarówno w zakresie „miękkiego” rozwoju zasobów ludzkich, jak również
w zakresie „twardych” zasad opłacalności inwestycji wc rozwój oprogramowania.
Ponowne wymyślanie koła nie jest złe tylko z powoduc marnotrawienia cennego
czasu, ale dlatego, że na nowo wymyślone koła częstco okazują się kwadratowe.
Rodzą się wówczas nieodparte ciągoty do różnych oszczędcności wynikających
z tworzenia prymitywnych i nieprzemyślanych projektówc, które jednak na dłuższą
metę powodują koszty przewyższające uzyskane oszczędcności.
— Henry Spencer
374
Rozdział 16. ♦ Ponowne wykorzystanie: nie wyważajmy otwartych drzłwi
Najskuteczniejszym sposobem na uniknięcie ponownego wymyślania koła jest pożycze-
nie czyjegoś projektu i implementacji, czyli ponowne wykorzystanie istniejącego kodu.
Unix pozwala na ponowne wykorzystanie praktycznie wszystkiego, począwszy od po-
jedynczych bibliotek, a kończąc na całych programach, które można dowolnie łączyć
za pomocą skryptów. Ponowne wykorzystanie kodu jest jednym z najważniejszych wy-
różników programistów uniksowych. Doświadczenie wynikające z korzystania z Uniksa
pozwala wytworzyć w sobie nawyk prób prototypowania różnych rozwiązań, przez
łączenie istniejących komponentów z minimalizacją tworzenia nowych wynalazków.
Daje to lepsze rezultaty niż pochopne pisanie autonomicznego kodu, który zostanie użyty
tylko w jednym miejscu.
Ponowne wykorzystanie kodu należy do najbardziej podstawowych elementów roz-
woju oprogramowania. Niestety wielu programistów przystępujących się do społecz-
ności uniksowej, którzy zdobywali doświadczenie w innych systemach operacyjnych,
nigdy nie wyrobili w sobie nawyku ponownego wykorzystania istniejących elementów.
Wszędzie kwitnie marnotrawstwo czasu i podwójna praca, mimo że szkodzi to interesom
zarówno płacących za kod, jak i twórców kodu. Poznanie powodów utrzymywania się tak
dziwacznych tendencji jest pierwszym krokiem do ich czmiany.
16.1. Opowieść o Janie Nowicjuszu
Dlaczego programiści ciągle wymyślają koło na nowo? Powodów jest wiele, zaczynając
od najprostszych technicznych potknięć, a kończąc na psychologii programisty i ekonomii
systemu produkcji oprogramowania. Efekt takiego powszechnego marnotrawienia czasu
programistów daje się odczuć na tych wszystkich płaszcczyznach.
Wyobraźmy sobie pierwsze doświadczenia w normalnej pracy pewnego programisty,
absolwenta uczelni, Jana Nowicjusza. Załóżmy, że w szkole wpojono mu zalety ponow-
nego wykorzystania kodu, i teraz pełen zapału pragnie wykorzystać te wiadomości.
Pierwszym zadaniem Nowicjusza jest praca w zespole tworzącym pewną wielką aplikację.
Na potrzeby tego przykładu załóżmy, że jest to środowisko graficzne, które ma pomagać
użytkownikom w tworzeniu zapytań i nawigowaniu w dużej bazie danych. Menadżerowie
projektu zebrali kolekcję narzędzi i komponentów, które uznali za właściwe do wykona-
nia zadania. W tej kolekcji znajduje się nie tylko wybrany język programowania, ale
również wiele bibliotek.
Zebrane biblioteki są kluczowym elementem projektu. Zawierają one wiele ważnych
usług — od kontrolek graficznych i połączeń sieciowych, aż do całych podsystemów,
takich jak pomoc kontekstowa. Brak tych usług spowodowałby konieczność tworzenia
sporej ilości dodatkowego kodu, co w znacznym stopniu wpłynęłoby na budżet pro-
jektu i datę wydania produktu.
Właśnie data wydania mocno niepokoi Nowicjusza. Być może nie ma doświadczenia,
ale czytał Dilberta i słyszał kilka kombatanckich opowieści doświadczonych pro-
gramistów. Dobrze wie, że zarząd ma tendencje do wyznaczania, delikatnie mówiąc
16.1. Opowieść o Janie Nowicjuszu
375
„agresywnych” terminów. Być może czytał nawet książkę Eda Yourdona Death
March [Yourdon], który już w roku 1996 zauważył, że budżet większości projektów
jest o co najmniej 50 za mały, zarówno jeżeli chodzi co środki, jak i czas, a tendencja
do takiego ograniczania budżetów sprawia, że w przysczłości będzie jeszcze gorzej.
Jednak Nowicjusz jest inteligentny i pełen energii. Dochodzi do wniosku, że największą
szansę na sukces daje mu szybkie nauczenie się jak najskuteczniejszego wykorzysta-
nia przekazanych mu narzędzi i bibliotek. Rozgrzewa palce i rzuca się w wir pracy…
w efekcie trafia do piekła.
Wszystko, za co się zabierze, jest trudniejsze i trwa dłużej niż tego oczekiwał. Wygląda
na to, że komponenty, których używa, mają wiele przypadków brzegowych, w których
zachowują się nieprawidłowo, a czasem wręcz niszczycielsko. Takich przypadków
unikano w aplikacjach przykładowych tych komponentów, a kod Nowicjusza tworzy
je co krok. Często zastanawia się, co mieli na myśli twórcy biblioteki, ale nie może
znaleźć właściwej odpowiedzi, ponieważ biblioteka nie jest właściwie udokumentowana.
Dokumentację często bowiem tworzą pracownicy techniczni niebędący programista-
mi i nie myślący jak programiści. Niestety nie można poznać sposobu działania bi-
blioteki przez przeczytanie jej kodu, ponieważ jest ona skompilowanym kawałkiem
kodu obiektowego obwarowanego licencjami.
W efekcie Nowicjusz musi tworzyć coraz bardziej złożone obejścia problemów tworzo-
nych przez biblioteki, co powoduje, że korzyści z ich stosowania stają cię coraz mniej
widoczne. Ponadto tworzone obejścia powodują, że kod wygląda coraz paskudniej.
Być może trafi na kilka miejsc w bibliotece, w których nie da się zmusić jej do wykona-
nia bardzo ważnego zadania (zgodnie ze specyfikacją powinna je wykonywać). Czasami
jest całkiem pewny, że istnieje jakiś sposób na zmuszenie tej czarnej skrzynki do dzia-
łania, ale nie jest w stanie zgadnąć jaki to sposób.
Nowicjusz zauważa, że im bardziej obciąża zadaniami bibliotekę, tym mocniej rośnie
czas debugowania kodu — nawet wykładniczo. Cały tworzony przez niego kod prze-
śladuje plaga błędów i wycieków pamięci; ich ślady prowadzą do bibliotek, których
kodu nie może zobaczyć ani zmodyfikować. Domyśla się, że wiele tych śladów po-
wraca z biblioteki do jego własnego kodu, ale bez źródeł nie jest w stanie określić, do
której jego części.
Nowicjusz jest coraz bardziej sfrustrowany. W szkole słyszał, że w normalnej pracy
napisanie stu linii ukończonego kodu w ciągu tygodnia uznawane jest za niezłą wy-
dajność. Wtedy śmiał się z tego, ponieważ w czasie tworzenia projektów szkolnych
i swojego prywatnego programowania był wielokrotnie bardziej wydajny. Teraz już
nie wydaje mu się to takie zabawne. Nie zmaga się już tylko z własnym brakiem do-
świadczenia, ale także z masą problemów powstałych w wyniku beztroski i niekom-
petencji innych. Są to problemy, których nie da się rozwiązać, ale można jedynie two-
rzyć ich obejścia.
Harmonogram projektu zaczyna się opóźniać. Nowicjusz marzył o pracy architekta,
a tymczasem stał się zwykłym murarzem, który dostał niepasujące do siebie cegły,
rozpadające się pod naciskiem. Ale menadżerowie nie chcą słyszeć od młodego pro-
gramisty żadnych wymówek. Zbyt głośne narzekanie na niską jakość komponentów
376
Rozdział 16. ♦ Ponowne wykorzystanie: nie wyważajmy otwartych drzłwi
najprawdopodobniej wpędzi go w konflikty ze starszymi menadżerami, którzy je wy-
bierali. Nawet jeżeli mógłby wygrać tę bitwę, to zmiana komponentów byłaby bardzo
trudna do wykonania — wiązałoby się to z pracą zespołu prawników przeglądających
szczegóły licencji.
Istnieje tylko niewielka szansa na to, że Nowicjusz doczeka się poprawienia błędów
w bibliotekach jeszcze w czasie tworzenia projektu. Przy odrobinie zastanowienia może
on zauważyć, że prawidłowo działający kod biblioteki nie zaprząta jego uwagi w takim
stopniu, jak znajdujące się w niej błędy i niedociągnięcia. Bardzo chciałby usiąść i po-
rozmawiać z twórcami biblioteki. Podejrzewa, że nie są oni tak skończonymi idiotami,
jak by wskazywał kod biblioteki, ale zwykłymi programistami, którzy podobnie jak
on zmagają się z przeciwnościami próbując właściwie wykonać swoją pracę. Niestety
nie jest w stanie sprawdzić, kim są ci programiści, a nawet jeżeli by się dowiedział,
firma dla której pracują, prawdopodobnie nie zgodziłabcy się na taką rozmowę.
W akcie desperacji Nowicjusz zaczyna tworzyć własne cegły, symulując niewłaściwie
działające elementy bibliotek własnym, lepiej sprawującym się kodem, tworzonym
praktycznie od zera. Dzięki temu, że Nowicjusz ma w głowie kompletny model tych
implementacji, powstający w ten sposób kod działa znacznie lepiej i jest łatwiejszy
w debugowaniu niż połączenie nieprzezroczystych bibliotek i tworzonych do nich obejść.
Nowicjusz czegoś się nauczył: im mniej polega na kodzie tworzonym przez innych
ludzi, tym więcej kodu może napisać sam. To bardzo mile łechce jego ego. Podobnie jak
wielu innych młodych programistów, w podświadomości sądzi, że jest znacznie mądrzej-
szy od innych, a jego doświadczenia zdają się to potwierdzać. Zaczyna więc tworzyć swój
własny zestaw narzędzi, lepiej dopasowanych do jegoc wymagań.
Niestety, w ten sposób uzyskuje tylko krótkoterminową i lokalną poprawę, która w efekcie
spowoduje długoterminowe problemy. Jest w stanie napisać większą ilość linii kodu, ma
on jednak o wiele niższą względną wartość w stosunku do kodu, który mógłby napisać
prawidłowo wykorzystując biblioteki. Więcej kodu niekoniecznie oznacza lepszy kod,
szczególnie jeżeli jest to kod niskiego poziomu, w znacznym stopniu związany z po-
nownym wymyślaniem koła.
Nowicjusza czeka jeszcze przynajmniej jedno nieprzyjemne doświadczenie, związane ze
zmianą pracy. Najprawdopodobniej okaże się, że nie będzie mógł zabrać ze sobą na-
pisanych przez siebie narzędzi. Jeżeli opuści firmę zabierając ze sobą kod, który napisał
w czasie pracy dla tej firmy, jego byli pracodawcy mogą potraktować to jako kradzież
własności intelektualnej. Gdy dowiedzą się o tym jego nowi pracodawcy, raczej nie
będą uszczęśliwieni, gdy Nowicjusz przyzna się, że ucżywa tego kodu w ich firmie.
Nawet jeżeli Nowicjuszowi uda się przemycić swoje narzędzia do nowej pracy, może się
okazać, że będą one tam zupełnie bezużyteczne. Nowi pracodawcy mogą używać zu-
pełnie innych narzędzi, języków i bibliotek chronionych prawami własności. Całkiem
prawdopodobne jest, że przy każdym nowym projekcie będzie musiał się nauczyć zu-
pełnie nowego zbioru technik i na nowo wyważać otwarcte drzwi.
W ten sposób programiści skutecznie oduczani są od ponownego wykorzystywania kodu
(a także innych dobrych praktyk, takich jak modułowość i przezroczystość) przez
połączenie problemów technicznych, barier tworzonych przez własność intelektualną,
16.2. Przezroczystość jako klucz do ponownego użycia kodu
377
politykę i potrzeby własnego ego. Spróbujmy takiego Jana Nowicjusza pomnożyć razy
sto tysięcy, dodać mu kilka dziesięcioleci i dorzucić mu nieco cynizmu i przyzwyczajenia
do takiego systemu. Otrzymamy obraz większej części przemysłu oprogramowania
i receptę na wielkie marnotrawienie czasu, kapitału i ludzkich umiejętności. Trzeba je
tylko powiększyć o taktyki kontroli rynku stosowane przez dostawców, niekompetentne
zarządzanie, niemożliwe do utrzymania terminy i wszystkie inne czynniki sprawiające,
że tak trudno jest prawidłowo wykonywać swoją pracęc.
Większość z nich odzwierciedla zawodowa kultura wynikająca z doświadczeń Jana
Nowicjusza. Firmy tworzące oprogramowanie są nękane kompleksem Nie Wymyślonego
Tutaj. Ich zachowanie w stosunku do ponownego wykorzystania kodu będzie nader
ambiwalentne. W celu dotrzymania terminów będą wymuszały na swoich programi-
stach stosowanie nieodpowiednich, ale szeroko reklamowanych komponentów. Jedno-
cześnie będą odmawiały wykorzystania kodu napisanego i przetestowanego przez ich
własnych programistów. Będą masowo produkować oprogramowanie o dość przypad-
kowym i powtarzającym się kodzie, tworzonym przez programistów zdających sobie
sprawę z tego, że wynik ich pracy okaże się wielkim śmietniskiem, ale pogodzonych
z myślą, że nie będą w stanie poprawić niczego poza tcym, co sami napisali.
W takiej kulturze ponowne wykorzystanie kodu zostanie zastąpione dogmatem, że raz
opłaconego kodu nie wolno wyrzucić, ale musi on być poprawiany i łatany, mimo że wszy-
scy dobrze wiedzą, że lepiej byłoby napisać go od nowa. Produkty tworzone w takiej
kulturze stają się z czasem coraz bardziej rozdęte i zawierają coraz więcej błędów, mimo
że każdy, kto pracuje przy ich tworzeniu, stara sięc dać z siebie wszystko.
16.2. Przezroczystość jako klucz
do ponownego użycia kodu
Historię Jana Nowicjusza przedstawiliśmy kilku doświadczonym programistom. Jeżeli
Czytelnik również jest programistą, powinien zareagować mniej więcej tak jak oni: po-
mrukiem rozpoznania. Jeżeli jednak nie jest programistą a menadżerem zarządzającym
programistami — mamy nadzieję, że dzięki tej opowieści doznał oświecenia. Historia
miała ilustrować sposób, w jaki różne naciski przeciwko ponownemu wykorzystaniu
kodu wzmacniają się wzajemnie, tworząc razem problem o rozmiarach przekraczających
wszelkie wyobrażenia.
Większość z nas jest bardzo przyzwyczajona do podstawowych założeń przemysłu opro-
gramowania, zgodnie z którymi oddzielenie podstawowych przyczyn tego problemu
od innych przypadków może wymagać wyjątkowego wysiłku umysłowego. A jednak
okazuje się, że nie są one bardzo skomplikowane.
Powodem większości kłopotów Jana Nowicjusza (a także powodowane przez nie większe
problemy z jakością) jest przezroczystość, a raczej jej brak. Nie da się naprawić tego,
czego wnętrza nie można zobaczyć. Tak naprawdę, w przypadku każdego nietrywialnego
API, tego, czego nie można zobaczyć od środka, nie da się nawet używać. Dokumentacja
jest z zasady niewystarczająca, nie da się w niej umieścić wszystkich niuansów kodu,
który opisuje.
378
Rozdział 16. ♦ Ponowne wykorzystanie: nie wyważajmy otwartych drzłwi
W rozdziale 6. rozważaliśmy zbawienny wpływ przezroczystości na jakość oprogra-
mowania. Komponenty składające się jedynie z kodu obiektowego niszczą przezro-
czystość oprogramowania. Z drugiej strony, jeżeli kod, którego próbujemy użyć ponow-
nie, można bez problemów obejrzeć i zmodyfikować, bardzo zmniejsza się szansa na to,
że zacznie on sprawiać niemiłe niespodzianki. Dobrze komentowane źródła kodu są
jego najdoskonalszą dokumentacją. Błędy w kodzie źródłowym można poprawić. Źródła
można konfigurować i kompilować specjalnie do debugowania, co znacznie ułatwia
analizę zachowania kodu w niejasnych przypadkach. A jeżeli zaistnieje taka potrzeba,
te zachowania można oczywiście zmieniać.
Istnieje jeszcze jeden ważny powód, dla którego należy żądać kodu źródłowego. Lekcja,
którą programiści uniksowi przyswoili sobie na przestrzeni dekad, mówi, że kod źró-
dłowy przetrwa, a kod obiektowy — nie. Zmieniają się platformy sprzętowe, zmie-
niają się różnego rodzaju biblioteki, systemy operacyjne wytwarzają nowe API i od-
suwają stare w cień. Wszystko się zmienia, a nieprzezroczyste binaria nie są w stanie
dostosować się do tych zmian. Są bardzo kruche, nie dają się łatwo przenosić do now-
szych warunków, ale wymagają stosowania bardzo grubych i podatnych na błędy warstw
emulacyjnych. Zamykają użytkowników w kręgu założeń poczynionych przez ich twór-
ców. Kody źródłowe są konieczne nawet wtedy, gdy nie istnieje potrzeba ani chęć zmiany
oprogramowania, bo do uruchomienia ich w nowych środowiskach wymagane jest prze-
kompilowanie.
Waga przezroczystości kodu i problem z jego przenośnością są wystarczającymi po-
wodami, dla których należy żą
Pobierz darmowy fragment (pdf)